Discuz!X叢集部署的系統方案和改造方式討論

來源:互聯網
上載者:User

多WEB部署時,面臨的核心問題是WEB伺服器間的資料共用和同步。就資料存放區的方式而言,Discuz資料包含兩部分,一部分儲存在MySQL資料庫中使用者、文章等文本類、結構化的資料),一部分儲存為檔案附件、快取檔案等)。其中儲存在MySQL中的資料可以方便地在多伺服器間共用,擴充和冗餘也已經有比較成熟的方案。這裡我們主要討論Discuz檔案類型的資料,部分涉及到多台MySQL伺服器的內容。
Discuz檔案類型的資料都儲存於DISCUZ_ROOT/data目錄,各目錄主要功能如下:data/attachment 附件類
data/log 作業記錄data/cache 配置參數類快取檔案預設是sql,配置參數通過pre_common_syscache表緩衝)、CSS緩衝、部分JS緩衝data/template 模組緩衝

data/threadcache 論壇頁面緩衝針對遊客的最佳化)


DISCUZ_ROOT/data目錄下有幾個重要的檔案檔案鎖)
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)時,會產生這個檔案鎖。


下面這些功能會涉及到多web伺服器間的資料共用和同步,預設Discuz通過MySQL實現。使用者session 表pre_common_session管理面板session 表pre_common_admincp_session

系統配置項緩衝 表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/attachment目錄裡的)檔案URL重構,但後台發布的廣告不行,有BUG在X3版本測試)。


在使用檔案鎖,且依賴於檔案的mtime等時間值執行邏輯時,請務必保證伺服器時鐘的一致性。


上面的方案簡單,且對Discuz的改造很小,維護成本低,適合單台伺服器向多台伺服器數量較少)擴充時選擇。隨著訪問量和web節點的增加,內網流量,NFS,MySQL均需要進行擴充。MySQL的擴充有較成熟的方案,如主重複製機制。NFS這個稍稍麻煩一點,且很多人詬病NFS的檔案分享權限設定機制不安全;論壇附件以較小尺寸幾百位元組不等)的檔案居多,而linux的ext檔案系統的塊大小一般是4K,從而浪費了儲存空間,對inode的利用率也不好;從長遠來看,NFS終將成為系統的瓶頸,我們有必要重新規劃檔案分享權限設定/同步機制。


這裡我們先討論 檔案分享權限設定問題MySQL擴充涉及的問題後面一點再說明。

目前很多公司都有解決大量小檔案儲存體的方案,如國內某大互連網公司使用基本MangoDB的GridFS等。實現的細節不在討論範圍,其基本思想就是構建檔案儲存體服務,把附件類靜態檔案儲存體到遠端遠端系統返回一個URL供訪問),並且由這個遠端系統處理使用者訪問的各種最佳化等。我們討論如果已經有了這樣的一個服務,Discuz接入到這樣的一個服務需要注意些什麼。


在這之前,我們來看一下Discuz的附件上傳、儲存流程。

文章附件的上傳和文章的發布是非同步。附件上傳後的實體檔案會被儲存到類似data/attachment/forum/201307/20/路徑,同時會在附件表格中pre_forum_attachment_unused)添加相應記錄,發布文章時,這些記錄被散列分布到相應的附件表格pre_corum_attachment_[0-9])中,並標識其所屬的pid, tid。這是附件本機存放區的流程。


遠程附件

Discuz支援“遠程附件”功能全域-上傳設定-遠程附件)。“遠程附件”功能支援將附件通過FTP的方式儲存到遠端系統,如果網站當前沒有檔案儲存體服務,但又想將檔案儲存體分離,使用這個內建功能也是一種不錯的選擇,畢竟FTP很好維護,也不需要對Discuz進行改造。雖然Discuz預設只支援FTP方式,但遠端儲存在功能介面層面基本是共同的概念,添加、刪除之類。所以當要把“遠程附件”擴充到自有的遠端檔案儲存體服務時,一個比較好的實踐是繼承Discuz的ftp類,用遠端檔案儲存體的功能重寫Discuz的ftp類定義的各方法,然後在ftp類執行個體化的地方,調用這個新的子類;如果不打算保留預設的FTP機制,甚至可以直接修改Discuz的ftp類實現,這樣連ftp類執行個體化的地方也不用修改了。這樣的處理對Discuz的改造最小,細節都隱藏在了ftp類的實現中,遵守與ftp相同的行為模式。


遠程附件將大部分的靜態資源流量分離,我們可以分別的最佳化兩個系統。但Discuz的遠程附件的行為模式仍需要我們注意,我們必須清楚它是怎樣啟動並執行,是否有某種陷阱,以便於系統的某些功能行為表現異常時,心裡有底。


1)開啟遠程附件時,附件上傳、儲存流程附件非同步上傳階段與本機存放區是一樣的,附件始終會先被上傳到類似data/attachment/forum/201307/20/路徑,同時會在附件表格中pre_forum_attachment_unused)添加相應記錄,發布文章時,這些記錄被散列分布到相應的附件表格pre_corum_attachment_[0-9])中,並標識其所屬的pid, tid。然後向遠端上傳附件資料,上傳完成後,會刪除掉本地的副本,並將附件表格pre_corum_attachment_[0-9])的remote欄位標識為遠程附件類型。 2)在什麼時間點執行向遠端上傳附件上傳到遠端的時間點是發布文章的時候,且在該進程周期內,上傳該文章的所有附件阻塞模型)。這會有一些風險點,如果上傳附件到無端系統花費的時間較長一個文章的附件很多、很大,或網路頻寬節流設定),使用者介面的響應體驗會有很明顯的卡頓感,甚至頁面逾時失敗。 3)已知會被儲存到遠端的資料文章附件 4)已知不會儲存到遠端的資料或者說會被儲存在本地)
  • 文章附件在上傳到無端之前,會儲存在本地。
  • “遊客查看小圖”需要啟用“遊客登陸查看大圖”功能),小圖是用類似forum.php?mod=image&aid=4&size=100x100&key=05869b37379ff990&type=1的調用產生的。小圖產生並儲存在類似data/attachment/image/000/00/00/123.gif ,且會在本地保留副本。
  • 活動貼的封面不會儲存為遠程附件。
  • 編輯文章時,顯示的縮圖所見即所得 (WYSIWYG))是即時產生的通過網路訪問遠端擷取原圖),產生這個縮圖的過程中,會把圖片儲存到data/attachment/temp目錄,圖片資料內容輸出到瀏覽器後,該位置儲存的的縮圖被會刪除。
  • 圖片附件的縮圖都是通過forum.php?mod=image&xxx 這個模組產生的。使用者可以通過拼裝請求,使伺服器側執行產生遠程附件的本機複本的流程,所以這裡可能存在某種風險。


從上面關於“遠程附件”的討論我們看到,即使啟用了“遠程附件”機制,但Discuz仍然會在眾多功能上用到data目錄下的多個子目錄,且有的子目錄還必須在多個web伺服器間共用如data/attachment)。所以如果不對這些功能點進行改造,我們仍然需要NFS這個裝置,畢竟遠程附件已經將大部分的流量分走了,NFS是保證業務正常啟動並執行最簡單的辦法,誰知道還有多少其它功能會依賴於此呢?


MySQL擴充在Discuz的業務模型上,對MySQL進行擴充使用最廣泛的機制是“主從複製”、“讀寫分離”。Discuz本身也支援這些機制,最近的版本還支援分庫的部署,我們不討論這些機制部署的細節,我們討論將Discuz部署到這樣的環境中時,需要做出的一些調整。 1)複寫延遲造成的主庫、從庫資料不同步。複製機制的延遲雖然很小,但總存在,即使是這種很小延遲,也足以給系統帶來行為異常,特別是實施“讀寫分離”的情境。在Disuz業務情境中,以下情況是曾經出現過的:在後台配置的參數不起作用,有可能是配置項寫入了主庫pre_common_setting),同時在主庫刪除了配置的緩衝pre_common_syscache),但在資料同步到從庫之前,另一個請求發現pre_common_syscache)沒有緩衝,於是觸發了產生緩衝的流程,這個流程會在從庫中讀到舊的配置項“讀”操作是在從庫)。類似的情境還有很多,如刷積分,管理員進後台異常等。解決類似這種與時序相關的情境,往往需要針對個例去處理,就緩衝這個問題,建議是在程式更新時間點,統一產生好緩衝,且避免線上對配置的操作。

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內建的計劃任務機制,不建議這種做法,計劃任務的數量畢竟是很有限的、執行的頻率也是有計劃的。


使用“檔案”緩衝配置項資料。即 $_config['cache']['type'] = 'file'Discuz預設是使用的MySQL儲存配置緩衝表pre_common_syscache)。$_config['cache']['type'] = 'sql'如果開啟了記憶體緩衝機制,如memcache,這些快取資料會放到緩衝中,以緩解資料庫的壓力。這些快取項目是每個動態網頁面都需要調用的,所以如果瀏覽量高的話,這種方式在網路等方面的開銷累計起來就很可觀了。

建議使用檔案快取這部分資料,快取檔案跟著程式檔案一起部署,每套程式檔案都有一套配置項的快取檔案的副本,從而完全最佳化掉了這部分開銷。優點:將配置項的緩衝寫入檔案是Discuz內建的機制,無需改造;磁碟檔案IO穩定性是最好的,成本是最低的,避免中心節點故障帶來的風險;上線時間點所有配置項緩衝已經產生,客觀上達到了“暖緩衝”效果。缺點:在系統上線部署之前,需要產生全部的配置項快取檔案,Discuz預設的產生快取檔案的策略Discuz預設的策略是“找不到緩衝再產生”,對於短時間並發較高的系統,這種策略往往會造成多個處理進程同時觸發寫緩衝的情況)不能滿足這個需求,這需要一些開發量。


在具體實施時,有一些建議。產生的快取檔案同程式原始碼一樣納入版本控制,以便於跟蹤配置變化。而通過後台UI操作,儲存在資料庫中的配置資料則沒有這麼方便。配置項緩衝的產生比較簡單,按照pre_common_syscache表的記錄產生即可。


同理,模板快取檔案也可以在上線部署前完成組建,只是模板快取檔案初始化會麻煩一些,建議收集最常用頁面的入口,建立指令碼來觸發。


如果要覆蓋Discuz預設的配置項的值,建議啟用一個設定檔,用新值覆蓋舊值,盡量避免管理後台UI操作,特別是線上環境,因為配置參數最終需要與配置項快取檔案同步才能起作用。


所有WEB伺服器上部署程式的路徑要完全一樣。Discuz的快取項目,會產生一些絕對路徑,一個例子是“本地附件儲存位置”配置項通過管理後台“全域-上傳設定-基本設定”操作)。mysql> select * from pre_common_setting where skey='attachdir';
+-----------+-------------------+
| skey | svalue |
+-----------+-------------------+
| attachdir | ./data/attachment |
+-----------+-------------------+

表pre_common_syscache cname='setting'mysql> SELECT * FROM pre_common_syscache WHERE `data` LIKE '%attachment%';
在輸出結果中尋找'attachdir',有類似下面的內容s:9:"attachdir";s:39:"D:/Apache/htdocs/./data/attachment/";
這些絕對路徑需要在所有WEB伺服器上存在,且功能匹配。如果網站的部署路徑發生了變更,重建這些快取項目值。
“論壇頁面緩衝”:“論壇首頁緩衝”只針對遊客有效)、緩衝文章;這些快取資料預設被儲存於data/threadcache目錄,特別的,這些快取資料沒有到期刪除機制,往往會產生大量快取檔案,需要注意監控緩衝目錄的情況。有些建議是使用類似memcache這樣的有到期控制機制的裝置來改造這個緩衝,可能需要權衡網路的負載。 “最佳化更新主題瀏覽量”、“附件下載量延遲更新”選項。如果是通過寫檔案的方式緩衝這部分資料,建議把這些檔案儲存體在各web伺服器上,而不是寫到NFS上以減少網路開銷,各種鎖),在把資料匯總到資料庫中時,需清理每台WEB伺服器上的相關日誌。最近的X版本通過“pre_forum_threadaddviews”表來緩衝主題瀏覽量,個人感覺寫檔案的方式對於均衡效能方面更好。通過上面的最佳化步驟後,只有data/attachment目錄需要在各web伺服器間共用,所以把NFS掛載到該目錄即可。保持這個位置可以在WEB伺服器間共用,可以在最小改造下避免眾多已知和不預知的問題情境出現。mount /PATH/TO/DISCUZ_ROOT/data/attachment NFS_SERVER:/PATH


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.