Discuz!X集群部署的系统方案和改造方式讨论
Discuz文件類型的數(shù)據(jù)都存儲(chǔ)于DISCUZ_ROOT/data目錄,各目錄主要功能如下:data/p_w_upload 附件類
data/log 運(yùn)行日志data/cache 配置參數(shù)類緩存文件(默認(rèn)是sql,配置參數(shù)通過pre_common_syscache表緩存)、CSS緩存、部分JS緩存data/template 模塊緩存
data/threadcache 論壇頁面緩存(針對游客的優(yōu)化)
data/install.lock 安裝程序鎖定。如果該文件存在,DISCUZ_ROOT/install/中的安裝程序不能執(zhí)行。
data/sendmail.lock 發(fā)送郵件鎖。Discuz默認(rèn)通過類似home.php?mod=misc&ac=sendmail&rand=1379315574這個(gè)隱藏頁面調(diào)用,由用戶的瀏覽行為觸發(fā)郵件發(fā)送流程(瀏覽器側(cè)用一個(gè)300秒的cookie控制頻率,服務(wù)器側(cè)通過sendmail.lock文件的mtime控制頻率5秒)。如果可以控制 服務(wù)器,應(yīng)該優(yōu)化掉這個(gè)機(jī)制。
data/updatetime.lock 某管理后臺(tái)使用的鎖。
data/update.lock 系統(tǒng)升級鎖。執(zhí)行版本升級程序(如x2升級到x3)時(shí),會(huì)生成這個(gè)文件鎖。
系統(tǒng)配置項(xiàng)緩存 表pre_common_syscache
我們假設(shè)部署兩臺(tái)web服務(wù)器的場景(且web服務(wù)器也是php應(yīng)用服務(wù)器)。我們需要解決data目錄共享的問題,引入NFS服務(wù)可以簡單解決這個(gè)問題。服務(wù)器復(fù)用,此處不表。這里會(huì)有一個(gè)選擇,哪些目錄放置在NFS上,從上面的分析來看,將data目錄放置在NFS上即可,即各web服務(wù)器均獨(dú)立部署程序文件,將NFS掛載到data目錄節(jié)點(diǎn),缺點(diǎn)是需要將程序文件部署到每一臺(tái)web服務(wù)器上,要解決程序文件更新部署的問題,優(yōu)點(diǎn)是可以節(jié)省web服務(wù)器通過網(wǎng)絡(luò)取NFS上的程序文件的開銷。如果圖方便,也可以把程序文件也放到NFS上,則所有文件都只有一個(gè)副本了,程序更新也很方便,缺點(diǎn)是會(huì)增加web服務(wù)器通過網(wǎng)絡(luò)取程序文件的開銷。這兩者需要權(quán)衡,建議第一種。
上面的方案存在一些問題。當(dāng)用戶訪問一個(gè)附件時(shí),WEB服務(wù)器都需要通過網(wǎng)絡(luò)從NFS上取文件,這給內(nèi)網(wǎng)網(wǎng)絡(luò)帶來了壓力和一些不必要的開銷,這可以通過在web前端增加緩存機(jī)制來緩解(如squid,nginx的proxy cache等)。為靜態(tài)資源配置單獨(dú)的域名供訪問也是值得實(shí)施的工作,Discuz可以很簡單的做到這一點(diǎn),通過配置“本地附件URL地址”項(xiàng)就可以實(shí)現(xiàn)附件類(data/p_w_upload目錄里的)文件URL重構(gòu),但后臺(tái)發(fā)布的廣告不行,有BUG(在X3版本測試)。
在使用文件鎖,且依賴于文件的mtime等時(shí)間值執(zhí)行邏輯時(shí),請務(wù)必保證服務(wù)器時(shí)鐘的一致性。
上面的方案簡單,且對Discuz的改造很小,維護(hù)成本低,適合單臺(tái)服務(wù)器向多臺(tái)服務(wù)器(數(shù)量較少)擴(kuò)展時(shí)選擇。隨著訪問量和web節(jié)點(diǎn)的增加,內(nèi)網(wǎng)流量,NFS,MySQL均需要進(jìn)行擴(kuò)展。MySQL的擴(kuò)展有較成熟的方案,如主重復(fù)制機(jī)制。NFS這個(gè)稍稍麻煩一點(diǎn),且很多人詬病NFS的文件共享機(jī)制不安全;論壇附件以較小尺寸(幾百字節(jié)不等)的文件居多,而linux的ext文件系統(tǒng)的塊大小一般是4K,從而浪費(fèi)了存儲(chǔ)空間,對inode的利用率也不好;從長遠(yuǎn)來看,NFS終將成為系統(tǒng)的瓶頸,我們有必要重新規(guī)劃文件共享/同步機(jī)制。
目前很多公司都有解決大量小文件存儲(chǔ)的方案,如國內(nèi)某大互聯(lián)網(wǎng)公司使用基本MangoDB的GridFS等。實(shí)現(xiàn)的細(xì)節(jié)不在討論范圍,其基本思想就是構(gòu)建文件存儲(chǔ)服務(wù),把附件類靜態(tài)文件存儲(chǔ)到遠(yuǎn)端(遠(yuǎn)端系統(tǒng)返回一個(gè)URL供訪問),并且由這個(gè)遠(yuǎn)端系統(tǒng)處理用戶訪問的各種優(yōu)化等。我們討論如果已經(jīng)有了這樣的一個(gè)服務(wù),Discuz接入到這樣的一個(gè)服務(wù)需要注意些什么。
帖子附件的上傳和帖子的發(fā)布是異步的。附件上傳后的實(shí)體文件會(huì)被存儲(chǔ)到類似data/p_w_upload/forum/201307/20/路徑,同時(shí)會(huì)在附件表中(pre_forum_p_w_upload_unused)添加相應(yīng)記錄,發(fā)布帖子時(shí),這些記錄被散列分布到相應(yīng)的附件表(pre_corum_p_w_upload_[0-9])中,并標(biāo)識(shí)其所屬的pid, tid。這是附件本地存儲(chǔ)的流程。
Discuz支持“遠(yuǎn)程附件”功能(全局-上傳設(shè)置-遠(yuǎn)程附件)。“遠(yuǎn)程附件”功能支持將附件通過FTP的方式存儲(chǔ)到遠(yuǎn)端系統(tǒng),如果網(wǎng)站當(dāng)前沒有文件存儲(chǔ)服務(wù),但又想將文件存儲(chǔ)分離,使用這個(gè)內(nèi)建功能也是一種不錯(cuò)的選擇,畢竟FTP很好維護(hù),也不需要對Discuz進(jìn)行改造。雖然Discuz默認(rèn)只支持FTP方式,但遠(yuǎn)端存儲(chǔ)在功能接口層面基本是共同的概念,添加、刪除之類。所以當(dāng)要把“遠(yuǎn)程附件”擴(kuò)展到自有的遠(yuǎn)端文件存儲(chǔ)服務(wù)時(shí),一個(gè)比較好的實(shí)踐是繼承Discuz的ftp類,用遠(yuǎn)端文件存儲(chǔ)的功能重寫Discuz的ftp類定義的各方法,然后在ftp類實(shí)例化的地方,調(diào)用這個(gè)新的子類;如果不打算保留默認(rèn)的FTP機(jī)制,甚至可以直接修改Discuz的ftp類實(shí)現(xiàn),這樣連ftp類實(shí)例化的地方也不用修改了。這樣的處理對Discuz的改造最小,細(xì)節(jié)都隱藏在了ftp類的實(shí)現(xiàn)中,遵守與ftp相同的行為模式。
遠(yuǎn)程附件將大部分的靜態(tài)資源流量分離,我們可以分別的優(yōu)化兩個(gè)系統(tǒng)。但Discuz的遠(yuǎn)程附件的行為模式仍需要我們注意,我們必須清楚它是怎樣運(yùn)行的,是否有某種陷阱,以便于系統(tǒng)的某些功能行為表現(xiàn)異常時(shí),心里有底。
- 帖子附件在上傳到無端之前,會(huì)存儲(chǔ)在本地。
- “游客查看小圖”(需要啟用“游客登陸查看大圖”功能),小圖是用類似forum.php?mod=p_w_picpath&aid=4&size=100x100&key=05869b37379ff990&type=1的調(diào)用生成的。小圖生成并存儲(chǔ)在類似data/p_w_upload/p_w_picpath/000/00/00/123.gif ,且會(huì)在本地保留副本。
- 活動(dòng)貼的封面不會(huì)存儲(chǔ)為遠(yuǎn)程附件。
- 編輯帖子時(shí),顯示的縮略圖(所見即所得)是即時(shí)生成的(通過網(wǎng)絡(luò)訪問遠(yuǎn)端獲取原圖),生成這個(gè)縮略圖的過程中,會(huì)把圖片存儲(chǔ)到data/p_w_upload/temp目錄,圖片數(shù)據(jù)內(nèi)容輸出到瀏覽器后,該位置存儲(chǔ)的的縮略圖被會(huì)刪除。
- 圖片附件的縮略圖都是通過forum.php?mod=p_w_picpath&xxx 這個(gè)模塊生成的。用戶可以通過拼裝請求,使服務(wù)器側(cè)執(zhí)行生成遠(yuǎn)程附件的本地副本的流程,所以這里可能存在某種風(fēng)險(xiǎn)。
從上面關(guān)于“遠(yuǎn)程附件”的討論我們看到,即使啟用了“遠(yuǎn)程附件”機(jī)制,但Discuz仍然會(huì)在眾多功能上用到data目錄下的多個(gè)子目錄,且有的子目錄還必須在多個(gè)web服務(wù)器間共享(如data/p_w_upload)。所以如果不對這些功能點(diǎn)進(jìn)行改造,我們?nèi)匀恍枰狽FS這個(gè)設(shè)備,畢竟遠(yuǎn)程附件已經(jīng)將大部分的流量分走了,NFS是保證業(yè)務(wù)正常運(yùn)行的最簡單的辦法,誰知道還有多少其它功能會(huì)依賴于此呢?
2)僅將需持久化的數(shù)據(jù)同步到從庫。
如pre_common_session、pre_common_admincp_session, pre_forum_threadaddviews這類數(shù)據(jù)是不應(yīng)該同步到從庫的,它們更新非常頻繁,且都是臨時(shí)性的,它們應(yīng)該被配置為忽略同步的表(replicate_wild_ignore_table選項(xiàng)),或者更好的辦法是通過其它機(jī)制處理(如memcache、redis等)來實(shí)現(xiàn),從而徹底從數(shù)據(jù)庫中分離。從庫同步主庫的寫操作時(shí),同樣會(huì)使用寫鎖,而這些性能開銷是不必要的、應(yīng)該優(yōu)化,以使從庫最大限度的服務(wù)于核心內(nèi)容的讀取查詢。
其它一些多web部署時(shí)要注意的問題
改造內(nèi)置計(jì)劃任務(wù)。
默認(rèn)Discuz內(nèi)置的計(jì)劃任務(wù)是通過用戶瀏覽行為觸發(fā)的,如果能控制 服務(wù)器,這應(yīng)該改成用操作系統(tǒng)的計(jì)劃任務(wù)驅(qū)動(dòng),Discuz!提供了api.php?mod=cron,稍作改造即可。僅在某一臺(tái)WEB服務(wù)器上部署,并且將Discuz的每個(gè)任務(wù)單獨(dú)部署成操作系統(tǒng)計(jì)劃任務(wù)的一項(xiàng),有一種選擇是只部署一個(gè)“每分鐘”周期的計(jì)劃任務(wù),然后由這個(gè)任務(wù)每分鐘的輪詢操作來驅(qū)動(dòng)Discuz內(nèi)置的計(jì)劃任務(wù)機(jī)制,不建議這種做法,計(jì)劃任務(wù)的數(shù)量畢竟是很有限的、執(zhí)行的頻率也是有計(jì)劃的。
建議使用文件緩存這部分?jǐn)?shù)據(jù),緩存文件跟著程序文件一起部署,每套程序文件都有一套配置項(xiàng)的緩存文件的副本,從而完全優(yōu)化掉了這部分開銷。優(yōu)點(diǎn):將配置項(xiàng)的緩存寫入文件是Discuz內(nèi)置的機(jī)制,無需改造;磁盤文件IO穩(wěn)定性是最好的,成本是最低的,避免中心節(jié)點(diǎn)故障帶來的風(fēng)險(xiǎn);上線時(shí)間點(diǎn)所有配置項(xiàng)緩存已經(jīng)生成,客觀上達(dá)到了“暖緩存”效果。缺點(diǎn):在系統(tǒng)上線部署之前,需要生成全部的配置項(xiàng)緩存文件,Discuz默認(rèn)的生成緩存文件的策略(Discuz默認(rèn)的策略是“找不到緩存再生成”,對于短時(shí)間并發(fā)較高的系統(tǒng),這種策略往往會(huì)造成多個(gè)處理進(jìn)程同時(shí)觸發(fā)寫緩存的情況)不能滿足這個(gè)需求,這需要一些開發(fā)量。
在具體實(shí)施時(shí),有一些建議。生成的緩存文件同程序源代碼一樣納入版本控制,以便于跟蹤配置變化。而通過后臺(tái)UI操作,存儲(chǔ)在數(shù)據(jù)庫中的配置數(shù)據(jù)則沒有這么方便。配置項(xiàng)緩存的生成比較簡單,按照pre_common_syscache表的記錄生成即可。
同理,模板緩存文件也可以在上線部署前完成生成,只是模板緩存文件初始化會(huì)麻煩一些,建議收集最常用頁面的入口,建立腳本來觸發(fā)。
如果要覆蓋Discuz默認(rèn)的配置項(xiàng)的值,建議啟用一個(gè)配置文件,用新值覆蓋舊值,盡量避免管理后臺(tái)UI操作,特別是線上環(huán)境,因?yàn)榕渲脜?shù)最終需要與配置項(xiàng)緩存文件同步才能起作用。
+-----------+-------------------+
| skey | svalue |
+-----------+-------------------+
| attachdir | ./data/p_w_upload |
+-----------+-------------------+
表pre_common_syscache cname='setting'mysql> SELECT * FROM pre_common_syscache WHERE `data` LIKE '%p_w_upload%';
在輸出結(jié)果中查找'attachdir',有類似下面的內(nèi)容s:9:"attachdir";s:39:"D:/Apache/htdocs/./data/p_w_upload/";
這些絕對路徑需要在所有WEB服務(wù)器上存在,且功能匹配。如果網(wǎng)站的部署路徑發(fā)生了變更,重新生成這些緩存項(xiàng)值。
“論壇頁面緩存”:“論壇首頁緩存”(只針對游客有效)、緩存帖子;這些緩存數(shù)據(jù)默認(rèn)被存儲(chǔ)于data/threadcache目錄,特別的,這些緩存數(shù)據(jù)沒有過期刪除機(jī)制,往往會(huì)生成大量緩存文件,需要注意監(jiān)控緩存目錄的情況。有些建議是使用類似memcache這樣的有過期控制機(jī)制的設(shè)備來改造這個(gè)緩存,可能需要權(quán)衡網(wǎng)絡(luò)的負(fù)載。“優(yōu)化更新主題瀏覽量”、“附件下載量延遲更新”選項(xiàng)。如果是通過寫文件的方式緩存這部分?jǐn)?shù)據(jù),建議把這些文件存儲(chǔ)在各web服務(wù)器上,而不是寫到NFS上(以減少網(wǎng)絡(luò)開銷,各種鎖),在把數(shù)據(jù)匯總到數(shù)據(jù)庫中時(shí),需清理每臺(tái)WEB服務(wù)器上的相關(guān)日志。最近的X版本通過“pre_forum_threadaddviews”表來緩存主題瀏覽量,個(gè)人感覺寫文件的方式對于均衡性能方面更好。通過上面的優(yōu)化步驟后,只有data/p_w_upload目錄需要在各web服務(wù)器間共享,所以把NFS掛載到該目錄即可。保持這個(gè)位置可以在WEB服務(wù)器間共享,可以在最小改造下避免眾多已知和不預(yù)知的問題場景出現(xiàn)。mount /PATH/TO/DISCUZ_ROOT/data/p_w_upload NFS_SERVER:/PATH
轉(zhuǎn)載于:https://blog.51cto.com/dikeen/1299948
總結(jié)
以上是生活随笔為你收集整理的Discuz!X集群部署的系统方案和改造方式讨论的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [Android Studio] A
- 下一篇: zmail邮件系统安装手册 V2.0版本