表格缓存问题_缓存常见问题,一网打尽哦!
勾哥:昨天發(fā)了一篇翻譯,英語水平一般般的我摳了半天字眼,一個 word 一個 word 翻譯過來,竟然被舉報了?!
哈?舉報的那位兄弟你是鹽吃多么
今天更新一篇緩存的常見問題,對很多開發(fā)老哥都能有幫助,盡量沒搞難度特別大,寫的簡單的很!有意見可以正常反饋~
(女神帶我避開杠精!)~~~以下正文~~~
對使用緩存時常遇到幾個問題,整理出了一個表格。
1. 緩存更新方式
第一個問題是緩存更新方式,這是決定在使用緩存時就該考慮的問題。
緩存的數(shù)據(jù)在數(shù)據(jù)源發(fā)生變更時需要對緩存進(jìn)行更新,數(shù)據(jù)源可能是 DB,也可能是遠(yuǎn)程服務(wù)。
更新的方式可以是主動更新。
數(shù)據(jù)源是 DB 時,可以在更新完 DB 后就直接更新緩存。
當(dāng)數(shù)據(jù)源不是 DB 而是其他遠(yuǎn)程服務(wù),可能無法及時主動感知數(shù)據(jù)變更,這種情況下一般會選擇對緩存數(shù)據(jù)設(shè)置失效期,也就是數(shù)據(jù)不一致的最大容忍時間。
這種場景下,可以選擇失效更新,key 不存在或失效時先請求數(shù)據(jù)源獲取最新數(shù)據(jù),然后再次緩存,并更新失效期。
但這樣做有個問題,如果依賴的遠(yuǎn)程服務(wù)在更新時出現(xiàn)異常,則會導(dǎo)致數(shù)據(jù)不可用。
改進(jìn)的辦法是異步更新,就是當(dāng)失效時先不清除數(shù)據(jù),繼續(xù)使用舊的數(shù)據(jù),然后由異步線程去執(zhí)行更新任務(wù)。這樣就避免了失效瞬間的空窗期。
另外還有一種純異步更新方式,定時對數(shù)據(jù)進(jìn)行分批更新。實際使用時可以根據(jù)業(yè)務(wù)場景選擇更新方式。
2. 數(shù)據(jù)不一致
第二個問題是數(shù)據(jù)不一致的問題,可以說只要使用緩存,就要考慮如何面對這個問題。
緩存不一致產(chǎn)生的原因一般是主動更新失敗,例如更新 DB 后,更新 Redis 因為網(wǎng)絡(luò)原因請求超時;或者是異步更新失敗導(dǎo)致。
解決的辦法——
- 如果服務(wù)對耗時不是特別敏感可以增加重試。
- 如果服務(wù)對耗時敏感可以通過異步補(bǔ)償任務(wù)來處理失敗的更新。
- 或者短期的數(shù)據(jù)不一致不會影響業(yè)務(wù),那么只要下次更新時可以成功,能保證最終一致性就可以。
3. 緩存穿透
第三個問題是緩存穿透。
產(chǎn)生這個問題的原因可能是外部的惡意攻擊,例如,對用戶信息進(jìn)行了緩存,但惡意攻擊者使用不存在的用戶 ID 頻繁請求接口,導(dǎo)致查詢緩存不命中,然后穿透 DB 查詢依然不命中。這時會有大量請求穿透緩存訪問到 DB。
解決的辦法——
- 對不存在的用戶,在緩存中保存一個空對象進(jìn)行標(biāo)記,防止相同 ID 再次訪問 DB,不過有時這個方法并不能很好解決問題,可能導(dǎo)致緩存中存儲大量無用數(shù)據(jù)。
- 使用 BloomFilter 過濾器,BloomFilter 的特點是存在性檢測,如果 BloomFilter 中不存在,那么數(shù)據(jù)一定不存在;如果 BloomFilter 中存在,實際數(shù)據(jù)也有可能會不存在。非常適合解決這類的問題。
4. 緩存擊穿
第四個問題是緩存擊穿,就是某個熱點數(shù)據(jù)失效時,大量針對這個數(shù)據(jù)的請求會穿透到數(shù)據(jù)源。
解決這個問題有這些辦法——
- 可以使用互斥鎖更新,保證同一個進(jìn)程中針對同一個數(shù)據(jù)不會并發(fā)請求到 DB,減小 DB 壓力。
- 使用隨機(jī)退避方式,失效時隨機(jī) sleep 一個很短的時間,再次查詢,如果失敗再執(zhí)行更新。
- 針對多個熱點 key 同時失效的問題,可以在緩存時使用固定時間加上一個小的隨機(jī)數(shù),避免大量熱點 key 同一時刻失效。
5. 緩存雪崩
第五個問題是緩存雪崩。產(chǎn)生的原因是緩存掛掉,這時所有的請求都會穿透到 DB。
解決方法——
- 使用快速失敗的熔斷策略,減少 DB 瞬間壓力。
- 使用主從模式和集群模式來盡量保證緩存服務(wù)的高可用。
- 實際場景中,這兩種方法會結(jié)合使用。
考察點與加分項
這部分主要面試考察點是對緩存特性的理解,對 MC、Redis 的特點和使用方式的掌握。
1. 要知道緩存的使用場景,不同類型緩存的使用方式,例如:
- 對 DB 熱點數(shù)據(jù)進(jìn)行緩存減少 DB 壓力;對依賴的服務(wù)進(jìn)行緩存,提高并發(fā)性能
- 單純 K-V 緩存的場景可以使用 MC,而需要緩存 list、set 等特殊數(shù)據(jù)格式,可以使用 Redis
- 需要緩存一個用戶最近播放視頻的列表可以使用 Redis 的 list 來保存、需要計算排行榜數(shù)據(jù)時,可以使用 Redis 的 zset 結(jié)構(gòu)來保存
2. 要了解 MC 和 Redis 的常用命令,例如:
- 原子增減、對不同數(shù)據(jù)結(jié)構(gòu)進(jìn)行操作的命令等
- 了解 MC 和 Redis 在內(nèi)存中的存儲結(jié)構(gòu),這對評估使用容量會很有幫助
- 了解 MC 和 Redis 的數(shù)據(jù)失效方式和剔除策略,比如主動觸發(fā)的定期剔除和被動觸發(fā)延期剔除
3. 要理解 Redis 的持久化、主從同步與 Cluster 部署的原理,例如:
- RDB 和 AOF 的實現(xiàn)方式與區(qū)別
如果想要在面試中獲得更好的表現(xiàn),還應(yīng)了解下面這些加分項。
1. 要結(jié)合實際應(yīng)用場景來介紹緩存的使用,例如:
- 調(diào)用后端服務(wù)接口獲取信息時,可以使用本地+遠(yuǎn)程的多級緩存
- 對于動態(tài)排行榜類的場景可以考慮通過 Redis 的 sorted set 來實現(xiàn)等等
2. 最好有過分布式緩存設(shè)計和使用經(jīng)驗,例如:
- 項目中在什么場景使用過 Redis,使用了什么數(shù)據(jù)結(jié)構(gòu),解決哪類的問題
- 使用 MC 時根據(jù)預(yù)估值大小調(diào)整 McSlab 分配參數(shù)等等
3. 最好可以了解緩存使用中可能產(chǎn)生的問題,例如:
- Redis 是單線程處理請求,應(yīng)盡量避免耗時較高的單個請求任務(wù),防止相互影響
- Redis 服務(wù)應(yīng)避免和其他 CPU 密集型的進(jìn)程部署在同一機(jī)器
- 禁用 Swap 內(nèi)存交換,防止 Redis 的緩存數(shù)據(jù)交換到硬盤上,影響性能
- MC 鈣化問題等等
4. 要了解 Redis 的典型應(yīng)用場景,例如:
- 使用 Redis 來實現(xiàn)分布式鎖
- 使用 Bitmap 來實現(xiàn) BloomFilter
- 使用 HyperLogLog 來進(jìn)行 UV 統(tǒng)計等等
5. 知道 Redis4.0、5.0 中的新特性,例如:
- 支持多播的可持久化消息隊列 Stream
- 通過 Module 系統(tǒng)來進(jìn)行定制功能擴(kuò)展等等
本文首發(fā)在公號:勾勾的Java宇宙
歡迎大家來找勾哥交流探討技術(shù)!
總結(jié)
以上是生活随笔為你收集整理的表格缓存问题_缓存常见问题,一网打尽哦!的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 嵌入式烤箱能不能放台面上_2021年开放
- 下一篇: el表达式动态取值中括号内两点_中考热点