1. 程式人生 > 程式設計 >淺析Memcached, Redis, MongoDB三者的區別

淺析Memcached, Redis, MongoDB三者的區別

Redis

是一個開源(BSD許可)的,記憶體中的資料結構儲存系統,它可以用作資料庫、快取和訊息中介軟體。 它支援多種型別的資料結構,如 字串(strings), 雜湊(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 與範圍查詢, bitmaps, hyperloglogs 和 地理空間(geospatial) 索引半徑查詢。 Redis 內建了 複製(replication),LUA指令碼(Lua scripting), LRU驅動事件(LRU eviction),事務(transactions) 和不同級別的 磁碟持久化(persistence), 並通過 Redis哨兵(Sentinel)和自動 分割槽(Cluster)提供高可用性(high availability)。

Redis的優點:

  1. 支援多種資料結構,如 string(字串)、 list(雙向連結串列)、dict(hash表)、set(集合)、zset(排序set)、hyperloglog(基數估算)。
  2. 支援持久化操作,可以進行aof及rdb資料持久化到磁碟,從而進行資料備份或資料恢復等操作,較好的防止資料丟失的手段。
  3. 支援通過Replication進行資料複製,通過master-slave機制,可以實時進行資料的同步複製,支援多級複製和增量複製,master-slave機制是Redis進行HA的重要手段。
  4. 單執行緒請求,所有命令序列執行,併發情況下不需要考慮資料一致性問題。
  5. 支援pub/sub訊息訂閱機制,可以用來進行訊息訂閱與通知。
  6. 支援簡單的事務需求,但業界使用場景很少,並不成熟。

Redis的侷限性:

  1. Redis只能使用單執行緒,效能受限於CPU效能,故單例項CPU最高才可能達到5-6wQPS每秒(取決於資料結構,資料大小以及伺服器硬體效能,日常環境中QPS高峰大約在1-2w左右)。
    支援簡單的事務需求,但業界使用場景很少,並不成熟,既是優點也是缺點。
  2. Redis在string型別上會消耗較多記憶體,可以使用dict(hash表)壓縮儲存以降低記憶體耗用。
  3. Mc和Redis都是Key-Value型別,不適合在不同資料集之間建立關係,也不適合進行查詢搜尋。比如redis的keys pattern這種匹配操作,對redis的效能是災難。

upload successfulupload successful

Memcached

是一個高效能的分散式記憶體物件快取系統,用於動態Web應用以減輕資料庫負載。它通過在記憶體中快取資料和物件來減少讀取資料庫的次數,從而提高動態、資料庫驅動網站的速度。Memcached基於一個儲存鍵/值對的hashmap。其守護程式(daemon )是用C寫的,但是客戶端可以用任何語言來編寫,並通過memcached協議與守護程式通訊。

Memcached的優點:

  1. Memcached可以利用多核優勢,單例項吞吐量極高,可以達到幾十萬QPS(取決於key、value的位元組大小以及伺服器硬體效能,日常環境中QPS高峰大約在4-6w左右)。適用於最大程度扛量。
  2. 支援直接配置為session handle。

Memcached的侷限性:

  1. 只支援簡單的key/value資料結構,不像Redis可以支援豐富的資料型別。
  2. 無法進行持久化,資料不能備份,只能用於快取使用,且重啟後資料全部丟失。
  3. 無法進行資料同步,不能將MC中的資料遷移到其他MC例項中。
  4. Memcached記憶體分配採用Slab Allocation機制管理記憶體,value大小分佈差異較大時會造成記憶體利用率降低,並引發低利用率時依然出現踢出等問題。需要使用者注重value設計。

upload successfulupload successful

MongoDB

是一個基於分散式檔案儲存的資料庫,檔案型的非關係型資料庫,與上面兩者不同。

先解釋一下檔案的資料庫,即可以存放xml、json、bson型別系那個的資料。

這些資料具備自述性(self-describing),呈現分層的樹狀資料結構。redis可以用hash存放簡單關係型資料。

MongoDB存放json格式資料。

適合場景:事件記錄、內容管理或者部落格平臺,比如評論系統。

upload successfulupload successful

Redis與Memcached的比較

1、資料型別支援不同

與Memcached僅支援簡單的key-value結構的資料記錄不同,Redis支援的資料型別要豐富得多。最為常用的資料型別主要由五種:String、Hash、List、Set和Sorted Set。Redis內部使用一個redisObject物件來表示所有的key和value。

2、記憶體管理機制不同

在Redis中,並不是所有的資料都一直儲存在記憶體中的。這是和Memcached相比一個最大的區別。

當實體記憶體用完時,Redis可以將一些很久沒用到的value交換到磁碟。Redis只會快取所有的key的資訊,如果Redis發現記憶體的使用量超過了某一個閥值,將觸發swap的操作,Redis根據“swappability = age*log(size_in_memory)”計算出哪些key對應的value需要swap到磁碟。然後再將這些key對應的value持久化到磁碟中,同時在記憶體中清除。

這種特性使得Redis可以保持超過其機器本身記憶體大小的資料。當然,機器本身的記憶體必須要能夠保持所有的key,畢竟這些資料是不會進行swap操作的。同時由於Redis將記憶體中的資料swap到磁碟中的時候,提供服務的主執行緒和進行swap操作的子執行緒會共享這部分記憶體,所以如果更新需要swap的資料,Redis將阻塞這個操作,直到子執行緒完成swap操作後才可以進行修改。

當從Redis中讀取資料的時候,如果讀取的key對應的value不在記憶體中,那麼Redis就需要從swap檔案中載入相應資料,然後再返回給請求方。 這裡就存在一個I/O執行緒池的問題。在預設的情況下,Redis會出現阻塞,即完成所有的swap檔案載入後才會相應。這種策略在客戶端的數量較小,進行批量操作的時候比較合適。但是如果將Redis應用在一個大型的網站應用程式中,這顯然是無法滿足大併發的情況的。所以Redis執行我們設定I/O執行緒池的大小,對需要從swap檔案中載入相應資料的讀取請求進行併發操作,減少阻塞的時間。

3、資料持久化支援

Redis雖然是基於記憶體的儲存系統,但是它本身是支援記憶體資料的持久化的,而且提供兩種主要的持久化策略:RDB快照和AOF日誌。而memcached是不支援資料持久化操作的。

4、叢集管理的不同

Memcached是全記憶體的資料緩衝系統,Redis雖然支援資料的持久化,但是全記憶體畢竟才是其高效能的本質。作為基於記憶體的儲存系統來說,機器實體記憶體的大小就是系統能夠容納的最大資料量。如果需要處理的資料量超過了單臺機器的實體記憶體大小,就需要構建分散式叢集來擴充套件儲存能力。

Memcached本身並不支援分散式

,因此只能在客戶端通過像一致性雜湊這樣的分散式演演算法來實現Memcached的分散式儲存。

結論

  • 沒有必要過多的關心效能,因為二者的效能都已經足夠高了。由於Redis只使用單核,而Memcached可以使用多核,所以在比較上,平均每一個核上Redis在儲存小資料時比Memcached效能更高。而在100k以上的資料中,Memcached效能要高於Redis,雖然Redis最近也在儲存大資料的效能上進行優化,但是比起Memcached,還是稍有遜色。說了這麼多,結論是,無論你使用哪一個,每秒處理請求的次數都不會成為瓶頸。(比如瓶頸可能會在網路卡)
  • 如果要說記憶體使用效率,使用簡單的key-value儲存的話,Memcached的記憶體利用率更高,而如果Redis採用hash結構來做key-value儲存,由於其組合式的壓縮,其記憶體利用率會高於Memcached。當然,這和你的應用場景和資料特性有關。
  • 如果你對資料持久化和資料同步有所要求,那麼推薦你選擇Redis,因為這兩個特性Memcached都不具備。即使你只是希望在升級或者重啟系統後快取資料不會丟失,選擇Redis也是明智的。
  • 當然,最後還得說到你的具體應用需求。Redis相比Memcached來說,擁有更多的資料結構和並支援更豐富的資料操作,通常在Memcached裡,你需要將資料拿到客戶端來進行類似的修改再set回去。這大大增加了網路IO的次數和資料體積。在Redis中,這些複雜的操作通常和一般的GET/SET一樣高效。所以,如果你需要快取能夠支援更復雜的結構和操作,那麼Redis會是不錯的選擇。