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 需要比較專業的技術。如果盲目使用反而適得其反。