当前位置:网站首页>十分鐘徹底掌握緩存擊穿、緩存穿透、緩存雪崩
十分鐘徹底掌握緩存擊穿、緩存穿透、緩存雪崩
2022-07-06 13:02:00 【Java烟雨】
寫篇文章緩一下,分享一下老八股:緩存擊穿
、緩存穿透
、緩存雪崩
。
在了解這三大問題之前,我們要理解,常用的分布式緩存Redis單機並發量能達到萬級,常用的關系型數據庫MySQL一般並發量是千級,他們支持的並發量可能差十倍,所以要盡可能把流量攔截在緩存層。
為什麼呢?就像是大湖裏多排點水,就可能把小河道沖垮,不知道你聽過沒——長江之水天上來,白洋澱裏把不住。
本文目錄:
緩存擊穿
什麼是緩存擊穿
緩存擊穿如何解决
緩存穿透
什麼是緩存穿透
緩存穿透如何解决
緩存雪崩
什麼是緩存雪崩
緩存雪崩如何解决
正文:
什麼是緩存擊穿
先從緩存擊穿開始。
緩存擊穿: 一個並發訪問量比較大的key在某個時間過期,導致所有的請求直接打在DB上。
緩存擊穿
緩存擊穿會增大數據庫的負載,我們看看怎麼緩解。
緩存擊穿如何解决
加鎖更新
查詢緩存,發現緩存中不存在,加鎖,讓其它線程等待,只讓一個線程去更新緩存。
加鎖更新
异步更新
還有一個可行的方案是把緩存設置永不過期。那緩存怎麼更新呢?通過异步的方式去更新緩存。
比如後臺設置一個守護線程定時更新緩存,但這種定時比較難以把握。
异步更新機制實際上更適合用於緩存預熱。
緩存穿透
什麼是緩存穿透
緩存穿透:緩存穿透指的查詢緩存和數據庫中都不存在的數據,這樣每次請求直接打到數據庫,就好像緩存不存在一樣。
緩存穿透
緩存穿透將導致不存在的數據每次請求都要到存儲層去查詢,失去了緩存保護後端存儲的意義。
緩存穿透可能會使後端存儲負載加大,如果發現大量存儲層空命中,可能就是出現了緩存穿透問題。
緩存穿透可能有兩種原因:
自身業務代碼問題
惡意攻擊,爬蟲造成空命中
我們來看看如何解决。
緩存穿透如何解决
緩存空值/默認值
一種方式是在數據庫不命中之後,把一個空對象或者默認值保存到緩存,之後再訪問這個數據,就會從緩存中獲取,這樣就保護了數據庫。
緩存空值
緩存空值有兩大問題:
空值做了緩存,意味著緩存層中存了更多的鍵,需要更多的內存空間(如果是攻擊,問題更嚴重),比較有效的
方法是針對這類數據設置一個較短的過期時間,讓其自動剔除。
緩存層和存儲層的數據會有一段時間窗口的不一致,可能會對業務有一定影響。
例如過期時間設置為5分鐘,如果此時存儲層添加了這個數據,那此段時間就會出現緩存層和存儲層數據的不一致。
這時候可以利用消息隊列或者其它异步方式清理緩存中的空對象。
布隆過濾器
除了緩存空對象,我們還可以在存儲和緩存之前,加一個布隆過濾器,做一層過濾。
布隆過濾器裏會保存數據是否存在,如果判斷數據不不能再,就不會訪問存儲。
布隆過濾器過濾
那布隆過濾器是什麼玩意兒?查找它會不會很慢?
布隆過濾器是什麼?
不知道你對哈希錶了解多少,布隆過濾器是一個類似的東西。
它是一個連續的數據結構,每個存儲比特存儲都是一個bit
,即0
或者1
, 來標識數據是否存在。
存儲數據的時時候,使用K個不同的哈希函數將這個變量映射為bit列錶的的K個點,把它們置為1。
布隆過濾器結構
我們判斷緩存key是否存在,同樣,K個哈希函數,映射到bit列錶上的K個點,判斷是不是1:
如果全不是1,那麼key不存在;
如果都是1,也只是錶示key可能存在。
至於為什麼?因為哈希函數是存在碰撞的可能的。
關於緩存穿透的兩種主要解决方案,我們簡單對比一下:
緩存空對象核布隆過濾器方案對比
緩存雪崩
接下來我們看最嚴重的一種情况,緩存雪崩。
什麼是緩存雪崩
緩存雪崩: 當某⼀時刻發⽣⼤規模的緩存失效的情况,例如緩存服務宕機、大量key在同一時間過期,這樣的後果就是⼤量的請求進來直接打到DB上,可能導致整個系統的崩潰,稱為雪崩。
....博主太懶了字數太多了,不想寫了....文章已經做成PDF,有需要的朋友可以私信我免費獲取!
边栏推荐
- 【GNSS】抗差估计(稳健估计)原理及程序实现
- 基本Dos命令
- 记录:初次cmd启动MySQL拒接访问之解决
- The master of double non planning left the real estate company and became a programmer with an annual salary of 25W. There are too many life choices at the age of 25
- Meanings and differences of PV, UV, IP, VV, CV
- What are the functions and features of helm or terrain
- 记录:动态Web项目servlet访问数据库404错误之解决
- isEmpty 和 isBlank 的用法区别
- [algorithm] sword finger offer2 golang interview question 12: the sum of the left and right sub arrays is equal
- [rtklib 2.4.3 B34] version update introduction I
猜你喜欢
The port is occupied because the service is not shut down normally
[算法] 剑指offer2 golang 面试题8:和大于或等于k的最短子数组
RTKLIB: demo5 b34f. 1 vs b33
[algorithm] sword finger offer2 golang interview question 10: subarray with sum K
Fairygui bar subfamily (scroll bar, slider, progress bar)
音乐播放(Toggle && PlayerPrefs)
[算法] 剑指offer2 golang 面试题9:乘积小于k的子数组
[dry goods] cycle slip detection of suggestions to improve the fixed rate of RTK ambiguity
Fairygui joystick
[algorithm] sword finger offer2 golang interview question 12: the sum of the left and right sub arrays is equal
随机推荐
Pride-pppar source code analysis
Heap sort [handwritten small root heap]
[算法] 剑指offer2 golang 面试题4:只出现一次的数字
Fabrication d'un sac à dos simple fairygui
记录:Navicat Premium初次无法连接数据库MySQL之解决
Particle system for introduction to unity3d Foundation (attribute introduction + case production of flame particle system)
错误: 找不到符号
[rtklib 2.4.3 B34] version update introduction I
Employment of cashier [differential constraint]
MySQL performance tuning - dirty page refresh
[算法] 剑指offer2 golang 面试题8:和大于或等于k的最短子数组
[算法] 剑指offer2 golang 面试题5:单词长度的最大乘积
C code implementation of robust estimation in rtklib's pntpos function (standard single point positioning spp)
RTKLIB: demo5 b34f.1 vs b33
[algorithm] sword finger offer2 golang interview question 3: the number of 1 in the binary form of the first n numbers
Error: sorting and subscript out of bounds
Comparative analysis of the execution efficiency of MySQL 5.7 statistical table records
使用rtknavi进行RT-PPP测试
FairyGUI增益BUFF數值改變的顯示
Combination of fairygui check box and progress bar