應對快取擊穿的解決方法

2021-09-10 04:46:49 字數 1880 閱讀 7856

一.什麼樣的資料適合快取?

分析乙個資料是否適合快取,我們要從訪問頻率、讀寫比例、資料一致性等要求去分析. 

二.什麼是快取擊穿

在高併發下,多執行緒同時查詢同乙個資源,如果快取中沒有這個資源,那麼這些執行緒都會去資料庫查詢,對資料庫造成極大壓力,快取失去存在的意義.打個比方,資料庫是人,快取是防彈衣,子彈是執行緒,本來防彈衣是防止子彈打到人身上的,但是當防彈衣裡面沒有防彈的物質時,子彈就會穿過它打到人身上. 

三.快取擊穿的解決辦法

方案一後台重新整理

後台定義乙個job(定時任務)專門主動更新快取資料.比如,乙個快取中的資料過期時間是30分鐘,那麼job每隔29分鐘定時重新整理資料(將從資料庫中查到的資料更新到快取中).

這種方案比較容易理解,但會增加系統複雜度。比較適合那些 key 相對固定,cache 粒度較大的業務,key 比較分散的則不太適合,實現起來也比較複雜。

方案二檢查更新

將快取key的過期時間(絕對時間)一起儲存到快取中(可以拼接,可以新增新字段,可以採用單獨的key儲存..不管用什麼方式,只要兩者建立好關聯關係就行).在每次執行get操作後,都將get出來的快取過期時間與當前系統時間做乙個對比,如果快取過期時間-當前系統時間<=1分鐘(自定義的乙個值),則主動更新快取.這樣就能保證快取中的資料始終是最新的(和方案一一樣,讓資料不過期.)

這種方案在特殊情況下也會有問題。假設快取過期時間是12:00,而 11:59 

到 12:00這 1 分鐘時間裡恰好沒有 get 請求過來,又恰好請求都在 11:30 分的時 

候高併發過來,那就悲劇了。這種情況比較極端,但並不是沒有可能。因為「高 

併發」也可能是階段性在某個時間點爆發。

方案三分級快取

採用 l1 (一級快取)和 l2(二級快取) 快取方式,l1 快取失效時間短,l2 快取失效時間長。 請求優先從 l1 快取獲取資料,如果 l1快取未命中則加鎖,只有 1 個執行緒獲取到鎖,這個執行緒再從資料庫中讀取資料並將資料再更新到到 l1 快取和 l2 快取中,而其他執行緒依舊從 l2 快取獲取資料並返回。

這種方式,主要是通過避免快取同時失效並結合鎖機制實現。所以,當資料更 

新時,只能淘汰 l1 快取,不能同時將 l1 和 l2 中的快取同時淘汰。l2 快取中 

可能會存在髒資料,需要業務能夠容忍這種短時間的不一致。而且,這種方案 

可能會造成額外的快取空間浪費。

方案四加鎖

方法1// 方法1:

public synchronized listgetdata01()

return result;

}這種方式確實能夠防止快取失效時高併發到資料庫,但是快取沒有失效的時候,在從快取中拿資料時需要排隊取鎖,這必然會大大的降低了系統的吞吐量.

方法2// 方法2:

static object lock = new object();

public listgetdata02()

}return result;

}這個方法在快取命中的時候,系統的吞吐量不會受影響,但是當快取失效時,請求還是會打到資料庫,只不過不是高併發而是阻塞而已.但是,這樣會造成使用者體驗不佳,並且還給資料庫帶來額外壓力.

方法3//方法3

public listgetdata03() }}

return result;

}雙重判斷雖然能夠阻止高併發請求打到資料庫,但是第二個以及之後的請求在命中快取時,還是排隊進行的.比如,當30個請求一起併發過來,在雙重判斷時,第乙個請求去資料庫查詢並更新快取資料,剩下的29個請求則是依次排隊取快取中取資料.請求排在後面的使用者的體驗會不爽.

方法4static lock reenlock = new reentrantlock();

public listgetdata04() throws interruptedexception finally

應對快取擊穿的解決方法

分析乙個資料是否適合快取,我們要從訪問頻率 讀寫比例 資料一致性等要求去分析.在高併發下,多執行緒同時查詢同乙個資源,如果快取中沒有這個資源,那麼這些執行緒都會去資料庫查詢,對資料庫造成極大壓力,快取失去存在的意義.打個比方,資料庫是人,快取是防彈衣,子彈是執行緒,本來防彈衣是防止子彈打到人身上的,...

快取擊穿的解決方法

摘抄自 在平常高併發的系統中,大量的請求同時查詢乙個 key 時,此時這個key正好失效了,就會導致大量的請求都打到資料庫上面去。這種現象我們稱為快取擊穿。解決辦法 上面的現象是多個執行緒同時去查詢資料庫的這條資料,那麼我們可以在第乙個查詢資料的請求上使用乙個 互斥鎖來鎖住它。其他的執行緒走到這一步...

redis雪崩,穿透,擊穿以及解決方法

一瞬間有大量的訪問只是資料庫崩了,比如12點重新整理快取,在重新整理快取的同時有大量的請求訪問,由於快取中沒有資料,知己查詢資料庫知識服務宕機 解決 往redis中存入快取的時候每個key設定失效時間的時候加乙個隨機數,使其不再同一時間大批量的重新整理快取 如在集群中部署熱點資料均勻分布,或者設定熱...