淺析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)。html

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 successfulgit

Memcached

是一個高性能的分佈式內存對象緩存系統,用於動態Web應用以減輕數據庫負載。它經過在內存中緩存數據和對象來減小讀取數據庫的次數,從而提升動態、數據庫驅動網站的速度。Memcached基於一個存儲鍵/值對的hashmap。其守護進程(daemon )是用C寫的,可是客戶端能夠用任何語言來編寫,並經過memcached協議與守護進程通訊。github

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 successfulweb

MongoDB

是一個基於分佈式文件存儲的數據庫,文檔型的非關係型數據庫,與上面二者不一樣。redis

先解釋一下文檔的數據庫,便可以存放xml、json、bson類型系那個的數據。算法

這些數據具有自述性(self-describing),呈現分層的樹狀數據結構。redis能夠用hash存放簡單關係型數據。數據庫

MongoDB存放json格式數據。json

適合場景:事件記錄、內容管理或者博客平臺,好比評論系統。緩存

upload successfulupload successful服務器

Redis與Memcached的比較

一、數據類型支持不一樣

與Memcached僅支持簡單的key-value結構的數據記錄不一樣,Redis支持的數據類型要豐富得多。最爲經常使用的數據類型主要由五種:String、Hash、List、Set和Sorted Set。Redis內部使用一個redisObject對象來表示全部的key和value。

二、內存管理機制不一樣

在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文件中加載相應數據的讀取請求進行併發操做,減小阻塞的時間。

三、數據持久化支持

Redis雖然是基於內存的存儲系統,可是它自己是支持內存數據的持久化的,並且提供兩種主要的持久化策略:RDB快照和AOF日誌。而memcached是不支持數據持久化操做的。

四、集羣管理的不一樣

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會是不錯的選擇。
相關文章
相關標籤/搜索