memcache和redis 你更鐘情于誰

一.memcache和redis的相同點:

1.都是 key-value 形式的內(nèi)存數(shù)據(jù)庫

2.都是NoSQL家族的數(shù)據(jù)管理解決方案

3.都基于同樣的key-value 數(shù)據(jù)模型

4.所有數(shù)據(jù)全部放在內(nèi)存中(這也是適用于緩存的原因)

5.性能得分不分伯仲,包括數(shù)據(jù)吞吐量和延遲等指標

6.都是成熟的棘脐、廣受開源項目歡迎的 key-value存儲系統(tǒng)

二.更適合memcached的場景:

第一種是很細碎的靜態(tài)數(shù)據(jù),如HTML代碼片段。 Memcached的內(nèi)存管理不像Redis那么復(fù)雜,所以性能更高一些,原因是Memcached 的元數(shù)據(jù)metadata更小,相對來說額外開銷就很少某残。 Memcached唯一支持的數(shù)據(jù)類型是字符串String,非常適合緩存只讀數(shù)據(jù),因為字符串不需要額外的處理圾亏。

第二個場景,是Memcached比Redis更容易水平擴展艰躺。 原因在于它的設(shè)計和和功能很簡單,Memcached更容易擴展。

數(shù)據(jù)訪問流向

三.redis相較memcached的優(yōu)勢:

1 Redis不僅僅支持簡單的k/v類型的數(shù)據(jù),同時還提供list炒事,set难礼,zset娃圆,hash等數(shù)據(jù)結(jié)構(gòu)的存儲。

2 Redis支持數(shù)據(jù)的備份蛾茉,即master-slave模式的數(shù)據(jù)備份讼呢。

3 Redis支持數(shù)據(jù)的持久化,可以將內(nèi)存中的數(shù)據(jù)保持在磁盤中谦炬,重啟的時候可以再次加載進行使用悦屏。

四.memcached相較redis的優(yōu)勢:

1) 分布式 。

2)相對應(yīng)用服務(wù)器的內(nèi)存而言键思,可以進行單點訪問础爬。

3)性能強

五.memchached和redis的內(nèi)存管理機制:

memchached:

Memcached默認使用Slab Allocation機制管理內(nèi)存,其主要思想是按照預(yù)先規(guī)定的大小吼鳞,將分配的內(nèi)存分割成特定長度的塊以存儲相應(yīng)長度的key-value數(shù)據(jù)記錄看蚜,以完全解決內(nèi)存碎片問題。Slab Allocation機制只為存儲外部數(shù)據(jù)而設(shè)計赔桌,也就是說所有的key-value數(shù)據(jù)都存儲在Slab Allocation系統(tǒng)里供炎,而Memcached的其它內(nèi)存請求則通過普通的malloc/free來申請渴逻,因為這些請求的數(shù)量和頻率決定了它們不會對整個系統(tǒng)的性能造成影響。

Slab Allocation的原理相當簡單:

它首先從操作系統(tǒng)申請一大塊內(nèi)存音诫,并將其分割成各種尺寸的塊Chunk裸卫,并把尺寸相同的塊分成組Slab Class。其中纽竣,Chunk就是用來存儲key-value數(shù)據(jù)的最小單位墓贿。每個Slab Class的大小,可以在Memcached啟動的時候通過制定Growth Factor來控制蜓氨。假定Figure 1中Growth Factor的取值為1.25聋袋,所以如果第一組Chunk的大小為88個字節(jié),第二組Chunk的大小就為112個字節(jié)穴吹,依此類推幽勒。

內(nèi)存管理機制

當Memcached接收到客戶端發(fā)送過來的數(shù)據(jù)時首先會根據(jù)收到數(shù)據(jù)的大小選擇一個最合適的Slab Class,然后通過查詢Memcached保存著的該Slab Class內(nèi)空閑Chunk的列表就可以找到一個可用于存儲數(shù)據(jù)的Chunk港令。當一條數(shù)據(jù)庫過期或者丟棄時啥容,該記錄所占用的Chunk就可以回收,重新添加到空閑列表中顷霹。

從以上過程我們可以看出Memcached的內(nèi)存管理制效率高咪惠,而且不會造成內(nèi)存碎片,但是它最大的缺點就是會導(dǎo)致空間浪費淋淀。因為每個 Chunk都分配了特定長度的內(nèi)存空間遥昧,所以變長數(shù)據(jù)無法充分利用這些空間。如下圖所示朵纷,將100個字節(jié)的數(shù)據(jù)緩存到112個字節(jié)的Chunk中炭臭,剩余的12個字節(jié)就浪費掉了。

Redis的內(nèi)存管理機制:

Redis的內(nèi)存管理主要通過源碼中zmalloc.h和zmalloc.c兩個文件來實現(xiàn)的袍辞。

內(nèi)存的管理

Redis為了方便內(nèi)存的管理鞋仍,在分配一塊內(nèi)存之后,會將這塊內(nèi)存的大小存入內(nèi)存塊的頭部搅吁。real_ptr是redis調(diào)用malloc后返回的指針威创。redis將內(nèi)存塊的大小size存入頭部,size所占據(jù)的內(nèi)存大小是已知的似芝,為 size_t類型的長度那婉,然后返回ret_ptr板甘。當需要釋放內(nèi)存的時候党瓮,ret_ptr被傳給內(nèi)存管理程序。通過ret_ptr盐类,程序可以很容易的算出 real_ptr的值寞奸,然后將real_ptr傳給free釋放內(nèi)存呛谜。

Redis通過定義一個數(shù)組來記錄所有的內(nèi)存分配情況,這個數(shù)組的長度為ZMALLOC_MAX_ALLOC_STAT枪萄。數(shù)組的每一個元素代表當前程序所分配的內(nèi)存塊的個數(shù)隐岛,且內(nèi)存塊的大小為該元素的下標。在源碼中瓷翻,這個數(shù)組為zmalloc_allocations聚凹。 zmalloc_allocations[16]代表已經(jīng)分配的長度為16bytes的內(nèi)存塊的個數(shù)。zmalloc.c中有一個靜態(tài)變量 used_memory用來記錄當前分配的內(nèi)存總大小齐帚。所以妒牙,總的來看,Redis采用的是包裝的malloc/free对妄,相較于Memcached的內(nèi)存管理方法來說湘今,要簡單很多。

六.Redis和Memcached的集群實現(xiàn)機制:

1.Memcached的分布式存儲

Memcached本身并不支持分布式剪菱,因此只能在客戶端通過像一致性哈希這樣的分布式算法來實現(xiàn)Memcached的分布式存儲摩瞎。

Memcached的分布式存儲實現(xiàn)架構(gòu)

下圖給出了。當客戶端向Memcached集群發(fā)送數(shù)據(jù)之前孝常,首先會通過內(nèi)置的分布式算法計算出該條數(shù)據(jù)的目標節(jié)點旗们,然后數(shù)據(jù)會直接發(fā)送到該節(jié)點上存儲。但客戶端查詢數(shù)據(jù)時构灸,同樣要計算出查詢數(shù)據(jù)所在的節(jié)點蚪拦,然后直接向該節(jié)點發(fā)送查詢請求以獲取數(shù)據(jù)冻押。

2)Redis的分布式存儲

相較于Memcached只能采用客戶端實現(xiàn)分布式存儲,Redis更偏向于在服務(wù)器端構(gòu)建分布式存儲洛巢。

A.Redis Cluster介紹:

Redis Cluster是一個實現(xiàn)了分布式且允許單點故障的Redis高級版本,它沒有中心節(jié)點稿茉,具有線性可伸縮的功能。

Redis Cluster的分布式存儲架構(gòu)

節(jié)點與節(jié)點之間通過二進制協(xié)議進行通信漓库,節(jié)點與客戶端之間通過ascii協(xié)議進行通信。在數(shù)據(jù)的放置策略上渺蒿,Redis Cluster將整個key的數(shù)值域分成4096個哈希槽,每個節(jié)點上可以存儲一個或多個哈希槽茂装,也就是說當前Redis Cluster支持的最大節(jié)點數(shù)就是4096善延。Redis Cluster使用的分布式算法也很簡單:crc16( key ) % HASH_SLOTS_NUMBER。

B.redis主從節(jié)點:

redis主從節(jié)點

每個Master節(jié)點都會有對應(yīng)的兩個用于冗余的Slave節(jié)點城侧。這樣在整個集群中易遣,任意兩個節(jié)點的宕機都不會導(dǎo)致數(shù)據(jù)的不可用。當Master節(jié)點退出后嫌佑,集群會自動選擇一個Slave節(jié)點成為新的Master節(jié)點豆茫。

七.數(shù)據(jù)持久化

1.memcached是不支持數(shù)據(jù)持久化,數(shù)據(jù)被放在內(nèi)存中,一旦關(guān)閉或者其他原因服務(wù)掛點,數(shù)據(jù)會丟失.

2.redis支持持久化

Redis雖然是基于內(nèi)存的存儲系統(tǒng),但是它本身是支持內(nèi)存數(shù)據(jù)的持久化的屋摇,而且提供兩種主要的持久化策略:RDB快照和AOF日志澜薄。我們會在下文分別介紹這兩種不同的持久化策略。

2.1 Redis?的快照

Redis支持將當前數(shù)據(jù)的快照存成一個數(shù)據(jù)文件的持久化機制摊册,即RDB快照肤京。Redis借助了fork命令的copy on write機制。在生成快照時茅特,將當前進程fork出一個子進程忘分,然后在子進程中循環(huán)所有的數(shù)據(jù),將數(shù)據(jù)寫成為RDB文件白修。

可以通過Redis的save指令來配置RDB快照生成的時機妒峦,比如可以配置當10分鐘以內(nèi)有100次寫入就生成快照,也可以配置當1小時內(nèi)有 1000次寫入就生成快照兵睛,也可以多個規(guī)則一起實施肯骇。這些規(guī)則的定義就在Redis的配置文件中,也可以通過Redis的CONFIG SET命令在Redis運行時設(shè)置規(guī)則祖很,不需要重啟Redis笛丙。

Redis的RDB文件不會壞掉,因為其寫操作是在一個新進程中進行的假颇,當生成一個新的RDB文件時胚鸯,Redis生成的子進程會先將數(shù)據(jù)寫到一個臨時文件中,然后通過原子性rename系統(tǒng)調(diào)用將臨時文件重命名為RDB文件笨鸡,這樣在任何時候出現(xiàn)故障姜钳,Redis的RDB文件都總是可用的。同時形耗,Redis 的RDB文件也是Redis主從同步內(nèi)部實現(xiàn)中的一環(huán)哥桥。

但可以很明顯的看到,RDB有它的不足激涤,就是一旦數(shù)據(jù)庫出現(xiàn)問題拟糕,那么RDB文件中保存的數(shù)據(jù)并不是全新的從上次RDB文件生成到 Redis停機這段時間的數(shù)據(jù)全部丟掉了

在某些業(yè)務(wù)下已卸,這是可以忍受的,我們也推薦這些業(yè)務(wù)使用RDB的方式進行持久化硼一,因為開啟RDB的代價并不高累澡。?

但是對于另外一些對數(shù)據(jù)安全性要求極高的應(yīng)用般贼,無法容忍數(shù)據(jù)丟失的應(yīng)用哼蛆,RDB就無能為力了,所以Redis引入了另一個重要的持久化機制:AOF日志肥矢。

2.2 Redis?的AOF日志

AOF日志的全稱是append only file甘改,從名字上就能看出來灭抑,它是一個追加寫入的日志文件。

與一般數(shù)據(jù)庫的binlog不同的是忘嫉,AOF文件是可識別的純文本庆冕,它的內(nèi)容就是一個個 的Redis標準命令劈榨。當然鞋既,并不是發(fā)送發(fā)Redis的所有命令都要記錄到AOF日志里面,只有那些會導(dǎo)致數(shù)據(jù)發(fā)生修改的命令才會追加到AOF文件跌前。

那么每一條修改數(shù)據(jù)的命令都生成一條日志陡舅,那么AOF文件是不是會很大?答案是肯定的

AOF文件會越來越大茎芋,所以Redis又提供了一個功能蜈出,叫做AOF rewrite铡原。其功能就是重新生成一份AOF文件,新的AOF文件中一條記錄的操作只會有一次只泼,而不像一份老文件那樣请唱,可能記錄了對同一個值的多次操作过蹂。其生成過程和RDB類似,也是fork一個進程孽惰,直接遍歷數(shù)據(jù),寫入新的AOF臨時文件勋功。在寫入新文件的過程中库说,所有的寫操作日志還是會寫到原來老的 AOF文件中潜的,同時還會記錄在內(nèi)存緩沖區(qū)中。當重完操作完成后信不,會將所有緩沖區(qū)中的日志一次性寫入到臨時文件中抽活。然后調(diào)用原子性的rename命令用新的 AOF文件取代老的AOF文件锰什。

AOF是一個寫文件操作丁逝,其目的是將操作日志寫到磁盤上霜幼,所以它也同樣會遇到寫操作的5個流程罪既。

寫操作的流程:

1)客戶端向服務(wù)端發(fā)送寫操作(數(shù)據(jù)在客戶端的內(nèi)存中)

2)數(shù)據(jù)庫服務(wù)端接收到寫請求的數(shù)據(jù)(數(shù)據(jù)在服務(wù)端的內(nèi)存中)

3)服務(wù)端調(diào)用write(2) 這個系統(tǒng)調(diào)用萝衩,將數(shù)據(jù)往磁盤上寫(數(shù)據(jù)在系統(tǒng)內(nèi)存的緩沖區(qū)中)

4)操作系統(tǒng)將緩沖區(qū)中的數(shù)據(jù)轉(zhuǎn)移到磁盤控制器上(數(shù)據(jù)在磁盤緩存中)

5)磁盤控制器將數(shù)據(jù)寫到磁盤的物理介質(zhì)中(數(shù)據(jù)真正落到磁盤上)

那么寫AOF的操作安全性又有多高呢没咙。實際上 這是可以設(shè)置的祭刚,在Redis中對AOF調(diào)用write(2)寫入后墙牌,何時再調(diào)用fsync將其寫到磁盤上,通過appendfsync選項來控制捉捅,下面 appendfsync的三個設(shè)置項棒口,安全強度逐漸變強辜膝。

1)appendfsync no

當設(shè)置appendfsync為no的時候,Redis不會主動調(diào)用fsync去將AOF日志內(nèi)容同步到磁盤茎毁,所以這一切就完全依賴于操作系統(tǒng)的調(diào)試了七蜘。對大多數(shù)Linux操作系統(tǒng)墙懂,是每30秒進行一次fsync垒在,將緩沖區(qū)中的數(shù)據(jù)寫到磁盤上扔亥。

2)appendfsync everysec

當設(shè)置appendfsync為everysec的時候旅挤,Redis會默認每隔一秒進行一次fsync調(diào)用粘茄,將緩沖區(qū)中的數(shù)據(jù)寫到磁盤秕脓。但是當這一次的 fsync調(diào)用時長超過1秒時。Redis會采取延遲fsync的策略芙贫,再等一秒鐘磺平。也就是在兩秒后再進行fsync拐辽,這一次的fsync就不管會執(zhí)行多 長時間都會進行俱诸。這時候由于在fsync時文件描述符會被阻塞,所以當前的寫操作就會阻塞赶诊。所以結(jié)論就是甫何,在絕大多數(shù)情況下遇伞,Redis會每隔一秒進行一 次fsync。在最壞的情況下巍耗,兩秒鐘會進行一次fsync操作炬太。這一操作在大多數(shù)數(shù)據(jù)庫系統(tǒng)中被稱為group commit驯耻,就是組合多次寫操作的數(shù)據(jù),一次性將日志寫到磁盤霎迫。

3)appednfsync always

當設(shè)置appendfsync為always時,每一次寫操作都會調(diào)用一次fsync瓤帚,這時數(shù)據(jù)是最安全的戈次,當然筒扒,由于每次都會執(zhí)行fsync霎肯,所以其性能也會受到影響榛斯。

八.Redis和Memcached整體對比

1)性能對比:由于Redis只使用單核驮俗,而Memcached可以使用多核,所以平均每一個核上Redis在存儲小數(shù)據(jù)時比Memcached性能更高搪柑。而在100k以上的數(shù)據(jù)中工碾,Memcached性能要高于Redis百姓,雖然Redis最近也在存儲大數(shù)據(jù)的性能上進行優(yōu)化,但是比起 Memcached旬迹,還是稍有遜色奔垦。

2)內(nèi)存使用效率對比:使用簡單的key-value存儲的話尸疆,Memcached的內(nèi)存利用率更高,而如果Redis采用hash結(jié)構(gòu)來做key-value存儲犯眠,由于其組合式的壓縮,其內(nèi)存利用率會高于Memcached兆衅。redis不僅僅有key-value存儲結(jié)構(gòu),也有其他的存儲結(jié)構(gòu).

3)Redis支持服務(wù)器端的數(shù)據(jù)操作:Redis相比Memcached來說羡亩,擁有更多的數(shù)據(jù)結(jié)構(gòu)和并支持更豐富的數(shù)據(jù)操作危融,通常在Memcached 里吉殃,你需要將數(shù)據(jù)拿到客戶端來進行類似的修改再set回去。這大大增加了網(wǎng)絡(luò)IO的次數(shù)和數(shù)據(jù)體積瓦灶。在Redis中贼陶,這些復(fù)雜的操作通常和一般的 GET/SET一樣高效。所以碉怔,如果需要緩存能夠支持更復(fù)雜的結(jié)構(gòu)和操作禁添,那么Redis會是不錯的選擇老翘。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市叁征,隨后出現(xiàn)的幾起案子捺疼,更是在濱河造成了極大的恐慌永罚,老刑警劉巖卧秘,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件翅敌,死亡現(xiàn)場離奇詭異蚯涮,居然都是意外死亡卖陵,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門棒旗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來铣揉,“玉大人餐曹,你說我怎么就攤上這事凸主《钕妫” “怎么了锋华?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長衍腥。 經(jīng)常有香客問我婆咸,道長芜辕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任倔丈,我火速辦了婚禮,結(jié)果婚禮上鹉动,老公的妹妹穿的比我還像新娘宏邮。我一直安慰自己蜜氨,他們只是感情好,可當我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布变姨。 她就那樣靜靜地躺著定欧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪砍鸠。 梳的紋絲不亂的頭發(fā)上爷辱,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天饭弓,我揣著相機與錄音,去河邊找鬼弟断。 笑死阀趴,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的刘急。 我是一名探鬼主播叔汁,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼攻柠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了冒滩?” 一聲冷哼從身側(cè)響起开睡,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤篇恒,失蹤者是張志新(化名)和其女友劉穎胁艰,沒想到半個月后智蝠,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡解虱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了悍汛。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抹恳。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡奋献,死狀恐怖瓶蚂,靈堂內(nèi)的尸體忽然破棺而出宣吱,到底是詐尸還是另有隱情,我是刑警寧澤杭攻,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站馆铁,受9級特大地震影響埠巨,放射性物質(zhì)發(fā)生泄漏现拒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望侥猬。 院中可真熱鬧陵究,春花似錦铜邮、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽玖瘸。三九已至,卻和暖如春檀咙,著一層夾襖步出監(jiān)牢的瞬間雅倒,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工弧可, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蔑匣,地道東北人。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像裁良,于是被迫代替她去往敵國和親凿将。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 一价脾、Redis高可用概述 在介紹Redis高可用之前牧抵,先說明一下在Redis的語境中高可用的含義。 我們知道彼棍,在w...
    空語閱讀 1,597評論 0 2
  • Redis雜談 Redis是近年來發(fā)展迅速的內(nèi)存數(shù)據(jù)庫灭忠,網(wǎng)上也已經(jīng)有多Redis的文章。但不管是英文還是中文映琳,多數(shù)...
    迷失于重逢閱讀 1,556評論 0 14
  • 文/其樂龍融 蒼穹與大地不屬于我 俯仰間有我的眼神 紅日與新月不屬于我 輪回里有我的期待 清風與雨露不屬于我 我有...
    其樂龍融閱讀 185評論 3 5