在用redis當中可能遇到的問題解決方案以及redis中的一些名詞解釋
- Redis篇
- 一、緩存穿透:
- 解決方案:
- 緩存空數據
- 布隆過濾器
- 二、緩存擊穿
- 解決方案
- 互斥鎖,強一致性,性能差,速度慢
- 邏輯過期,數據不同步,性能優
- 三、緩存雪崩
- 解決方案
- 四、雙寫一致
- 解決方案
- 允許業務延時一致的業務,采用異步通知
- 強一致性的,采用Redisson提供的讀寫鎖
- 五、Redis持久化
- RDB
- AOF
- 六、數據過期策略
- 惰性刪除
- 定期刪除
- 七、數據淘汰策略
- LRU
- LFU
- 八、redis分布式鎖是如何實現的
- 分布式鎖主要利用Redis的setnx命令
- Redisson實現分布式鎖如何合理的控制鎖的有效時長
- Redisson的這個鎖,可以重入嗎
- Redisson鎖能解決主從一致的問題嗎
- 九、Redis集群有哪些方案,
- 主從同步
- 全量同步
- 主從增量同步(slave重啟或后期數據變化)
- 十、怎么保證Redis的高并發高可用
- 使用的redis是單點還是集群
- 分片集群結構
- 解釋I/O多路復用模型
- Redis網絡模型
- Redis網絡模型
Redis篇
一、緩存穿透:
名次解釋:查詢一個不存在的數據,musql查詢不到數據也不會直接寫入緩存,就會導致每次請求都查數據庫
解決方案:
-讓查詢返回的數據為空,這個空數據緩存在Redis當中,優點:簡單 *缺點:消耗內存,可能會發生不一致問題,
二、緩存擊穿
名次解釋:給某一個Key設置了過期時間,當key過期的時候,恰好這個時間段有大量的靠key查詢的請求發過來,這些請求可能一瞬間將DB壓垮
解決方案
-
互斥鎖,強一致性,性能差,速度慢
-
邏輯過期,數據不同步,性能優
三、緩存雪崩
名次解釋:緩存雪崩是指在統一時間內大量的緩存key同時失效或者Redis服務宕機,導致大量請求到達數據庫
解決方案
- 給不同的Key的TTL添加隨機值
- 利用Redis集群提高服務的可用性(哨兵模式,集群模式)
- 給緩存業務添加降級限流策略(ngxin或spring cloud gateway)
- 給業務添加多級緩存 guava或caffeine
四、雙寫一致
問題:redis作為緩存,mysql的數據怎么保證和redis的數據一樣
解決方案
允許業務延時一致的業務,采用異步通知
-
使用MQ中間中間件,更新數據之后,通知緩存刪除,在此當中保證MQ的可靠性
-
利用canal中間件,不需要修改業務代碼,偽裝為mysql的一個從節點,canal通過讀取binlog數據更新緩存
Canal是一個用于MySQL數據庫增量日志解析的開源工具,常用于數據庫鏡像、實時備份、索引維護和緩存刷新等。它模擬MySQLslave與master交互,解析binlog并提供數據同步。文章介紹了Canal的工作原理、架構、高可用機制以及配置和應用示例,包括與Redis和ES的同步,并提供了實戰代碼示例。
強一致性的,采用Redisson提供的讀寫鎖
-
共享鎖,讀鎖readlock
-
排他鎖:獨占鎖,加鎖之后,其他線程讀寫受阻
五、Redis持久化
RDB
basave開始時會fork(克隆)主進程得到子進程,子進程共向內存數據(頁表),頁表儲存著虛擬內存和物理內存之間的映射關系,完成fork操作之后讀取數據并且寫入RDB文件,
AOF
aof默認是關閉的,通過redis.conf文件來打開,配置項有三種,always,everysec,no,通過執行bgrewriteof命令,可以讓redis使用重寫功能,auto-aof-rewrite-pencentage 100(增長超過多少百分比觸發)
六、數據過期策略
惰性刪除
設置過期時間后,不去管它,當需要用到的時候,驗證是否過期,如果過期,則刪掉它,否則,就返回該key
優點:對Cpu友好,只有在用到該內存時,才會對該值進行檢查
缺點:長時間不用的話過期的key值堆積
定期刪除
每隔一段時間,我們就對一些key進行檢查,刪除里面過期的key(從一定數量的數據庫中取出一定數量的隨機key進行檢查,并刪除其中的過期key),分為兩種模式
slow模式是定時任務,執行頻率默認10hz,每次不超過25ms
fast模式執行頻率不固定,但兩次間隔時間不超過2ms
優點:可以限制刪除操作執行的時長和頻率來減少刪除操作對CPU的影響,
缺點:難以確定刪除操作執行的時長和頻率
七、數據淘汰策略
CTemp%5C1727269554012.png&pos_id=img-LdwbyIj5-1743062150316)
當Redis中的內存不夠時
此時再向Redis中添加新的數據,那么Redis就會使用一種策略將內存中的數據刪除掉
LRU
最近最少使用。用當前時間減去最后一次訪問時間,這個值越大則淘汰優先級越高
LFU
最少頻率使用。會統計每個key值得訪問頻率
- 優先使用allkeys-lru策略,把最近最常訪問得數據留在緩存當中,如果有明顯得冷熱數據區分,建議使用
- 如果數據訪問頻率差距不大,allkeys-random
- 有置頂需求,volatile-lru策略,同時置頂數據不設置過期時間
- 業務中有短時間內高頻訪問得數據,可以使用allkeys-lfu或者volatile-lfuf
八、redis分布式鎖是如何實現的
分布式鎖主要利用Redis的setnx命令
我們當使用的rdisson實現的分布式鎖,底層是setnx和lua腳本(保證原子性性),在代碼中,加鎖,設置過期時間等操作都是基于Lua腳本完成
Redisson實現分布式鎖如何合理的控制鎖的有效時長
在redisson的分布式鎖中,提供了一個WatchDog(看門狗),一個線程獲取鎖成功以后,WatchDog會給持有鎖的線程續期(默認是每十秒續期一次)
Redisson的這個鎖,可以重入嗎
可以重入,多個鎖重入需要判斷是否是當前線程,在redis中進行存儲的時候使用的hash結構,來存儲線程信息和重入的次數
Redisson鎖能解決主從一致的問題嗎
不能解決,但是可以使用redisson提供的紅鎖來解決,但性能低,如果非要保證數據的強一致性,采用zoo keeper實現的分布式鎖
九、Redis集群有哪些方案,
三種,主從同步,哨兵模式,Redis分片集群
主從同步
缺點 不能保證Redis的高可用性,當主節點宕機之后,就喪失了寫數據的能力
單節點Redis的并發能力是有上限的,要進一步提高Redis的并發能力,就需要搭建主從集群,實現讀寫分離,一般都是一主多從,主節點負責寫數據,從節點負責讀數據
全量同步
replication id:簡稱Replid,是數據集的標記,id一致說明是統一數據集,每一個master都有唯一的replid,slave則會繼承master節點的replid
offset: 偏移量,隨著記錄在repl_baklog中的數據增多而逐漸增大,slave完成同步時也會記錄當前同步的offset,如果slave中的offset小于master中的offset,說明slave數據落后于master,需要更新
步驟
1,salve執行replicaof命令,建立連接,請求數據同步,
2,master判斷是否是第一次同步(replid是否一致),是第一次,返回master的數據版本信息replid,offset,slave保存版本信息
3,master執行bgsave,生成RDB文件,發送RDB文件,slave清空本地數據,加載RDB文件
4,master,記錄RDB期間的所有命令,發送repl_baklog中的命令,slave執行收到的命令
主從增量同步(slave重啟或后期數據變化)
1,slave重啟,發送psync replid offset,master判斷請求replid是否一致,不是第一次,回復continue,去repl_baklog中獲取offset后的數據,發送offset后的命令,slave執行命令
十、怎么保證Redis的高并發高可用
哨兵模式:實現主從集群的自動故障恢復(監控,自動故障恢復,通知)
哨兵選主規則
-
首先判斷主從節點斷開時間長短,如超過指定值就排除該節點
-
判斷從節點的額slave-priority值,越小優先級越高
-
如果以上一樣,則判斷slave節點的offset值,越大優先級越高
-
判斷slave節點id值得大小
使用的redis是單點還是集群
主從(1+1)+哨兵,單節點內存不超過10G,如果內存不足,可以給不同得服務分配獨立的Redis主從節點
redis集群腦裂:是由于主節點和從節點的sentinel處于不同的網絡分區,使得sentinel沒有能夠心跳感知到主節點,所以通過選舉的方式提升了一個從節點為主,這樣就存在了兩個主節點,導致客戶點在老地節點那邊寫數據,新節點無法同步數據,當網絡恢復后,sentinel會將老的主節點將為從節點,這是再從新的master同步數據,
解決方法:修改redis的配置,設置最小的從節點數量,縮短同步的延遲時間
分片集群結構
解釋I/O多路復用模型
單個線程同時監聽多個,Socket,再某個Socekt進程可讀可寫時,得到通知,從而避免無效的等待,多數用epoll模式實現,它在通知socket就緒的同時,將socket寫入用戶空間,不會每個遍歷,節省了時間
Redis網絡模型
就是使用I/O多路復用結合時間的處理器來應對多個Socket請求
連接應答處理器
命令恢復處理器,在Redis6.0之后,使用多線程來處理
命令請求處理器,在Redis6.0之后,將命令的轉換使用了多線程,增加命令的轉換速度
無效的等待,多數用epoll模式實現,它在通知socket就緒的同時,將socket寫入用戶空間,不會每個遍歷,節省了時間
Redis網絡模型
就是使用I/O多路復用結合時間的處理器來應對多個Socket請求
連接應答處理器
命令恢復處理器,在Redis6.0之后,使用多線程來處理
命令請求處理器,在Redis6.0之后,將命令的轉換使用了多線程,增加命令的轉換速度