discuz-redis 扩展 轻松快速分页 避免分页瓶颈 (更新 DXEXTEND 框架版)
设计原理:
1 、起因:
Discuz!X 系列中,使用了 SELECT * FROM pre_forum_thread WHERE fid=x AND displayorder IN ORDER BY xxx LIMIT x 这样的 sql 语句获取当前页的主题列表的。主题越多,翻页的数字越大,在 mysql 中就越容易出现慢查询,影响性能。表中只对回帖时间字段进行了索引,所以当使用发帖时间、回帖数、查看数排序查看翻页的时候,很容易出现慢查询。
由于上述原因,论坛中做了限制翻页的页数。官网上目前是能翻 500 页,一般论坛默认设置能翻 1000 页。
2 、目标:
在使用 redis 特性的前提下解决如下 2 个问题:
1) 、支持多种排序模式的翻页,不产生性能问题
2) 、不限翻页数量,不产生性能问题。
3) 、不会改动和破坏论坛 mysql 中的数据,实现相互兼容。
3 、设计:
在 redis 中我为每个板块创建了一组 sorted set 。包括发帖时间集合、回帖时间集合、回帖数集合、浏览数集合。 tid 为值,排序条件为分数。每次翻页的时候,就在板块的对应集合中取得一组 tid 。然后再使用 SELECT * FROM pre_forum_thread WHERE tid IN () 获取到帖子的其他数据。
(结构如附件图)
另外因为置顶数据的要求,在板块的每组集合中还加了一个一级置顶集合。在整个系统中加了一个 fid 集合。
4 、代码实现:
工具:因为 redis 数据库需要初始化,所以单独提供了初始化工具
1) 、初始化工具 php 版
2) 、初始化工具 py 版
新增类:
1) 、 redis 底层驱动类
2) 、 redis 类
修改类:
1) 、 table_forum_thread 类
通过上述新增 2 个数据库类和修改一个主题表类就能实现设计中的功能。
五、结论:
目前通过测试能达到目标中的三项要求。
1) 、四种主题列表排序方式,不管翻页到多少也,速度均在 0.0x 秒。
2) 、在保证性能的前提下,可翻所有页。
3) 、和 mysql 实现无缝兼容。不影响 mysql 中正式数据,在 redis 服务未启动的情况下自动切换到老的分页方式。
一、结构
init_tools 初始化程序
init_php.php
在使用 discuz-redis 扩展的时候,需要使用上述程序进行初始化 redis 数据库一次。 php 版、 py 版都行。
upload 需要上传到 web 目录的文件
二、使用前提
1 、 redis 服务器
2 、 php-redis 扩展
3 、 DXEXTEND1.1.2beta 以上
三、安装步骤
1 、上传 upload 文件夹中的文件到论坛根目录
2 、在 config/config_global.php 中增加如下配置
// ----------------------- CONFIG DISCUZ_REDIS ------------------------ //
$_config['extend']['discuz_redis']['on'] = 1;
$_config['discuz_redis']['server'] = '127.0.0.1';
$_config['discuz_redis']['port'] = 6379;
$_config['discuz_redis']['pconnect'] = 1;
$_config['discuz_redis']['auth'] = '';
$_config['discuz_redis']['db'] = '0';
3 、上述配置好后,修改 init_php.php 文件分别填写:
$mhost = '127.0.0.1'; mysql 服务器地址
$muser = 'root'; mysql 用户名
$mpw = '';
mysql 密码
$mdb = 'x25redis';
mysql 中 discuz 数据库名
$rhost = '127.0.0.1'; redis 地址
$rport = 6379; redis 端口
$_max_num_per_forum = 100000; 此项设置每个板块最多显示多少主题。如服务器内存足够,可填写较大的值,显示所有主题。
4 、在服务器上执行 init_php.php 同步 redis 数据,例如/usr/local/php/bin/php /usr/local/src/init_php.php
按数据量大小大概遇到几十秒到几分种时间。建议在数据库服务器负载低的时候运行。
5 、在 Linux 服务器上设置计划任务,每天半夜运行一次 init_php.php 文件保证 redis 数据同步。时间点可以自定,建议凌晨 3 点或者 4 点。
四、关闭与启动
$_config['extend']['discuz_redis']['on'] = 1; 1 为启动,0 为停止
五、注意事项
1,目前的版本不能和 innodb 插件一起用,这个问题会在下一版本中解决。 2,该插件针对大数据大访问量,数据库压力比较大的站点,如果没有性能问题则不建议使用,维护 redis 需要比较专业的技术。如果盲目使用反而适得其反。