請求快取問題 怎樣應對快取穿透?

2021-10-16 05:35:29 字數 1688 閱讀 5245

1為什麼需要快取

如果沒有快取,那麼所有業務請求會直接指向資料庫,以mysql為例的資料庫基本都是基於磁碟的,而磁碟i/o開銷大,面對大規模請求時,會降低系統效能。

對一些熱點資料,將其從資料庫中抽離出來放進快取,每次查詢時先走快取,快取命中則直接返回結果,能提高效率。

2快取帶來的問題

有三個經典問題:

快取雪崩:指快取大面積失效,導致大量查詢落到了資料庫上,使資料庫掛掉。

快取擊穿:快取中熱點key突然失效,原本走快取的大量請求直接打向了資料庫,就好像在快取中擊穿了乙個洞。

快取穿透:使用者一直請求快取和資料庫都不存在的資料,每次請求快取不命中,資料庫也不命中,就像快取不存在一樣,同時不斷地請求也給資料庫帶來壓力。

3應對方案

這裡主要介紹快取穿透的解決方案,先看兩幅原理圖。

使用者請求大致原理圖:

使用者發出請求後先查快取,快取命中則直接返回;

快取不命中就查資料庫,查到後將資料寫入快取並返回給使用者。

使用者請求快取和資料庫都沒有的資料(即快取穿透,如請求id=-1的資料):

此時快取基本失去了作用。

常見的解決思路:

將使用者請求的不存在的資料也放進快取,並將值置為null,這樣請求走快取的時候發現結果為null,直接返回即可。

但是需要給快取中的key設定乙個合適的過期時間,否則資料庫中有了這樣的資料,就會出現 資料不一致 問題。

更好的解決思路:

使用 布隆過濾器(bloom filter) 。 它可用於快速判斷資料是否存在於某個集合中,借助這個功能,我們可用它來應對快取穿透。

回顧一下布隆過濾器的兩條重要特性:

1. 布隆過濾器判定資料存在,那麼它可能存在也可能不存在。

2. 布隆過濾器判定資料不存在,那麼它一定不存在。

加上布隆過濾器之後:

使用者請求資料,若bloom filter返回false,則直接過濾該請求或返回null;若 bloom filter 返回true,則查快取,快取命中則返回,不命中則查資料庫。

bloom filter 就好像是加在快取前的一道 屏障 ,過濾了幾乎所有不符合要求的請求。雖然有一定的誤判率,即可能有少數通過了 blo om filter 的請求在資料庫和快取中也還是不命中,但相比之下,整個系統效能已經大大提公升,且 blo om filter 的預設誤判率只有0.03.

順帶提一下快取擊穿和快取雪崩的解決方案。

快取擊穿:

在被查詢的資料上加互斥鎖,一條請求執行緒拿到鎖後其它執行緒只能等待。

快取雪崩:

事前:盡量保證整個 redis 集群的高可用性,發現機器宕機盡快補上。選擇合適的記憶體淘汰策略。

事中:本地ehcache快取 + hystrix限流&降級,避免mysql崩掉。

事後:利用 redis 持久化機制儲存的資料盡快恢復快取。

快取穿透 快取擊穿 快取雪崩問題

快取穿透 快取穿透,是指查詢乙個資料庫一定不存在的資料正常的使用快取流程大致是,資料查詢先進行快取查詢,如果 key 不存在或者 key 已經過期,再對資料庫進行查詢,並把查詢到的物件,放進快取。如果資料庫查詢物件為空,則不放進快取,就會每次都去查詢資料庫,而每次查詢都是空,每次又都不會進行快取。假...

Redis快取穿透 快取雪崩問題

穿透雪崩主要是因為查詢資料庫造成的,那麼讀寫分離,快取資料查詢失敗不去查資料庫就好了。查的時候有即是有,無即是無,不會再查資料庫,快取的穿透和雪崩問題就不存在了。其次新增資料庫和快取同步功能,保證資料庫和快取資料是一致的即可 需要注意的是這時候資料庫資料是有限和相對穩定的,其實如果是海量資料同時放入...

快取 redis 快取穿透

哪一些因素 考慮使用redis,畢竟 redis 也要增加成本 1 熱點資料 2 讀的成本非常大 3 讀多寫少 4 對資料一致性要求 沒有那麼嚴格 可以出現資料與資料庫不一致 1 秒殺場景 3 物流查詢軌跡 熱點資料 啟用的資料是被快取到redis 當中 快取key 乙個時間點過期的時候,如果快取資...