負載均衡算法有不少,好比論詢、隨機、加權輪詢等。那如何才能實現一個會話粘滯(session sticky)的負載均衡算法呢?也就是說,咱們須要在同一個客戶端上,把在一次會話中的全部請求都路由到同一個服務器上。算法
最直接的方法就是,維護一張映射關係表,這張表的內容是客戶端 IP 地址或者會話 ID 與服務器編號的映射關係。客戶端每次發出請求時,就從映射表中查找到對應的服務器編號,而後再請求該編號的服務器。這種方法簡單直觀,但也有幾個弊端:數據庫
若是藉助哈希算法,咱們能夠對客戶端 IP 地址或者會話 ID 計算哈希值,將獲得的哈希值與服務器列表的大小進行取模運算,獲得的值就是應該被路由到的服務器。這樣,咱們就把同一個 IP 過來的全部請求,都路由到同一個後端服務器上。後端
若是咱們要處理 1T 的日誌文件,來統計用戶的搜索關鍵詞特性。顯然,一臺機器不只內存不夠,並且處理速度也會很慢。所以,咱們能夠先對數據進行分片,而後採用多臺數據處理的方法,來提升處理速度。緩存
咱們對讀出的每一個搜索關鍵詞用哈希函數來計算哈希值,而後再和機器總數 N 取模,最終獲得的值,就是該關鍵詞應該被分配到的機器編號。這樣,同一個關鍵詞就會被分配到同一個機器上,每一個機器會分別統計關鍵詞出現的次數,最後再把結果合併起來。服務器
在 哈希算法上 中,咱們介紹瞭如何應用哈希算法構建散列表來判斷圖片是否在圖庫中。但若是圖片數量很是多的話,咱們就沒法在一臺機器上創建散列表。session
這時候,咱們就能夠仿照上面的思路,將數據進行分片,而後採用多機處理。咱們對圖庫中的每張圖片計算惟一標識,再和機器總數 N 取模,獲得的值就是應該被分配到的機器編號,而後咱們把惟一標識和圖片路徑發往對應的機器構建散列表。數據結構
當咱們要判斷一張圖片是否在圖庫中的時候,咱們經過一樣的哈希算法,計算這個圖片的惟一標識,再和機器總數 N 取模,而後就到對應的機器中去查找。負載均衡
如今互聯網面對的都是海量的數據、海量的用戶,爲了提升對數據的讀取、寫入能力,通常都採用分佈式的方式來存儲數據,好比分佈式緩存,咱們須要將數據分佈在多臺機器上。分佈式
該如何決定某個數據該放到哪臺機器上呢?咱們能夠借用前面數據分片的思想,即經過哈希算法對數據取哈希值,而後對機器個數取模,而後做爲該數據應該存儲的緩存機器編號。函數
可是,若是數據增多,原來的 10 個機器已經沒法承受了,咱們就須要進行擴容,好比擴充到 11 臺機器。這時候,麻煩就來了,原來的數據是經過 10 來取模的,如今須要按照 11 來取模,一樣的數據就會被分配到不一樣的機器上去了。
所以,全部的數據都須要從新計算哈希值,而後搬移到正確的機器上。這樣就至關於緩存中的數據一會兒就都失效了。全部的數據都會穿透緩存,直接去請求數據庫。這樣就可能發生雪崩效應,壓跨數據庫。所以,咱們須要一種方法,使得在新加入一個機器後,並不須要作大量的數據搬移。
一致性哈希算法。假設咱們有 K 個機器,數據的哈希值的範圍爲 [0, MAX]。咱們將整個範圍劃分爲 m 個小區間(m 遠大於 K),每一個機器負責 m/K 個小區間。當有新機器加入的時候,咱們就將某幾個小區間的數據搬移到新機器上去。這樣,既不用所有從新計算哈希值,搬移數據,也保持了各個機器上數據數量的均衡。
獲取更多精彩,請關注「seniusen」!