集團內部很多團隊都使用Memcache來提高應用性能,最近的一次工作匯報中提及了Memcache的Hash算法需要研究來滿足一些需求,同時提高Memcache的利用效率。討論了一下最后自己總結了這么幾點是對Hash算法需要著重考慮的。
問題:
1. 存儲數據如何均勻分散。如何把數據盡可能的散開存儲,這樣對于Memcache的可擴展性才會有充分利用,試想如果算法每次都會把數據定向到某幾臺機器,那么就會導致集群機器之間利用率的不均衡,無法發揮出集群效應。
2. 增減機器減小對原有數據存取的影響。由于業務量的增長勢必需要對后端的服務器有所擴容,但是增加或者減少機器如何盡可能小的影響已有的緩存數據,這點直接影響業務處理以及應用的效率。
3. 提高Memcache效率。Memcache在壓力測試下也會暴露出對于網絡資源的消耗問題,畢竟也是網絡間的Socket數據交互。
解決的一些思路和方法:
1. Consistent Hashing是一種比較好的解決思路。可以參看一下:http://tech.idv2.com/2008/07/24/memcached-004/ 其中主要兩個亮點就是稀釋節點以及環狀分區段管理。稀釋節點就是將原來的節點再復制幾十倍,使得離散度更高,數據更加分散。環狀分區段管理,就能夠將數據分區管理,在加入和減少節點時對數據產生影響最低,最好的類比就是解放前的地下工作者單線聯系,如果被捕不會涉及到所有的地下黨同志。
2. 集群的機器使用Memcache最好結合本地Cache,這里我們自己寫了一個本地的類似于Memcache有超時時間Cache,兩者結合一起使用緩存信息,在壓力測試下提高了20%左右的性能。這里和我們的系統也有關系,我們對于Memcache有比較大的依賴,雖然已經對于每一個請求處理都防止重復獲取信息,將必要信息放在線程上下文中,但是在運行期間還是會有不少的請求。
存儲到Memcache中的數據類型:
1. 一次寫入多次讀,很少更新。這種數據系統啟動以后構建,在非命中情況下不采用從后備數據源中獲取數據來填充Memcache。(也是提高效率,同時防止一些攻擊性的請求)
2. 多次寫入多次讀取。這類數據往往是在運行期被構建,非命中下會從后備數據源中獲取,或者是某一種計算結果的緩存。
對于第一類數據來說,增加機器需要重新構建,如果采用分區分段,那么只需要構建某一部分的數據,或者是移動數據。對于第二類數據,增加機器如果采用簡單的Hash算法也問題不大,最多存儲多份,命中率降低,但是如果采用分區,也可以降低命中率下降的情況。
這里只是拋出問題,后續如何解決請各位看官各抒己見了。當然這里自己也會考慮這方面的實現和設計。