Redis常見問題
- 2022 年 10 月 22 日
- 筆記
- 不可忽視的Java知識點
一.Redis的持久化方式?
RDB:定時對數據記憶體做快照存儲
AOF:記錄執行的命令
默認開啟RDB,AOF需手動設置開啟使用;實際的應用中,採取RDB+AOF結合使用
二者區別
RDB | AOF | |
---|---|---|
數據完整性 | 低(兩次備份有丟失數據的風險) | 高 |
宕機恢復速度 | 快(數據) | 慢(記錄的命令) |
數據優先順序 | 低(數據完整性低於AOF) | 高 |
文件大小 | 小(文件可以壓縮,並且記錄值) | 大 |
記憶體佔用 | 大量CPU和記憶體消耗 | AOF主要佔用磁碟IO資源,在重寫時,會佔用CPU和記憶體消耗 |
應用場景 | 追求更快的啟動速度使用RDB | 追求數據的安全性 |
觸發條件
RDB觸發機制有三種,分別是:save觸發、bgsave觸發和自動觸發
- bgsave觸發
具體流程是Redis進程執行fork操作創建子進程,RDB持久化過程由子進程負責,完成後自動結束。阻塞只發生在fork階段,一般時間很短。bgsave命令也是Redis內部RDB操作的默認方式。
- 自動觸發
配置:save second changes
作用:滿足限定時間範圍內key的變化數量達到指定數量即進行持久化
參數:second:監控時間範圍,changes:監控key的變化量
位置:在conf文件中進行配置
範例:
配置的含義:
900秒之內至少一次寫操作、300秒之內至少發生10次寫操作、60秒之內發生至少10000次寫操作;只要滿足任一條件,均會觸發bgsave
AOF觸發的條件有三種可以設置
二.Redis為什麼這麼快?
- 單執行緒,避免了多執行緒的頻繁切換開銷
- 記憶體操作
- IO多路復用
- 跳躍表
三.Redis的過期刪除策略和記憶體淘汰機制
1.過期刪除策略
定時: redis中存入一個帶有過期時間的key時,會為這個key生成一個專屬的定時器,用來監視這個key的過期時間,當過期時間達到後,立即進行刪除;優點是redis中的數據可以保持為最新的數據,但缺點是每個帶有過期時間的key都會分配一個定時器,對CPU和記憶體佔用消耗是很大的;
定期: redis每隔100ms會抽取一部分key檢驗其過期時間,達到後將其刪除;但是可能有些過期了的key始終抽取不到,導致記憶體佔用問題,於是定期刪除策略都和惰性刪除策略結合使用;
惰性: 當使用到某個key是,redis會先檢驗key的過期時間,時間達到進行刪除,弊端是某個不經常使用的key清楚不掉,佔用記憶體;
在使用redis的過期刪除策略時,採取的是定期+惰性,還會使用redis的記憶體淘汰機制!
2.記憶體淘汰機制
- novecation:當記憶體不足以容納新數據時,拋出異常;
- allkeys-lru:當記憶體不足以容納新數據時,使用lru演算法,從所有的key中找出最不常使用的key進行刪除;
- allkeys-random :當記憶體不足以容納新數據時,隨機抽取某個key進行刪除;
- volatile-lru:當記憶體不足以容納新數據時,使用lru演算法,從已設置過期時間的key中,找出最近不常使用的key進行刪除;
- volatile-random:當記憶體不足以容納新數據時,從已設置過期時間的key中,隨機抽取某個key進行刪除;
- volatile-ttl:刪除到期時間最早的key;
四.Redis的五種數據類型
List、String、Set、ZSet、Hash
詳細命令可參考redis中文網://www.redis.net.cn/
五.雪崩、擊穿、穿透
1.雪崩
如果在某一時刻快取集中失效,或者快取系統出現故障,所有的並發流量就會直接到達資料庫。數據存儲層的調用量就會暴增,用不了多長時間,資料庫就會被大流量壓垮,這種級聯式的服務故障,就叫作快取雪崩。
解決方案
- 解決快取雪崩問題最常用的一種方案就是保證Redis的高可用,將Redis快取部署成高可用集群(必要時候做成異地多活),可以有效的防止快取雪崩問題的發生。
- 為了緩解大並發流量,我們也可以使用限流降級的方式防止快取雪崩。例如,在快取失效後,通過加鎖或者使用隊列來控制讀資料庫寫快取的執行緒數量。具體點就是設置某些Key只允許一個執行緒查詢數據和寫快取,其他執行緒等待。則能夠有效的緩解大並發流量對資料庫打來的巨大衝擊。
- 另外,我們也可以通過數據預熱的方式將可能大量訪問的數據載入到快取,在即將發生大並發訪問的時候,提前手動觸發載入不同的數據到快取中,並為數據設置不同的過期時間,讓快取失效的時間點盡量均勻,不至於在同一時刻全部失效。
2.擊穿
快取中的數據在某個時刻批量過期,導致大部分用戶的請求都會直接落在資料庫上,這種現象就叫作快取擊穿。
解決方案
- 對於比較熱點的數據,我們可以在快取中設置這些數據永不過期;也可以在訪問數據的時候,在快取中更新這些數據的過期時間;如果是批量入庫的快取項,我們可以為這些快取項分配比較合理的過期時間,避免同一時刻失效。
- 還有一種解決方案就是:使用分散式鎖,保證對於每個Key同時只有一個執行緒去查詢後端的服務,某個執行緒在查詢後端服務的同時,其他執行緒沒有獲得分散式鎖的許可權,需要進行等待。不過在高並發場景下,這種解決方案對於分散式鎖的訪問壓力比較大。
3.穿透
在查詢某個Key對應的數據時,Redis快取中沒有相應的數據,則直接到資料庫中查詢。資料庫中也不存在要查詢的數據,則資料庫會返回空,而Redis也不會快取這個空結果。導致查詢每次都會請求到資料庫;
解決方案
- 當進行查詢時,發現key不存在,則為其設置個空值並設置合理的過期時間,減少資料庫的壓力
- 布隆過濾器:設置布隆過濾器,相當於redis的網關,會對redis的key進行三次hash計算,得到的結果都為1的話證明redis中存在對應的key,才會進入redis中,key有值返回數據,無值訪問資料庫,得到結果再存儲到redis中;