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