1. 程式人生 > >Redis與memcached區別

Redis與memcached區別

Redis與memcached區別

 

 

參考:http://blog.csdn.net/tonysz126/article/details/8280696

http://blog.csdn.net/colorant/article/details/21089057

https://www.zhihu.com/question/21419897

1.   為什麼需要快取

少量的資料儲存,高速讀寫訪問。此類產品通過資料全部in-memory的方式保證高速訪問,同時提供資料落地功能

 

2.   Redis與Memcached的區別

 

2.1.          資料型別儲存

         Memcached只支援簡單的K/V資料型別

         Redis不僅僅支援簡答的K/V型別資料,同時還提供了List,Set,SortedSet,Hash等資料結構的儲存

 

2.2.          資料的備份

         Redis可以以master-slave的方式配置伺服器,Slave節點對資料進行replica備份,Slave節點也可以充當Read only的節點分擔資料讀取的工作

 

2.3.          資料的持久化

         memcached不保證儲存的資料的有效性,Slab內部基於LRU也會自動淘汰舊資料。

客戶端不能假設資料在伺服器端的當前狀態,這應該說是Memcached的Feature設定,使用者不必太多關心或者自己管理資料的淘汰更新工作。Memcached也不做資料的持久化工作,但是有許多基於memcached協議的專案實現了資料的持久化,例如memcacheDB使用BerkeleyDB進行資料儲存,但本質上它已經不是一個Cache Server,而只是一個相容Memcached的協議key-valueData Store了。

 

         Redis支援資料的持久化,可以將記憶體中的資料儲存在磁碟中,重啟時可以再次載入使用。Redis內建支援兩種持久化方案,snapshot快照和AOF 增量Log方式。快照顧名思義就是隔一段時間將完整的資料Dump下來儲存在檔案中。AOF增量Log則是記錄對資料的修改操作(實際上記錄的就是每個對資料產生修改的命令本身),兩種方案可以並存,也各有優缺點,具體參見 http://redis.io/topics/persistence

         Redis並不是所有的資料都一直儲存在記憶體中,這是和Memcached相比最大的區別。Redis只會快取所有的key資訊,如果Redis發現記憶體的使用量超過一個閥值後,將進行swap操作,計算出哪些key需要交換到磁碟中。然後再將這些key對應的value持久化到磁碟,同時在記憶體中清除這些資料。

         Redis將記憶體中的資料swap到磁碟中的時候,提供服務的主執行緒和進行swap操作的子執行緒會共享這部分記憶體,所以如果更新需要swap的資料,Redis將阻塞這個操作,直到子執行緒完成swap操作後才可以進行修改。

 

2.4.          資料的一致性(事務)

         Memcached提供了cas命令,可以保證多個併發訪問操作同一份資料的一致性問題。

除了increment/decrement這樣的原子操作命令,不存在對事務的支援

 

         Redis沒有提供cas 命令,並不能保證這點。不過Redis提供了事務的功能,可以保證一串 命令的原子性,中間不會被任何操作打斷。

         Redis通過Multi / Watch /Exec等命令可以支援事務的概念,原子性的執行一批命令。在2.6以後的版本中由於添加了對Script指令碼的支援,而指令碼固有的是以transaction事務的方式執行的,並且更加易於使用

 

2.5.          網路IO模型

          Memcached是多執行緒,非阻塞IO複用的網路模型,分為監聽主執行緒和worker子執行緒,監聽執行緒監聽網路連線,接受請求後,將連線描述字pipe 傳遞給worker執行緒,進行讀寫IO, 網路層使用libevent封裝的事件庫,多執行緒模型可以發揮多核作用,但是引入了cache coherency和鎖的問題,比如,Memcached最常用的stats 命令,實際Memcached所有操作都要對這個全域性變數加鎖,進行計數等工作,帶來了效能損耗。

          Redis使用單執行緒的IO複用模型,自己封裝了一個簡單的AeEvent事件處理框架,主要實現了epoll、kqueue和select,對於單純只有IO操作來說,單執行緒可以將速度優勢發揮到最大,但是Redis也提供了一些簡單的計算功能,比如排序、聚合等,對於這些操作,單執行緒模型實際會嚴重影響整體吞吐量,CPU計算過程中,整個IO排程都是被阻塞住的。

2.6.          記憶體管理

          Memcached使用預分配的記憶體池的方式,使用slab和大小不同的chunk來管理記憶體,Item根據大小選擇合適的chunk儲存,記憶體池的方式可以省去申請/釋放記憶體的開銷,並且能減小記憶體碎片產生,但這種方式也會帶來一定程度上的空間浪費,並且在記憶體仍然有很大空間時,新的資料也可能會被剔除,原因可以參考Timyang的文章:http://timyang.net/data/Memcached-lru-evictions/

Redis使用現場申請記憶體的方式來儲存資料,並且很少使用free-list等方式來優化記憶體分配,會在一定程度上存在記憶體碎片,Redis跟據儲存命令引數,會把帶過期時間的資料單獨存放在一起,並把它們稱為臨時資料,非臨時資料是永遠不會被剔除的,即便實體記憶體不夠導致swap也不會剔除任何非臨時資料(但會嘗試剔除部分臨時資料),這點上Redis更適合作為儲存而不是cache

 

2.7.          叢集

Memcached本身並不支援分散式,因此只能在客戶端通過像一致性雜湊這樣的分散式演算法來實現Memcached的分散式儲存。下圖給出了Memcached的分散式儲存實現架構。當客戶端向Memcached叢集傳送資料之前,首先會通過內建的分散式演算法計算出該條資料的目標節點,然後資料會直接傳送到該節點上儲存。但客戶端查詢資料時,同樣要計算出查詢資料所在的節點,然後直接向該節點發送查詢請求以獲取資料。

 

Redis3.0之前

客戶端Redis Sharding技術其主要思想是採用一致性雜湊演算法(consistent hashing),將key和節點name同時hashing。採用一致性雜湊而不是採用簡單類似雜湊求模對映的主要原因是當增加或減少節點時,不會產生由於重新匹配造成的rehashing。一致性雜湊隻影響相鄰節點key分配,影響量小。

 

Redis3.0

Redis Cluster中,Sharding採用slot(槽)的概念,一共分成16384個槽,這有點兒類pre sharding思路。對於每個進入Redis的鍵值對,根據key進行雜湊,分配到這16384個slot中的某一箇中。使用的hash演算法也比較簡單,就是CRC16後16384取模。

http://doc.redisfans.com/topic/cluster-tutorial.html

3.   總結

1.Redis使用最佳方式是全部資料in-memory。

2.Redis更多場景是作為Memcached的替代者來使用。

3.當需要除key/value之外的更多資料型別支援時,使用Redis更合適。

4.當儲存的資料不能被剔除時,使用Redis更合適。