Memcached 及 Redis 架構分析和比較
Memcached和Redis作為兩種Inmemory的key-value資料庫,在設計和思想方面有著很多共通的地方,功能和應用方面在很多場合下(作為分散式快取伺服器使用等) 也很相似,在這裡把兩者放在一起做一下對比的介紹
基本架構和思想
首先簡單介紹一下兩者的架構和設計思路
Memcached
Memcached採用客戶端-伺服器的架構,客戶端和伺服器端的通訊使用自定義的協議標準,只要滿足協議格式要求,客戶端Library可以用任何語言實現。
從使用者的角度來說,伺服器維護了一個鍵-值關係的資料表,伺服器之間相互獨立,互相之間不共享資料也不做任何通訊操作。客戶端需要知道所有的伺服器,並自行負責管理資料在各個伺服器間的分配。
在伺服器端,內部的資料儲存,使用基於Slab的記憶體管理方式,有利於減少記憶體碎片和頻繁分配銷燬記憶體所帶來的開銷。各個Slab按需動態分配一個page的記憶體(和4Kpage的概念不同,這裡預設page為1M),page內部按照不同slab class的尺寸再劃分為記憶體chunk供伺服器儲存KV鍵值對使用
Memcached的基本應用模型如下圖所示
Redis
Redis的基本應用模式和上圖memcached的基本相似,不難發現網上到處都是關於redis是否可以完全替代memcached使用的問題
Redis內部的資料結構最終也會落實到key-Value對應的形式,不過從暴露給使用者的資料結構來看,要比memcached豐富,除了標準的通常意義的鍵值對,Redis還支援List,Set, Hashes,Sorted Set等資料結構
基本命令
Memcached的命令或者說通訊協議非常簡單,Server所支援的命令基本就是對特定key的新增,刪除,替換,原子更新,讀取等,具體包括 Set, Get, Add, Replace, Append, Inc/Dec 等等
Memcached的通訊協議包括文字格式和二進位制格式,用於滿足簡單網路客戶端工具(如telnet)和對效能要求更高的客戶端的不同需求
Redis的命令在KV(String型別)上提供與Memcached類似的基本操作,在其它資料結構上也支援基本類似的操作(當然還有這些資料結構所特有的操作,如Set的union,List的pop等)而支援更多的資料結構,在一定程度上也就意味著更加廣泛的應用場合
除了多種資料結構的支援,Redis相比Memcached還提供了許多額外的特性,比如Subscribe/publish命令,以支援釋出/訂閱模式這樣的通知機制等等,這些額外的特性同樣有助於擴充它的應用場景
Redis的客戶端-伺服器通訊協議完全採用文字格式(在將來可能的伺服器間通訊會採用二進位制格式)
事務
redis通過Multi / Watch /Exec等命令可以支援事務的概念,原子性的執行一批命令。在2.6以後的版本中由於新增了對Script指令碼的支援,而指令碼固有的是以transaction事務的方式執行的,並且更加易於使用,所以不排除將來取消Multi等命令介面的可能性
Memcached的應用模式中,除了increment/decrement這樣的原子操作命令,不存在對事務的支援
資料備份,有效性,持久化等
memcached不保證儲存的資料的有效性,Slab內部基於LRU也會自動淘汰舊資料,客戶端不能假設資料在伺服器端的當前狀態,這應該說是Memcached的Feature設定,使用者不必太多關心或者自己管理資料的淘汰更新工作,當然是否適合你的應用,取決於具體的需求,它也可能成為你需要精確自行控制Cache生命週期的一個障礙
Memcached也不做資料的持久化工作,但是有許多基於memcached協議的專案實現了資料的持久化,例如memcacheDB使用BerkeleyDB進行資料儲存,但本質上它已經不是一個Cache Server,而只是一個相容Memcached的協議key-valueData Store了
Redis可以以master-slave的方式配置伺服器,Slave節點對資料進行replica備份,Slave節點也可以充當Read only的節點分擔資料讀取的工作
Redis內建支援兩種持久化方案,snapshot快照和AOF 增量Log方式。快照顧名思義就是隔一段時間將完整的資料Dump下來儲存在檔案中。AOF增量Log則是記錄對資料的修改操作(實際上記錄的就是每個對資料產生修改的命令本身),兩種方案可以並存,也各有優缺點,具體參見http://redis.io/topics/persistence
以上Redis的資料備份持久化方案等,如果不需要,為了提高效能,也完全可以Disable
效能
效能方面,兩者都有一些自己考慮和實現
Memcached
memcached自身並不主動定期檢查和標記哪些資料需要被淘汰,只有當再次讀取相關資料時才檢查時間戳,或者當記憶體不夠使用需要主動淘汰資料時進一步檢查LRU資料
Redis
Redis為了減少大量小資料CMD操作的網路通訊時間開銷 RTT (Round Trip Time),支援pipeline和script技術
- 所謂的pipeline就是支援在一次通訊中,傳送多個命令給伺服器批量執行,帶來的代價是伺服器端需要更多的記憶體來快取查詢結果。
- Redis內嵌了LUA解析器,可以執行lua 指令碼,指令碼可以通過eval等命令直接執行,也可以使用script load等方式上傳到伺服器端的script cache中重複使用
這兩種方式都可以有效地減少網路通訊開銷,增加資料吞吐率
對於KV的操作,Memcached和Redis都支援Multiple的Get和Set命令(Memcached的Multiple Set命令貌似只在二進位制的協議中支援),這同樣有利於效能的提升
實際效能方面,網上有很多測試比較,給出的結果各不相同,這無疑和各種測試的測試用例,測試環境,和測試時具體使用的客戶端Library實現有關。但是總體看下來,比較靠譜的結論是在kv類操作上,兩者的效能接近,Memcached的結構更加簡單,理論上應該會略微快一些。
叢集
memcached的伺服器端互相完全獨立,客戶端通常通過對鍵值應用Hash演算法決定資料的分割槽,為了減少伺服器的增減對Hash結果的影響,導致大面積的快取失效,多數客戶端實現了一致性hash演算法
Redis計劃在伺服器端內建對叢集的支援,但是目前程式碼還處於alpha階段(貌似已經Design了兩三年了?)在此之前,同樣可以認為每個Redis伺服器例項相互之間是完全獨立的,需要依靠客戶端處理分割槽演算法和可用伺服器列表管理的工作。
Redis官方推薦的用於Sharding的客戶端程式庫是Twitter的開源專案 Twemproxy, Twemproxy同時支援Memcached和Redis的文字通訊協議。
需要注意的是,Redis的許多命令在叢集環境下是不能正確執行的,例如set的交集,以及跨節點的事務操作等等,因為目前的Redis叢集設計,根本目標也就是伺服器之間互相彙報一下存活狀態,以及對資料做榮譽備份平衡負載等而已,本質上對資料的跨節點操作並不提供任何額外支援,所以在資料服務的層面上來說,各個伺服器依舊是完全獨立的。
這些操作如果一定要實現,當然可以通過客戶端程式碼來實現(效率有多高且不說),類似的問題memcached叢集當然也會遇上,但是原本memcached就不支援複雜的操作和資料型別,許多運算邏輯原本就是由客戶端程式碼或應用程式自己處理的。
MR類批處理應用
提供指定範圍的遍歷操作,是支援類似MapReduce這樣的批處理應用邏輯的關鍵之一,但是要在基於hash方式儲存的資料結構的基礎上提供這樣的支援並不容易(或者說要實現高效的範圍或遍歷操作並不容易)
Redis支援Scan操作用於遍歷資料集,這一操作基於其內部資料結構及實現的限制,可以保證在Scan開始時的所有資料都能被獲取到,但是不能保證不返回重複的資料,這需要由客戶端來檢查,或者客戶端對此無所謂。Scan操作還支援Match條件用來過濾鍵值,雖然存在一定的侷限性,例如match條件的比較是在獲取資料之後再執行的,效率是一個問題,更明顯的問題是不能保證每次scan的iterate過程都能返回同樣數量的有效資料。
對於範圍操作,Redis的Ordered Set支援在插入時指定資料的分數(Score)用於排序,而後支援在指定Score範圍內的各種操作,雖然由於不支援基於字串的或自定義的基準的Range操作,這樣的範圍操作應用起來有很大的侷限性(或者說需要滿足特定的應用模式),但是還是比沒有好了
Memcached核心協議本身不支援任何範圍類的操作,也沒有對遍歷操作的支援,甚至不存在官方合法的列舉所有Key的操作,這當然很大程度上源於其設計思想和精簡的架構
不過還是有一些相容memcached協議的伺服器實現了範圍類操作,具體格式可以參考 https://code.google.com/p/memcached/wiki/RangeOps 所建議的標準
此外Redis的Hashes資料結構,在一定程度上可以滿足獲取特定子集資料的應用邏輯需求。
綜上來說,如果要實現類似HBase支援的scan操作,不論是Redis還是memcached都無法做到,但是對於Redis來說,能否用於批處理類應用,不能一概而論,取決於具體的資料的格式邏輯和使用方式。通過適當的調整應用程式使用資料的方式,還是有可能在一定程度上實現對MR類批處理,或範圍查詢類應用邏輯的支援的。而對於鍵值分佈在一個較大的連續空間,數量不確定,同時又無法很好的對映為數值進而使用ordered set來處理的這樣一些資料結構,應該還是很難高效的分割槽遍歷的
轉載:http://blog.csdn.net/colorant/article/details/21089057
相關文章
- Redis 和 Memcached 比較Redis
- PostgreSQL、Redis與Memcached的效能比較 - CYBERTECSQLRedis
- Transformer和MoE架構比較ORM架構
- memcached 和 redis 使用場景及優缺點對比Redis
- etcd和redis比較Redis
- 全面對比 Redis 和 Memcached 的 6 點區別Redis
- 對比Memcached和Redis,誰才是適合你的快取?Redis快取
- Memcached和Redis的區別?Redis
- Redis的配置及與memcached區別Redis
- redis學習(九) redis事務和redis指令碼的比較Redis指令碼
- Hybris service layer和SAP CRM WebClient UI架構的橫向比較WebclientUI架構
- 大前端技術選型總結和一些架構比較前端架構
- Redis vs. MongoDB比較RedisMongoDB
- 比較 Pandas、Polars 和 PySpark:基準分析Spark
- 好好耕耘redis和memcached的區別Redis
- js 深比較和淺比較JS
- Nosql/Redis/ttserver/Flare/memcache比較SQLRedisTTSServer
- tomcat架構分析及配置詳解Tomcat架構
- Web3架構與傳統Web的比較 - thenewstackWeb架構
- 精講Redis服務架構分析與搭建Redis架構
- Oracle date 型別比較和String比較Oracle型別
- 細說紛紜——Redis 和 Memcached 的區別Redis
- 訊息中介軟體部署及比較:rabbitMQ、activeMQ、zeroMQ、rocketMQ、Kafka、redisMQKafkaRedis
- 資深架構師談Redis高可用架構的應用及改進架構Redis
- 資料管理架構:單體資料架構與分散式資料網格比較 - enyo架構分散式
- not in 和 not exists 比較和用法
- 【架構分析】MESA (EGL/GLES)架構分析架構
- 【原創】InnoDB 和TokuDB的讀寫分析與比較
- Lock的獨佔鎖和共享鎖的比較分析
- TCP和UDP比較TCPUDP
- Java和JavaSciprt比較Java
- Redis基礎篇(五)AOF與RDB比較和選擇策略Redis
- Go和Python比較的話,哪個比較好?GoPython
- NUMA架構介紹及優缺點分析架構
- SaaS架構:流程架構分析架構
- 譯文 | 科普:Pulsar 和 Kafka 架構對比Kafka架構
- 阿里P8架構師談:NoSQL和SQL的區別,NoSQL的使用場景和選型比較阿里架構SQL
- 比較器-Comparable和Comparator
- ImageMagic 和 GraphicsMagick 的比較