叢集、分散式你想好怎麼用了嗎?

oecpAdmin發表於2011-04-06

叢集、分散式你想好怎麼用了嗎?

       做網際網路、做電子商務,我們都盼望著使用者數和訪問量不斷的攀升,這意味著我們將有更多的業務,將有更多的訂單,將會有更多的盈利。欣喜之餘,我們開始有更多的擔憂,我們的應用能不能抗得住啊,當一個個的問題在高訪問量的時候一個個的暴露出來時,我們的壓力也就接踵而來,我們忙前忙後焦頭爛額。這樣的景象不知道大家有沒有經歷過,不好意思我還沒有。俗話說,未雨綢繆,早做準備永遠都是好事。在設計OECP社群的時候,我早早的設計了OECP社群未來的執行環境,負載均衡,分散式叢集,反向代理,快取,檔案系統,並在程式的架構上分離了平臺層和應用層,正當我暗自得意的時候,一盆冷水讓我從驕傲中甦醒過來。我平時一再吹噓的通過可無限擴充套件的伺服器叢集方式解決系統壓力的方案一下子出了問題。我一再提倡要將傳統的將壓力嫁禍於資料庫的做法前置到應用伺服器,通過應用伺服器可擴充套件叢集的能力來解決系統效能問題,這種思路我始終認為是對的,那又是什麼問題讓我坐立不安呢?
       獨立應用可以透明的遷移到叢集結構中,這種認識是錯誤的。儘管一些供應商宣稱他們的J2EE產品有這樣的靈活性。不要相信他們!事實你要在開始系統設計時就要準備叢集,而這將影響開發和測試的所有階段。
        1、Http Session
       在叢集環境中,使用HTTP Session有很多限制,這取決於你的應用程式伺服器採用了哪種會話失效轉移的機制。如果負載叢集採用的一個會話始終是連線的一個應用伺服器,那麼帶來的影響還是可以容忍的。只是當這個應用伺服器斷開的時候,使用者的此次請求也將斷掉無法訪問,而不能切換到其他伺服器。如果你採取了會話失效轉移,或者直接根據壓力輪詢路由應用伺服器,雖然可以保持使用者的請求不會斷掉,但是其他的問題來了。你必須做的處理的就是session的複製或者同步,雖然很多應用伺服器有這方面的能力,但是一個重要的限制就是所有儲存的HTTP Session中的物件必須是可序列化的,這將限制設計和應用程式結構。我們可以問一下自己,我們session中放置的都是可序列化的嗎?如果不是,你完了。即使我們都是放置的可序列話的物件,物件的序列的反序列化對效能的影響很大,如果你的叢集節點很多,session的物件又放了很多,session的同步將會出現形成伺服器間的IO阻塞。所以不要什麼東西都往session中放。
        2、快取
        我們採用快取來提升系統的效能,降低資料庫的壓力,這種思路絕對是正確的,對於單應用伺服器來說也是絕對沒有問題的。但是在叢集環境下,問題又來了。在叢集環境,每個JVM例項都要維護一份快取的拷貝,這些拷貝必須同步以維持所有伺服器例項狀態的一致性。有時這種型別的同步會比沒有快取帶來更糟的效能。而更可怕的是我們根本就沒考慮到同步快取,造成資料的不一致。叢集環境下,我們需要考慮使用的快取產品支不支援分散式,我們自己寫的快取實現在叢集下有沒有同步的功能。
        3、單例和靜態變數
        當我們設計J2EE應用程式時,在架構上經常會使用一些設計模式。這些如“Singleton”的設計模式會用到靜態變數來在多物件之間共享狀態。這種方式在單服務中工作得很好,但在叢集環境將失效。一個使用靜態變數的例子就是用它來保持線上使用者數。用靜態變數來儲存線上使用者數是一個很簡單的辦法,當使用者進入或離開時就增加和減少它。這種方式在單伺服器中絕對是好的,但在叢集環境將失效。在叢集中更好的方式是將所有狀態儲存到資料庫,或者全域性的快取中。
       4、檔案操作和外部資源
       一些應用會使用檔案系統來儲存使用者上傳的檔案,或是建立一個動態配置的XML檔案。在叢集環境是沒有辦法來在其他例項之間來複制這些檔案的。為了在叢集中工作,辦法是用資料庫作為外部檔案的存放點,另外也可以使用SAN(儲存區域網,Storage Area Network)作為存放點。對於檔案上傳下載,我們最常用的做法就是採用檔案伺服器統一存取。
       5、一些特殊服務
       一些特殊的服務只在獨立的環境中才有意義,定時服務就一個很好例子,這種服務可以在一個固定的間隔時間有規律的觸發。定時服務常用於執行一些自動化管理任務。如日誌檔案滾動,系統資料備份,資料庫一致性檢查和冗餘資料清理等。對於這些服務,他們大部分不是由請求觸發的,負載均衡是沒有任何用處的,如果遷移到叢集中,有些服務也是固定在某臺應用伺服器上的,而不是每個伺服器上都要開啟這些服務。

        看了上面總結的這些問題,你還敢拍著胸脯說,我的系統可以遷移到叢集中,我們的系統在壓力大了之後可以做負載均衡啊?有些問題是可以在系統的演變升級中逐漸完善的,但是有些問題就需要我們在設計和開發階段就要去思考,並做出相應的解決方案的。WHY總是先於HOW的,先去分析然後再做,多動腦子總比光動手要好得多。從上面的一些問題引申出的一些思考:
       1、一個好的架構師是多麼的重要,不要以為他們沒有像牛一樣的工作就遭到鄙夷,他們在用腦子工作,他們的能力就是分析問題,防患於未然。我們每個人都應該向著能防範問題的方向去思考和發展。
       2、是自我吹噓也罷,我依然認為我做了一個正確的決定,將系統抽象出了平臺層和應用層。以上出現的大部分問題,我們都可以在平臺層上去做正確的實現方案,然後將API暴露給應用層。比如我們統一封裝支援分散式的快取,對於靜態變數的處理,我們在平臺層上可以採用全域性分散式快取或者KEY-VALUE資料庫這樣的方案來進行替代,並公佈API。平臺層的建立,有效的降低了應用層的開發難度,讓他們更關注業務,而不是太多的技術細節。平臺層可以制定相應的技術標準和規範,可以持續不斷的積累完善,可以被更多系統複用,對於一個團隊發展都是有好處的。
        3、一個建議,儘量不要讓一個業務型的專案經理來做架構設計的工作,他們的關注點是截然不同的,他只會關注進度,這對架構設計沒有任何好處。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/24790026/viewspace-691786/,如需轉載,請註明出處,否則將追究法律責任。

相關文章