一.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中文網:https://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中;
本文來自博客園,作者:weibo,轉載請注明原文鏈接:https://www.cnblogs.com/weiboyaonuli/p/redis.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/518917.html
標籤:Java
上一篇:golang中的字串
