Redis與Memcached區(qū)別:
兩者都是非關(guān)系型數(shù)據(jù)庫(kù)终畅。主要有以下不同:
數(shù)據(jù)類型:
- Memcached僅支持字符串類型亡容。
- redis支持:String,List,set,zset,hash 可以靈活的解決問(wèn)題讼稚。
數(shù)據(jù)持久化:
- Memcached不支持持久化。
- Redis采用兩種持久化策略:RDB快照和AOF日志。
分布式:
- Mencached不支持分布式扒寄,只能在客戶端使用一致性hash來(lái)實(shí)現(xiàn)分布式存儲(chǔ),這種方式在存儲(chǔ)和查詢時(shí)都需要在客戶端先計(jì)算一次數(shù)據(jù)所在的節(jié)點(diǎn)拟烫。
- redis cluster實(shí)現(xiàn)了分布式的支持该编。
內(nèi)存管理機(jī)制:
- redis中,并不是所有數(shù)據(jù)都一直存儲(chǔ)在內(nèi)存中硕淑,可以將一些很久沒(méi)用的value交換到磁盤课竣,而memcached數(shù)據(jù)則候會(huì)一直在內(nèi)存中。
- memcached將內(nèi)存分割成特定的塊進(jìn)行存儲(chǔ)置媳,以完全解決內(nèi)存碎片化的問(wèn)題于樟,但是這種方式使得內(nèi)存利用率不高,如塊大小128bytes拇囊,只存儲(chǔ)了100bytes的數(shù)據(jù)迂曲,那么剩下的28bytes就浪費(fèi)掉了。
鍵的過(guò)期時(shí)間:
redis可以為每個(gè)鍵設(shè)置過(guò)期時(shí)間寥袭,當(dāng)鍵過(guò)期時(shí)路捧,自動(dòng)刪除該鍵。
對(duì)于散列表這種容器传黄,只能為整個(gè)鍵設(shè)置過(guò)期時(shí)間(整個(gè)散列表)杰扫,而不是為鍵里面的單個(gè)元素設(shè)置過(guò)期時(shí)間。
設(shè)置鍵的生存時(shí)間:
- expire: 指定秒
- pexpire: 指定毫秒
127.0.0.1:6379> set key hello
OK
127.0.0.1:6379> expire key 1
(integer) 1
127.0.0.1:6379> get key
(nil)
127.0.0.1:6379> hset hashkey key1 1
(integer) 0
127.0.0.1:6379> hget hashkey key1
"1"
127.0.0.1:6379> expire hashkey 1
(integer) 1
127.0.0.1:6379> hget hashkey key1
(nil)
127.0.0.1:6379> zadd zset 0 key1 1 key2
(integer) 0
127.0.0.1:6379> zrange zset 0 -1
1) "key1"
2) "key3"
3) "key2"
127.0.0.1:6379> expire zset 1
(integer) 1
127.0.0.1:6379> zrange zset 0 -1
(empty list or set)
設(shè)置過(guò)期時(shí)間:過(guò)期時(shí)間是一個(gè)unix時(shí)間戳
- expireat:秒精度
- pexpireat:毫秒精度
過(guò)期鍵的刪除策略:
定時(shí)刪除:
在設(shè)置鍵的過(guò)期時(shí)間的同時(shí)膘掰,創(chuàng)建一個(gè)定時(shí)器章姓,讓定時(shí)器在鍵過(guò)期時(shí)間來(lái)臨時(shí),立即執(zhí)行對(duì)鍵的刪除操作炭序。
- [ ] 優(yōu)點(diǎn):對(duì)內(nèi)存是友好的啤覆,可以保證過(guò)期鍵會(huì)盡可能快被刪除,并釋放過(guò)期鍵所占用的內(nèi)存惭聂。
- [ ] 缺點(diǎn):對(duì)CPU不友好,在過(guò)期鍵較多的情況下相恃,刪除鍵的操作會(huì)占用相當(dāng)一部分的CPU時(shí)間辜纲,在內(nèi)存不緊張但CPU緊張的情況下,將cpu時(shí)間用在刪除與當(dāng)前任務(wù)無(wú)關(guān)的過(guò)期鍵上拦耐,無(wú)疑會(huì)對(duì)服務(wù)器的響應(yīng)時(shí)間和吞吐量造成影響耕腾。
此外,定時(shí)器需要使用redis服務(wù)器的時(shí)間事件杀糯,時(shí)間事件的實(shí)現(xiàn)方式為無(wú)序鏈表扫俺,查找一個(gè)事件的事件復(fù)雜度為O(N),因此創(chuàng)建大量的定時(shí)器不現(xiàn)實(shí)固翰。
惰性刪除:
僅在程序取出鍵時(shí)才進(jìn)行過(guò)期檢查
- [ ] 優(yōu)點(diǎn): CPU友好狼纬,不會(huì)花費(fèi)額外的時(shí)間羹呵。
- [ ] 缺點(diǎn):對(duì)內(nèi)存不友好,會(huì)造成內(nèi)存泄漏疗琉。
定期刪除:
每隔一段時(shí)間執(zhí)行一次刪除過(guò)期鍵操作冈欢,并通過(guò)限制刪除操作執(zhí)行的時(shí)長(zhǎng)和頻率來(lái)減少對(duì)CPU時(shí)間的影響。
數(shù)據(jù)淘汰策略:6種
可以設(shè)置內(nèi)存最大使用量盈简,當(dāng)內(nèi)存使用超出時(shí)凑耻,施行數(shù)據(jù)淘汰策略。
作為內(nèi)存數(shù)據(jù)庫(kù)柠贤,出于對(duì)性能和內(nèi)存消耗的考慮香浩,redis的淘汰算法實(shí)際上并未針對(duì)所有key,而是抽樣一小部分并且從中選出被淘汰的key臼勉。
使用reids緩存數(shù)據(jù)時(shí)弃衍,為提高緩存命中率,需要保證緩存都是熱點(diǎn)數(shù)據(jù)坚俗【刀ⅲ可以將內(nèi)存最大使用量設(shè)置為熱點(diǎn)數(shù)據(jù)占用的內(nèi)存量,然后啟用allkeys-lru淘汰策略猖败,將最近最少未使用的數(shù)據(jù)進(jìn)行淘汰速缆。
redis4.0 版本后引入了volatile-lfu和allkeys-lfu淘汰策略,LFU策略通過(guò)統(tǒng)計(jì)訪問(wèn)頻率恩闻,將訪問(wèn)頻率最小的鍵值進(jìn)行淘汰艺糜。
持久化:
redis是內(nèi)存型數(shù)據(jù)庫(kù),為了保證數(shù)據(jù)在斷電后不會(huì)丟失幢尚,需要將內(nèi)存中的數(shù)據(jù)持久化到硬盤上破停。
RDB持久化:
- 將某個(gè)時(shí)間點(diǎn)的所有數(shù)據(jù)都存放到硬盤上。
- 可以將快照復(fù)制到其他服務(wù)器從而創(chuàng)建具有相同數(shù)據(jù)的服務(wù)器副本尉剩。
- 如果系統(tǒng)方法故障真慢,將會(huì)丟失最后一次快照后的數(shù)據(jù)。
- 如果數(shù)據(jù)量很大理茎,保存快照時(shí)間會(huì)很長(zhǎng)黑界。
手動(dòng)觸發(fā):
- [ ] redis命令
- save:生成RDB文件,會(huì)阻塞服務(wù)器進(jìn)程皂林,知直到RDB文件創(chuàng)建完畢朗鸠。
- bgsave: 派生(fork)一個(gè)子進(jìn)程,然后由子進(jìn)程負(fù)責(zé)創(chuàng)建RDB文件础倍,父進(jìn)程繼續(xù)處理命令請(qǐng)求烛占。
自動(dòng)觸發(fā):
- 使用save相關(guān)配置,如“save m n”沟启。表示m秒中對(duì)數(shù)據(jù)集進(jìn)行n次修改忆家,就觸發(fā)bgsave犹菇。
- 如果從節(jié)點(diǎn)執(zhí)行全量復(fù)制操作,主節(jié)點(diǎn)自動(dòng)執(zhí)行bgsave生成RDB文件發(fā)送給從文件弦赖。
- 執(zhí)行debug reload 命令重新加載redis時(shí)项栏,自動(dòng)觸發(fā)save操作。
- 默認(rèn)情況下執(zhí)行shutdown命令時(shí)蹬竖,若沒(méi)有開(kāi)啟AOF持久化功能則自動(dòng)執(zhí)行bgsave沼沈。
優(yōu)缺點(diǎn):
- [ ] 優(yōu)點(diǎn): 適用于備份,全量復(fù)制等場(chǎng)景币厕×辛恚恢復(fù)數(shù)據(jù)遠(yuǎn)快于AOF方法。
- [ ] 缺點(diǎn):沒(méi)辦法做到實(shí)時(shí)持久化/秒級(jí)持久化旦装。 RDB使用特定二進(jìn)制格式页衙,redis演化中有多個(gè)RDB版本,存在版本不兼容情況阴绢。
AOF 持久化:
將寫(xiě)命令添加到AOF文件的末尾(append Only File)
使用AOF持久化需要設(shè)置同步選項(xiàng)店乐,從而保證寫(xiě)命令什么時(shí)候會(huì)被同步到磁盤文件上。這時(shí)因?yàn)閷?duì)文件進(jìn)行寫(xiě)入并不會(huì)呻袭,馬上將內(nèi)容同步到磁盤上眨八,而是先存儲(chǔ)到緩沖區(qū),然后由操作系統(tǒng)決定什么時(shí)候同步到磁盤左电。有以下同步方式:
- always:每個(gè)寫(xiě)命令都同步廉侧。嚴(yán)重影響服務(wù)器性能
- everysec:每秒同步一次÷ㄗ悖可以保證系統(tǒng)崩潰時(shí)只丟失一秒左右的數(shù)據(jù)段誊,每秒執(zhí)行一次對(duì)性能幾乎沒(méi)影響。
- no:讓操作系統(tǒng)決定栈拖,最長(zhǎng)30秒连舍。不能帶來(lái)太多的性能提升,但是會(huì)增加系統(tǒng)崩潰時(shí)數(shù)據(jù)丟失的數(shù)量辱魁。
隨著服務(wù)器寫(xiě)請(qǐng)求的增多烟瞧,AOF文件會(huì)越來(lái)越大。redis提供了一種將AOF重寫(xiě)的特性染簇,能夠去除AOF文件中冗余的寫(xiě)命令。
為什么會(huì)變星堪丁:
- 進(jìn)程中已經(jīng)超時(shí)數(shù)據(jù)不再寫(xiě)入文件锻弓。
- 舊的AOF文件含有無(wú)效命令。
- 多條命令合并(對(duì)同一鍵值的更新)蝌箍。