Memcache,Redis,MongoDB(資料快取系統)方案對比與分析

suifeng3051發表於2014-04-15
一、問題:
     
    資料庫表資料量極大(千萬條),要求讓伺服器更加快速地響應使用者的需求。

二、解決方案:
     1.通過高速伺服器Cache快取資料庫資料
     2.記憶體資料庫

  (這裡僅從資料快取方面考慮,當然,後期可以採用Hadoop+HBase+Hive等分散式儲存分析平臺)

三、主流解Cache和資料庫對比:

     上述技術基本上代表了當今在資料儲存方面所有的實現方案,其中主要涉及到了普通關係型資料庫(MySQL/PostgreSQL),NoSQL資料庫(MongoDB),記憶體資料庫(Redis),記憶體Cache(Memcached),我們現在需要的是對大資料表仍保持高效的查詢速度,普通關係型資料庫是無法滿足的。而MongoDB其實只是一種非關係型資料庫,其優勢在於可以儲存海量資料,具備強大的查詢功能,因此不宜用於快取資料的場景。

 

       從以上各資料可知,對於我們產品最可行的技術方案有兩種:
         1.Memcached         記憶體Key-Value Cache
         2.Redis                     記憶體資料庫

四、下面重點分析Memcached和Redis兩種方案:

4.1 Memcached介紹  

     Memcached 是一個高效能的分散式記憶體物件快取系統,用於動態Web應用以減輕資料庫負載。它通過在記憶體中快取資料和物件來減少讀取資料庫的次數,從而提供動態、資料庫驅動網站的速度,現在已被LiveJournal、hatena、Facebook、Vox、LiveJournal等公司所使用。

4.2 Memcached工作方式分析
     
     許多Web應用都將資料儲存到RDBMS中,應用伺服器從中讀取資料並在瀏覽器中顯示。 但隨著資料量的增大、訪問的集中,就會出現RDBMS的負擔加重、資料庫響應惡化、 網站顯示延遲等重大影響。Memcached是高效能的分散式記憶體快取伺服器,通過快取資料庫查詢結果,減少資料庫訪問次數,以提高動態Web等應用的速度、 提高可擴充套件性。下圖展示了memcache與資料庫端協同工作情況:

     

     其中的過程是這樣的:
           1.檢查使用者請求的資料是快取中是否有存在,如果有存在的話,只需要直接把請求的資料返回,無需查詢資料庫。

           2.如果請求的資料在快取中找不到,這時候再去查詢資料庫。返回請求資料的同時,把資料儲存到快取中一份。
           3.保持快取的“新鮮性”,每當資料發生變化的時候(比如,資料有被修改,或被刪除的情況下),要同步的更新快取資訊,確保使用者不會在快取取到舊的資料。


     Memcached作為高速執行的分散式快取伺服器,具有以下的特點: 
  • 協議簡單 
  • 基於libevent的事件處理 
  • 內建記憶體儲存方式
  • memcached不互相通訊的分散式

4.3 如何實現分散式可擴充性?

     Memcached的分散式不是在伺服器端實現的,而是在客戶端應用中實現的,即通過內建演算法制定目標資料的節點,如下圖所示:
4.4 Redis 介紹  

     Redis是一個key-value儲存系統。和Memcached類似,它支援儲存的value型別相對更多,包括string(字串)、list(連結串列)、set(集合)和zset(有序集合)。這些資料型別都支援push/pop、add/remove及取交集並集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支援各種不同方式的排序。與memcached一樣,為了保證效率,資料都是快取在記憶體中。區別的是redis會週期性的把更新的資料寫入磁碟或者把修改操作寫入追加的記錄檔案,並且在此基礎上實現了master-slave(主從)同步,當前Redis的應用已經非常廣泛,國內像新浪、淘寶,國外像 Flickr、Github等均在使用Redis的快取服務。
4.5 Redis 工作方式分析

     Redis作為一個高效能的key-value資料庫具有以下特徵: 
    • 多樣的資料模型 
    • 持久化 
    • 主從同步  
     Redis支援豐富的資料型別,最為常用的資料型別主要由五種:String、Hash、List、Set和Sorted Set。Redis通常將資料儲存於記憶體中,或被配置為使用虛擬記憶體。Redis有一個很重要的特點就是它可以實現持久化資料,通過兩種方式可以實現資料持久化:使用RDB快照的方式,將記憶體中的資料不斷寫入磁碟;或使用類似MySQL的AOF日誌方式,記錄每次更新的日誌。前者效能較高,但是可能會引起一定程度的資料丟失;後者相反。
Redis支援將資料同步到多臺從資料庫上,這種特性對提高讀取效能非常有益。
     

4.6 Redis如何實現分散式可擴充性?

2.8以前的版本:與Memcached一致,可以在客戶端實現,也可以使用代理,twitter已開發出用於Redis和Memcached的代理Twemproxy 。
3.0以後的版本:相較於Memcached只能採用客戶端實現分散式儲存,Redis則在伺服器端構建分散式儲存。Redis Cluster是一個實現了分散式且允許單點故障的Redis高階版本,它沒有中心節點,各個節點地位一致,具有線性可伸縮的功能。如圖給出Redis Cluster的分散式儲存架構,其中節點與節點之間通過二進位制協議進行通訊,節點與客戶端之間通過ascii協議進行通訊。在資料的放置策略上,Redis Cluster將整個key的數值域分成16384個雜湊槽,每個節點上可以儲存一個或多個雜湊槽,也就是說當前Redis Cluster支援的最大節點數就是16384
     

五、綜合結論

   
 應該說Memcached和Redis都能很好的滿足解決我們的問題,它們效能都很高,總的來說,可以把Redis理解為是對Memcached的擴充,是更加重量級的實現,提供了更多更強大的功能。具體來說:
1.效能上:
     效能上都很出色,具體到細節,由於Redis只使用單核,而Memcached可以使用多核,所以平均每一個核上Redis在儲存小資料時比

Memcached效能更高。而在100k以上的資料中,Memcached效能要高於Redis,雖然Redis最近也在儲存大資料的效能上進行優化,但是比起 Memcached,還是稍有遜色。

2.記憶體空間和資料量大小:
     MemCached可以修改最大記憶體,採用LRU演算法。Redis增加了VM的特性,突破了實體記憶體的限制。
3.操作便利上:
     MemCached資料結構單一,僅用來快取資料,而Redis支援更加豐富的資料型別,也可以在伺服器端直接對資料進行豐富的操作,這樣可以減少網路IO次數和資料體積。
4.可靠性上:
     MemCached不支援資料持久化,斷電或重啟後資料消失,但其穩定性是有保證的。Redis支援資料持久化和資料恢復,允許單點故障,但是同時也會付出效能的代價。
5.應用場景:
     Memcached:動態系統中減輕資料庫負載,提升效能;做快取,適合多讀少寫,大資料量的情況(如人人網大量查詢使用者資訊、好友資訊、文章資訊等)。
     Redis:適用於對讀寫效率要求都很高,資料處理業務複雜和對安全性要求較高的系統(如新浪微博的計數和微博釋出部分系統,對資料安全性、讀寫要求都很高)。
六、需要慎重考慮的部分
1.Memcached單個key-value大小有限,一個value最大隻支援1MB,而Redis最大支援512MB
2.Memcached只是個記憶體快取,對可靠性無要求;而Redis更傾向於記憶體資料庫,因此對對可靠性方面要求比較高
3.從本質上講,Memcached只是一個單一key-value記憶體Cache;而Redis則是一個資料結構記憶體資料庫,支援五種資料型別,因此Redis除單純快取作用外,還可以處理一些簡單的邏輯運算,Redis不僅可以快取,而且還可以作為資料庫用
4.新版本(3.0)的Redis是指叢集分散式,也就是說叢集本身均衡客戶端請求,各個節點可以交流,可擴充行、可維護性更強大。

   


相關文章