當一個開發人員提升計算機系統負荷時,通常會考慮兩種方式垂直擴充套件和水平擴充套件。選用哪種策略主要依賴於要解決的問題以及系統資源的限制。在這篇文章中我們將講述這兩種策略並討論每種策越的優缺點。如果你已經有一個軟體系統需要不斷成長,那麼你將有意或者無意中選擇這兩種策略中的一種。
垂直擴充套件
在垂直擴充套件模型中,想要增加系統負荷就意味著要在系統現有的部件上下工夫,即通過提高系統部件的能力來實現。例如,假設你現在負責一批木材採伐的操作。
在這個例子中,我們假設有3輛卡車,每輛車一次可以運25根木材,計算花費1小時的情況下可以運送到指定地點等待處理的木材數量。通過這些數字我們可以算出我們系統最大的負荷量:
3輛卡車 * 25根木材 * 1小時=75根木材/小時
如果我們選擇垂直擴充套件模型,那麼我們將怎麼做來使我們每小時可以處理150根木材?我們需要至少做以下兩件事中的一件:
使每輛卡車的運輸量增加一倍(50棵樹每小時),或者使每輛卡車的運輸時間減半(每輛卡車30分鐘)。
3輛卡車 * 50棵樹 * 1小時 = 150棵樹/每小時
或者
3輛卡車 * 25棵樹 * 30分鐘 = 150棵樹/每小時
我們沒有增加系統的成員數,但是我們通過增加系統成員的生產效率來獲得期望的負荷量。
水平擴充套件
在水平擴充套件模型中,我們不是通過增加單個系統成員的負荷而是簡單的通過增加更多的系統成員來實現。也就是說,在以上運送木材的例子中,通過增加卡車的數量來運送木材。因此,當我們需要將負荷從75棵樹每小時增加到150棵樹每小時,那麼只需要增加3輛卡車。
6輛卡車 * 25棵樹 * 1小時 = 150棵樹/每小時
假如我們已經選擇了垂直擴充套件方式,那麼我們想要每小時處理150棵被砍伐的樹時需要怎麼做呢?我們需要做到以下兩方面之一:要麼使每輛卡車的運輸量翻倍(50棵木材一次),要麼使每輛開車的運輸時間減半(30分鐘)。
3輛卡車 * 50棵樹 * 1小時 = 150棵樹/每小時
或者
3輛卡車 * 50棵樹 * 30分鐘 = 150棵樹/每小時
在這個例子中,系統每個成員的生產力依然沒變,我們通過增加更多的卡車來提高系統的能力。
擴充套件你的web資料庫
通過對水平擴充套件和垂直擴充套件的基本瞭解,下面讓我們來關注web系統的擴充套件。一個網站通常有很多元件都需要去考慮它們的擴充套件性,但是我通常喜歡關注處在最邊緣的一個:資料庫。為什麼資料庫是最邊緣的?因為資料庫通常是共享資源,是幾乎所有請求最終的連線點。
你的系統是什麼型別的?
在 擴充套件你的資料庫時,你必須要問的一個重要問題是:“我所面對的系統是什麼型別的?”你所面對的是一個讀操作多還是寫操作多的系統?讀操作多的網站一般包 括:線上商城,在商城裡使用者大部時間是在瀏覽(讀操作),只有少數時間在付款(寫操作)、或者部落格,在部落格上人們大部分時間是在瀏覽博文(讀操作),只有 少數時間是在評論或者發表博文(寫操作)。相反的,關於寫操作非常多的很好的例子包括:信用卡交易處理器,這個系統的主要負載時在處理記錄交易(寫操 作),偶爾會查詢交易(讀操作)、或者Google分析,主要工作實在記錄業務資料(寫操作),偶爾會展示分析圖(讀操作)。
瞭解你所建立的網站是什麼型別的,可以在網站成長過程中幫助你選擇正確的技術。
讀操作擴充套件
如 果你的系統讀操作非常多,那麼通過關係型資料庫如mysql或者PostgreSql來垂直擴充套件資料儲存是一個不錯的選擇。結合你的關係型資料庫通過使用 memcached或者CDN來構建一個健壯的快取系統,那麼你的系統將非常容易擴充套件。在這種模式中,如果資料庫超負荷執行,那麼將更多的資料放入快取中 來緩解系統的讀壓力。當沒有更多的資料往快取中放時,可以更換更快的資料儲存硬體或者買更多核的處理器來獲取更多的執行通道。摩爾定律使通過這種方法來垂 直擴充套件變得和購買更好的硬體一樣簡單。
寫操作擴充套件
如 果你的系統寫操作非常多,那麼你可能更希望考慮使用可水平擴充套件的資料儲存方式,比如Riak,Cassandra或者HBase。和大多數關係型資料管理 系統不同,這種資料儲存隨著增長增加更多的節點。由於你的系統大部分時間是在寫入,所以快取曾並不能像在讀操作比較頻繁的系統中起到那麼大作用。很多寫頻 繁的系統一開始使用垂直擴充套件的方式,但是很快發現並不能根本解決問題。為什麼?因為硬碟數和處理器數在某一點達到平衡,在這個邊界上再增加一個處理器或者 一個硬碟都會是每秒鐘的I/O運算元成指數性增長。相反,如果對寫頻繁的系統採取水平擴充套件策略,那麼你將達到一個拐點,在這個拐點之後如果在增加一個節點 都遠比使用更多的硬碟來的實惠。
其他注意事項
另 一件事需要記住的是每種擴充套件策略下預想不到的開銷。採用垂直擴充套件的系統將開銷凡在單獨的元件上。當我們去提升系統負荷時,這些單獨的元件需要在管理上花費 更多。拿我們運送木材的例子來說,如果需要使每輛卡車的貨運量翻倍,那麼我們需要更寬、更長、或者更高的車廂。也許有的路因為橋的高度對車輛高度有要求, 或者基於巷子寬度車寬不能太大,又或者由於機動車安全駕駛要求車廂不能太長。這裡的限制就是對單個卡車做垂直擴充套件做的什麼程度。同樣的概念延伸到伺服器垂 直擴充套件:更多的處理器要求更多的空間,進而要求更多的伺服器儲存架。
相反的,採用水平擴充套件的系統將額外的開銷放在系統中連線起來的共享元件 上。當我們去提升系統負荷時,共享的開銷和新增加的成員之間的協調性有關。在我們運送木材的例子中,當我們在路上增加更多卡車時,那麼路就是共享資源也就 成了約束條件。這條路上適合同時跑多少量卡車?我們是否有足夠的安全緩衝區使得所有的車可以同時裝運木材?如果再來看我們水平擴充套件的資料庫系統,那麼經常 被忽略的開銷就是伺服器同時連線時的網路開銷(譯者注:網路為各個系統的共享資源)。當你為系統增加更多的節點時,共享資源的負荷也就越來越重,通常呈非 線性改變。
綜合說明
和 計算機的大多數東西一樣,好的解決辦法通常並不像我這裡列出來的這麼簡單。而我在這裡嘗試簡化這種思想用來來說明這中概念而不是講具體的解決辦法。擴充套件是 個困難的問題,這是個需要在實際處理的每個步驟中都要思考的問題。擴充套件策略沒有魔法,也沒有魔法般的軟體幫你建立一個完整可靠的可擴充套件系統。就像擴充套件中的 其他問題一樣,一個大的解決方案通常是由很多個一起協調工作的小的解決辦法組成的。這需對每一箇中解決方案進行精心正確的設計和開發。