導(dǎo)讀
- redis的工作模型和常用數(shù)據(jù)結(jié)構(gòu)
- redis的持久化及數(shù)據(jù)淘汰機(jī)制
- redis的應(yīng)用場(chǎng)景及應(yīng)對(duì)措施
- 分布式鎖
- 緩存穿透、緩存擊穿和緩存雪崩
- redis的性能瓶頸
redis工作模型
redis的特點(diǎn):
- 單線程
- 高并發(fā)
- 高性能
- 支持分布式鎖
單線程
-
多線程的優(yōu)缺點(diǎn):
- 優(yōu)點(diǎn):提高cpu的利用率
- 缺點(diǎn):需要額外的管理開銷,需要復(fù)雜的同步機(jī)制,避免死鎖等等。
-
單線程的優(yōu)缺點(diǎn):
- 沒有線程切換的消耗
- 實(shí)現(xiàn)并發(fā)處理,有點(diǎn)復(fù)雜
-
redis為什么要使用單線程?
- 沒有線程上下文切換的消耗
- redis在內(nèi)存中工作,性能比較好,無需多線程
- redis依賴多路復(fù)用,實(shí)現(xiàn)了并發(fā)處理
底層數(shù)據(jù)結(jié)構(gòu)
-
redis底層的數(shù)據(jù)類型
-
字符串
- 簡(jiǎn)單動(dòng)態(tài)字符串
- free:可以知道緩存區(qū)還有多少剩余空間,可以將惰性空間釋放
- len:做字符串間隔,不需要用指定的字符來間隔,并且可以直接獲取字符串長(zhǎng)度,不需要遍歷
-
鏈表
-
哈希
- table:指向桶
- size:元素的個(gè)數(shù)
- sizemask:hash計(jì)算掩碼
- rehash的過程:
- 按照ht[0]的大小給h[1]分配空間
- 將ht[0]的元素rehash計(jì)算放入ht[1]中
- ht[0]放完之后,釋放ht[0]
- 將原h(huán)t[0]指向ht[1]
- 漸進(jìn)式rehash
- 按照ht[0]的大小給h[1]分配空間
- 維持一個(gè)rehashIndex,記錄遷移狀態(tài)
- 每次增刪改查都對(duì)ht[0]和ht[1]操作,將ht[0]刪除,rehashIndex++
- 當(dāng)遷移完成之后,將ht[0]釋放,并rehashIndex置未-1
-
集合
- 無序
- 不重復(fù)
- 整數(shù)集合:當(dāng)這個(gè)集合內(nèi)只有整數(shù)的時(shí)候,redis會(huì)自動(dòng)選擇使用整數(shù)集合
-
有序集合 sortSet
-
redis的工作模型
了解redis的單線程模型工作原理?一篇文章就夠了
多路復(fù)用模型+事件處理器redis的應(yīng)用場(chǎng)景
Redis在互聯(lián)網(wǎng)公司一般有以下應(yīng)用:
String:緩存、限流、計(jì)數(shù)器、分布式鎖、分布式Session
Hash:存儲(chǔ)用戶信息、用戶主頁訪問量、組合查詢
List:微博關(guān)注人時(shí)間軸列表、簡(jiǎn)單隊(duì)列
Set:贊、踩、標(biāo)簽、好友關(guān)系
Zset:排行榜
持久化
- redis持久化
- RDB:數(shù)據(jù)快照模式(save、bgsave、自定義)
- 優(yōu)點(diǎn):
- 簡(jiǎn)單、恢復(fù)快
- 不影響性能(bgsave)
- 缺點(diǎn):
- 在fork的之后,如果有變更,會(huì)丟失
- 實(shí)現(xiàn)比較重,只有數(shù)據(jù)的最終狀態(tài)
- 優(yōu)點(diǎn):
- AOF:增量日志模式(always、second、自定義)
- 優(yōu)點(diǎn):
- 安全,可以根據(jù)不同配置,保證較小區(qū)間的數(shù)據(jù)丟失
- 輕量、靈活
- 缺點(diǎn):
- rewrite可能會(huì)影響系統(tǒng)性能
- 恢復(fù)慢
- 優(yōu)點(diǎn):
- RDB:數(shù)據(jù)快照模式(save、bgsave、自定義)
緩存淘汰
- redis過期策略和內(nèi)存淘汰
-
- redis采用定時(shí)刪除+惰性刪除,缺點(diǎn)是如果一些key始終沒有被操作,那會(huì)一直存在于內(nèi)存中。這時(shí)就需要內(nèi)存淘汰機(jī)制。
- redis的定時(shí)刪除
Redis 默認(rèn)會(huì)每秒進(jìn)行 10 次(redis.conf 中通過 hz 配置)過期掃描,掃描并不是遍歷過期字典中的所有鍵,而是采用了如下方法:
從過期字典中隨機(jī)取出 20 個(gè)鍵
刪除這 20 個(gè)鍵中過期的鍵
如果過期鍵的比例超過 25% ,重復(fù)步驟 1 和 2為了保證掃描不會(huì)出現(xiàn)循環(huán)過度,導(dǎo)致線程卡死現(xiàn)象,還增加了掃描時(shí)間的上限,默認(rèn)是 25 毫秒(即默認(rèn)在慢模式下,如果是快模式,掃描上限是 1 毫秒)
-
內(nèi)存淘汰機(jī)制
- LRU算法:Redis 緩存淘汰算法------LRU算法
- LFU算法
-
redis集群
-
redis分布式集群的常見形式
主從模式
哨兵模式
集群模式 -
Redis的多路復(fù)用
集群模式下key是怎么尋址的
分布式尋址都有哪些算法
一致性hash算法如何動(dòng)態(tài)的增加和刪除一個(gè)節(jié)點(diǎn)
常見問題
-
緩存穿透、緩存擊穿、緩存雪崩
- 緩存穿透
- 查詢了不存在的數(shù)據(jù),每次都會(huì)透過redis,查詢db
- 解決方法:布隆過濾器、當(dāng)返回結(jié)果為空,也進(jìn)行緩存。
- 緩存雪崩
- 大量key在同一時(shí)刻過期,導(dǎo)致db壓力暴增。
- 解決方法:
- 可以設(shè)置一個(gè)隨機(jī)范圍的過期時(shí)間
- 互斥鎖更新
- 緩存擊穿
- 單個(gè)key過期時(shí),正好有大量調(diào)用,請(qǐng)求直接打到db上。
- 解決方法:
- 互斥鎖更新
- 設(shè)置永不失效(不推薦)
- 無論結(jié)果是否存在都返回,不存在則起異步線程去獲取
- 緩存穿透
-
redis性能為什么高?
- 設(shè)計(jì)巧妙的數(shù)據(jù)結(jié)構(gòu)
- 多路復(fù)用模型
- 事件機(jī)制
-
有海量key和value都比較小的數(shù)據(jù),在redis中如何存儲(chǔ)才更省內(nèi)存?
首先這是一個(gè)hash結(jié)構(gòu)的數(shù)據(jù),在redis中hash結(jié)構(gòu)的數(shù)據(jù)通常是有兩種結(jié)構(gòu)保存。- 壓縮列表
- hashtable
從更省內(nèi)存的角度來看,應(yīng)該選擇壓縮列表,這種場(chǎng)景,可以將key映射到不同的map里,因?yàn)閗ey和value都很小,這樣就可以使用壓縮列表的數(shù)據(jù)結(jié)構(gòu)保存數(shù)據(jù)。
(事實(shí)上,redis在創(chuàng)建數(shù)據(jù)的時(shí)候,會(huì)自我判斷使用哪種數(shù)據(jù)結(jié)構(gòu)。) -
如何保證redis和DB中的數(shù)據(jù)一致性?
如何用redis實(shí)現(xiàn)分布式鎖?
-
壓測(cè)產(chǎn)生的垃圾數(shù)據(jù)該怎么清理
- db,用影子表
- redis,key帶上后綴,標(biāo)志
- 常見緩存問題解決方案
- redis事務(wù)
- redis的CAS方案
- redis的pipeline
- redis的主從復(fù)制原理
- 百億級(jí)key存儲(chǔ)方案
- 如何保證redis和數(shù)據(jù)庫的一致性
- redis和membercache的區(qū)別,為什么單線程的redis性能要比多線程的membercache要高
- redis的并發(fā)競(jìng)爭(zhēng)實(shí)質(zhì)是什么?如何解決
- redis的性能瓶頸
Redis 常見的性能問題和解決方法
Redis 的性能幻想與殘酷現(xiàn)實(shí)
延伸
- redis中hash的擴(kuò)容與縮容與java的hashmap方法的比較?
- 有序鏈表的實(shí)現(xiàn)
- redis中的跳躍表與hashmap的紅黑樹