memcache與一致性HASH算法

       很多Memcache客戶端,都使用一致性HASH算法(Consistent Hashing)來實現對Memcache的分佈式管理。使用一致性HASH算法可儘可能的降低緩存系統伸縮(比如添加、移除緩存服務器)時原HASH映射關係的變化率。

       通常,值進行集合映射最簡單的辦法是CRC32散列後取模,這個模數是被映射到的集合範圍。但是,當模數變化時,原有映射關係也發生明顯的變化,在分佈式緩存系統中,會造成緩存大範圍的失效。

       使用一致性HASH,節點故障時,緩存失效的範圍可以縮小到相應故障節點影響的範圍,而不會對其它的節點產生影響。新增節點時,影響範圍可以縮小到隻影響下一個節點(我們認爲集羣中的所有緩存服務器節點都被部署在一個環形上,範圍是0到2^32-1)部分緩存數據的命中,因爲未被命中的數據被認爲分佈在了新的服務器節點上。

       節點映射情況如下:

       wKioL1MSv9zydmiEAANG3jyXV04997.jpg


       首先通過HASH運算,將服務器緩存節點散列在一個0到2^32-1範圍內的一個環上,也就是4字節存儲無符號數據類型的空間,散列值通過crc32哈唏函數計算得到。

       對於所要存儲的數據,系統對KEY也通過crc32進行HASH運算,同樣得到一個0到2^32-1範圍內的HASH值,根據這個HASH值所落環上的位置,尋找最近的下一個數據緩存節點進行數據緩存。比如圖所示:key1, key2落在了svr2上,key3, key4, key5落到了svr3上,而key6, key7落到了svr4上。當然,如果key計算出來的HASH值找不到比它大的HASH緩存節點,則該key將落在第一個緩存節點上,也正因爲此,形成了一個環形的數據結構。

       使用這種數據結構,如果svr2掛了,則只會影響key1, key2緩存的命中,並不會影響其它緩存數據的命中,同時key1, key2新的數據會被映射到svr3上。如果新增一臺緩存服務器svr+,假設被映射到svr3和svr4之間,則此時僅僅會影響svr3到svr+之間數據的命中,當然了,下一次這個區間的數據會被緩存在svr+上。

       使用一致性HASH算法的最大特色是新增、刪除緩存節點時,避免對其它節點的影響。很顯然,緩存服務器越多,每臺服務器所管轄的區間就會越小,故障時所產生的影響也會越小。

       

       雖說如此,但CRC32算法並無法保證每臺緩存服務器可以均勻的分佈在HASH環上,也許有的管轄區間大,有的管轄的區間小,這樣就對數據存儲的平衡性帶來了影響。同樣,硬件好的服務器希望多幹點活,次點的服務器希望少乾點活,這種需要也是常見的。爲了提高數據的平衡性,又引入了虛擬節點的概念。

       例如:

       有三臺服務器SVR1, SVR2, SVR3, 我們希望它們服務的權重分別是1:3:5的關係。假設虛擬節點的基數爲10,則SVR1對應10個虛擬節點,SVR2對應30個虛擬節點,SVR3對應50個虛擬節點。虛擬節點也是通過CRC32算法散列在不同的點。這樣,如果說散列3次拼的是人品,那麼散列90次(10+30+50),基本上拼的就是技術了。

       引入虛擬節點後,需要緩存的數據的KEY,經過HASH運算,先找到離它最近的一個虛擬節點,然後根據虛擬節點與具體緩存服務器的對應關係映射到具體的機器上。這樣基本上可保持平衡和權重設定的比例。






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章