天天看點

跟我一起資料挖掘(17)——分布式緩存分布式緩存架構 一緻性hash Memcached Memcached變種産品介紹 總結

先看架構:

跟我一起資料挖掘(17)——分布式緩存分布式緩存架構 一緻性hash Memcached Memcached變種産品介紹 總結

                                                    圖一

使用者通過通路http伺服器,然後通路應用伺服器資源,應用伺服器調用後端的資料庫,在第一次通路的時候,直接通路資料庫,然後将要緩存的内容放入memcached叢集,叢集規模根據緩存檔案的大小而定。在第二次通路的時候就直接進入緩存讀取,不需要進行資料庫的操作。這個适合資料變化不頻繁的場景,比如:網際網路站顯示的榜單、閱讀排行等。

部落格園的48小時閱讀排行就類似于這一種:

跟我一起資料挖掘(17)——分布式緩存分布式緩存架構 一緻性hash Memcached Memcached變種産品介紹 總結

當然,緩存的架構使用方式不止這一種方式,在資料挖掘系統中,對于不頻繁更新的資料或者離線的資料都可以使用這種方式。具體的應用需要在不同的場景下進行架構設計。

一緻性雜湊演算法在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的一個圓環上(順時針分布)。如下圖所示:

跟我一起資料挖掘(17)——分布式緩存分布式緩存架構 一緻性hash Memcached Memcached變種産品介紹 總結
                                圖二

叢集中有機器: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值,将機器映射到環中的一個節點,如下圖:

跟我一起資料挖掘(17)——分布式緩存分布式緩存架構 一緻性hash Memcached Memcached變種産品介紹 總結

                                 圖三

增加機器節點f之後,通路政策不改變,依然按照(2)中的方式通路,此時緩存命不中的情況依然不可避免,不能命中的資料是hash(k)在增加節點以前落在c~f之間的資料。盡管依然存在節點增加帶來的命中問題,但是比較傳統的 hash取模的方式,一緻性hash已經将不命中的資料降到了最低。

memcached 是一個高性能的分布式記憶體對象緩存系統,用于動态web應用以減輕資料庫負載。它通過在記憶體中緩存資料和對象來減少讀取資料庫的次數,進而提高動态、資料庫驅動網站的速度。memcached基于一個存儲鍵/值對的hashmap。其守護程序(daemon )是用c寫的,但是用戶端可以用任何語言來編寫,并通過memcached協定與守護程序通信。下圖圖四介紹的是緩存的拓補結構:

跟我一起資料挖掘(17)——分布式緩存分布式緩存架構 一緻性hash 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、後端為列式資料庫的場景。

還有其它很多的應用場景與資料挖掘系統的模型層進行整合,快速提供通路模型處理結果,總之,在架構設計中很好的利用緩存将極大的提高應用程式的性能,使整個系統更加健壯。