分布式緩存架構
先看架構:
圖一
用戶通過訪問http服務器,然后訪問應用服務器資源,應用服務器調用后端的數據庫,在第一次訪問的時候,直接訪問數據庫,然后將要緩存的內容放入memcached集群,集群規模根據緩存文件的大小而定。在第二次訪問的時候就直接進入緩存讀取,不需要進行數據庫的操作。這個適合數據變化不頻繁的場景,比如:互聯網站顯示的榜單、閱讀排行等。
博客園的48小時閱讀排行就類似於這一種:
當然,緩存的架構使用方式不止這一種方式,在數據挖掘系統中,對於不頻繁更新的數據或者離線的數據都可以使用這種方式。具體的應用需要在不同的場景下進行架構設計。
一致性hash
一致性哈希算法在1997年由麻省理工學院提出的一種分布式哈希(DHT)實現算法,設計目標是為了解決因特網中的熱點(Hot spot)問題,初衷和CARP十分類似。一致性哈希修正了CARP使用的簡 單哈希算法帶來的問題,使得分布式哈希(DHT)可以在P2P環境中真正得到應用。
一致性hash算法提出了在動態變化的Cache環境中,判定哈希算法好壞的四個定義:
1、平衡性(Balance):平衡性是指哈希的結果能夠盡可能分布到所有的緩沖中去,這樣可以使得所有的緩沖空間都得到利用。很多哈希算法都能夠滿足這一條件。
2、單調性(Monotonicity):單調性是指如果已經有一些內容通過哈希分派到了相應的緩沖中,又有新的緩沖加入到系統中。哈希的結果應能夠保證原有已分配的內容可以被映射到原有的或者新的緩沖中去,而不會被映射到舊的緩沖集合中的其他緩沖區。
3、分散性(Spread):在分布式環境中,終端有可能看不到所有的緩沖,而是只能看到其中的一部分。當終端希望通過哈希過程將內容映射到緩沖上時,由於不同終端所見的緩沖范圍有可能不同,從而導致哈希的結果不一致,最終的結果是相同的內容被不同的終端映射到不同的緩沖區中。這種情況顯然是應該避免的,因為它導致相同內容被存儲到不同緩沖中去,降低了系統存儲的效率。分散性的定義就是上述情況發生的嚴重程度。好的哈希算法應能夠盡量避免不一致的情況發生,也就是盡量降低分散性。
4、負載(Load):負載問題實際上是從另一個角度看待分散性問題。既然不同的終端可能將相同的內容映射到不同的緩沖區中,那么對於一個特定的緩沖區而言,也可能被不同的用戶映射為不同 的內容。與分散性一樣,這種情況也是應當避免的,因此好的哈希算法應能夠盡量降低緩沖的負荷。
在分布式集群中,對機器的添加刪除,或者機器故障后自動脫離集群這些操作是分布式集群管理最基本的功能。如果采用常用的hash(object)%N算法,那么在有機器添加或者刪除后,很多原有的數據就無法找到了,這樣嚴重的違反了單調性原則。接下來主要講解一下一致性哈希算法是如何設計的:
1、 hash機器節點
首先求出機器節點的hash值(怎么算機器節點的hash?ip可以作為hash的參數吧。。當然還有其他的方法了),然后將其分布到0~2^32的一個圓環上(順時針分布)。如下圖所示:
圖二
集群中有機器:A , B, C, D, E五台機器,通過一定的hash算法我們將其分布到如上圖所示的環上。
2、訪問方式
如果有一個寫入緩存的請求,其中Key值為K,計算器hash值Hash(K), Hash(K) 對應於圖 – 1環中的某一個點,如果該點對應沒有映射到具體的某一個機器節點,那么順時針查找,直到第一次找到有映射機器的節點,該節點就是確定的目標節點,如果超過了2^32仍然找不到節點,則命中第一個機器節點。比如 Hash(K) 的值介於A~B之間,那么命中的機器節點應該是B節點(如上圖 )。
3、增加節點的處理
如上圖二,在原有集群的基礎上欲增加一台機器F,增加過程如下:
計算機器節點的Hash值,將機器映射到環中的一個節點,如下圖:
圖三
增加機器節點F之后,訪問策略不改變,依然按照(2)中的方式訪問,此時緩存命不中的情況依然不可避免,不能命中的數據是hash(K)在增加節點以前落在C~F之間的數據。盡管依然存在節點增加帶來的命中問題,但是比較傳統的 hash取模的方式,一致性hash已經將不命中的數據降到了最低。
Memcached
Memcached 是一個高性能的分布式內存對象緩存系統,用於動態Web應用以減輕數據庫負載。它通過在內存中緩存數據和對象來減少讀取數據庫的次數,從而提高動態、數據庫驅動網站的速度。Memcached基於一個存儲鍵/值對的hashmap。其守護進程(daemon )是用C寫的,但是客戶端可以用任何語言來編寫,並通過memcached協議與守護進程通信。下圖圖四介紹的是緩存的拓補結構:
圖四
Memcached的特點包括:
- 全內存運轉
- 哈希方式存儲
- 簡單文本協議進行數據通信
- 叧操作字符型數據
- 其它類型數據由應用解釋,序列化以及反序列化
- 集群也由應用進行控制,采用一致性散列(哈希)算法
Memcached變種產品介紹
國內外有很多基於Memcached開發的產品,這些產品支持所有Memcached的協議,同時側重不同的應用場景,可以根據自己的應用需求選擇合適的Memcached變種。下面分別介紹幾種Memcached的變種產品。
1. memcachedb
memcachedb是新浪網基於Memcached開發的一個開源項目。通過為Memcached增加Berkeley DB的持久化存儲機制和異步主輔復制機制,使Memcached具備了事務恢復能力、持久化能力和分布式復制能力,非常適合需要超高性能讀寫速度、持久化保存的應用場景,例如,將memcachedb應用於新浪博客的管理。如果對Memcached有持久化需求,可以考慮使用memcachedb。
2. repcached
repcached是日本人開發的基於Memcached的一個patch,實現Memcached的復制功能,它支持多個Memcached之間相互復制,可以解決Memcached的容災問題。有cache容災需求的可以嘗試使用這一功能。
3. memcached_functions_mysql
這個功能相當於MySQL的UDFs(User Defined Functions),在MySQL中通過觸發器更新Memcached。這樣可以做到把數據寫入MySQL,然后從Memcached獲取數據,以減輕數據庫的壓力,同時減少很多開發的工作量。
關於memcached_functions_mysql的使用和經驗會在下一節進行詳細介紹。
4. memcacheQ
memcacheQ在Memcached的基礎上實現了消息隊列。下面以PHP客戶端為例介紹memcacheQ實現消息隊列的方式。
消息從尾部入棧:memcache_set
消息從頭部出棧:memcache_get
memcacheQ最大的優勢是:它是基於Memcached開發的,可以通過各種Memcached命令對它進行操作。基於Memcached開發的應用完全不需要做任何修改。
總結
分布式緩存通常用在頻繁訪問或者不能實時處理的情況下,使用場景包括:
1、訪問量大於更新量的場景。
2、需要離線處理數據的場景。
3、后端為列式數據庫的場景。
還有其它很多的應用場景與數據挖掘系統的模型層進行整合,快速提供訪問模型處理結果,總之,在架構設計中很好的利用緩存將極大的提高應用程序的性能,使整個系統更加健壯。