#41 Load Balance 負載平衡

Load Balance 顧名思義就知道是在兩個以上的運算器環境下將每個運算器的運算負載量達成一致的目的.這樣子的概念應該在許多的情境之下,例如大型網站或是大型的資料庫等.這種類型的情境一定都有一個共同的特點,那就是 request 的 client 很多而提供 service 的 server 很少.

我們以大型網站服務為例子.最先開始架設一台網站伺服器來服務某一數量的用戶端,只要用戶端不繼續增加或是服務本身的運算邏輯沒有變的更複雜時,則一切都會相安無事.只要其中一個有增多的現象時,最終總是會面臨到該網站伺服器的資源不用使用的情況.因為每個用戶端連線都需要佔用 CPU/Memory 資源,所以既便是 CPU 再快 Memory 再多,也是會遇到上限.因此,要解決的方法有兩種,一個稱為 scale up,另一個稱為 scale out.Scale up 是指在同一個伺服器內進行硬體的升級以求在同一時間內服務更多的用戶端,例如升級 CPU,記憶體,網路卡等等.Scale out 是指再加入其他的伺服器來服務用戶端.通常來說,scale up的方式比較受限,而且一台伺服器若是要能裝入更多的 CPU 和 Memory,則價錢通常都是非常地高,所以比較經濟的做法就是 scale out.

Scale out 第一個會遇到的問題就是該如何分派工作.既然要達到負載平衡,也就是每台伺服器的運算負載量是接近一致的,那麼首要考慮的事情就是該如何達到一致.如果每個用戶端所要求的工作量都是固定的,很容易就可以做到負載量是一致的.因為只要在這些伺服器前都有一個 dispatcher 來輪流地分配工作,就可以達成負載量一致的效果,就如下圖一樣.


這種方式有一個缺點,dispatcher 將會是 single point of failure,單一失敗點,也就是說它若壞掉了,整個系統便無法運作.這種運作方式也稱為 Round-robin,輪流分配工作.在直實世界中,我們很難要求每一個用戶端都會有相同的運算工作量,因此每個用戶端送過來的需求一定會有不同的運算工作量,因此用 round-robin 的方式是很難達成負載量一致的,只能說是用戶端需求分配數量是一致的,因為很有可能某一個伺服器都會收到運算量很大的工作導致它比別的伺服器來的更加忙碌或是資源更吃緊.Round-robin 的方式算是集中式的管理,因為都是透過 dispatcher 來運作.

另外還有一種比較常見的負載平衡的方法是不需要 dispatcher,而是伺服器之間要互相溝通訊息,把自己的負載量資訊傳給其他的伺服器.所以每個一伺服器都會有一份每個伺服器負載量的資料,而且這分資料是經常地在更新.因此,當新的用戶端需求進來時,這份需求會先被某一個伺服器接收,然後該伺服器會依照這份資料來決定這份工作是要自己做還是傳給其他伺服器來做,這就看系統實作的是什麼樣的演算法.若採用最簡單的,也就是挑選負載量最小的伺服器,那這份工作就會被傳送到負載量最小的伺服器來處理.


這個方式聽起來似乎比較好,因為不會有 single point of failure 的問題,只是這樣的伺服器集合不適合有太多的伺服器在一起.我們簡單地想像一下,如果這個群組有十台伺服器,每一台伺服器在每隔幾秒鐘就要彼此交換負載量的資訊,這似乎不會是一個太麻煩的工作,但如果這群組變成是一百台或是一千台伺服器時,這樣的方法顯然會有問題,因為光是和其他 999 台伺服器完成一輪的負載量資訊交換可能就要花上一段時間和不少的 CPU 與 Memory,顯然不是一個經濟的做法,而且也不見得能儘量達成負載平衡.

其實在許多伺服器之間要對一份資料取得共識,也就是說一號伺服器上收集到的資料和 n 號伺服器上收集到的資料是一樣的,這也是一個很大的學問.往後的主題將會來討論這部份.
Share:

0 意見:

張貼留言