摘要:緩存擊穿給緩存加一個過期時間,下次未命中緩存時再去從數據源獲取結果寫入新的緩存,這個是后端開發人員再熟悉不過的基操。
緩存擊穿
????給緩存加一個過期時間,下次未命中緩存時再去從數據源獲取結果寫入新的緩存,這個是后端開發人員再熟悉不過的基操。本人之前在做直播平臺活動業務的時候,當時帶著這份再熟練不過的自信,把復雜的數據庫鏈表語句寫好,各種微服務之間調用撈數據最后算好的結果,丟進了緩存然后設了一個過期時間,當時噼里啪啦兩下寫完代碼覺得穩如鐵蛋,結果在活動快結束之前,數據庫很友好的掛掉了。當時回去查看監控后發現,是在活動快結束前,大量用戶都在瘋狂的刷活動頁,導致緩存過期的瞬間有大量未命中緩存的請求直接打到數據庫上所導致的,所以這個經典的問題稍不注意還是害死人
????防緩存擊穿的方式有很多種,比如通過計劃任務來跟新緩存使得從前端過來的所有請求都是從緩存讀取等等。之前讀過 groupCache的源碼,發現里面有一個很有意思的庫,叫singleFlight, 因為groupCache從節點上獲取緩存如果未命中,則會去其他節點尋找,其他節點還沒有的話再從數據源獲取,所以這個步驟對于防擊穿非常有必要。singleFlight使得groupCache在多個并發請求對一個失效的key進行源數據獲取時,只讓其中一個得到執行,其余阻塞等待到執行的那個請求完成后,將結果傳遞給阻塞的其他請求達到防止擊穿的效果。
SingleFlight 使用Demo本文模擬一個數據源是從調用rpc獲取的場景
然后再模擬一百個并發請求在緩存失效的瞬間同時調用rpc訪問源數據
效果
可以看到100個并發請求從源數據獲取時,rpcServer端只收到了來自client 17的請求,而其余99個最后也都得到了正確的返回值。
在看完singleFlight的實際效果后,欣喜若狂,想必其實現應該相當復雜吧, 結果翻看源碼一看, 100行不到的代碼就解決了這么個業務痛點, 不得不佩服。
package singlefilght import "sync" type Group struct { mu sync.Mutex m map[string]*Call // 對于每一個需要獲取的key有一個對應的call } // call代表需要被執行的函數 type Call struct { wg sync.WaitGroup // 用于阻塞這個調用call的其他請求 val interface{} // 函數執行后的結果 err error // 函數執行后的error } func (g *Group) Do(key string, fn func()(interface{}, error)) (interface{}, error) { g.mu.Lock() if g.m == nil { g.m = make(map[string]*Call) } // 如果獲取當前key的函數正在被執行,則阻塞等待執行中的,等待其執行完畢后獲取它的執行結果 if c, ok := g.m[key]; ok { g.mu.Unlock() c.wg.Wait() return c.val, c.err } // 初始化一個call,往map中寫后就解 c := new(Call) c.wg.Add(1) g.m[key] = c g.mu.Unlock() // 執行獲取key的函數,并將結果賦值給這個Call c.val, c.err = fn() c.wg.Done() // 重新上鎖刪除key g.mu.Lock() delete(g.m, key) g.mu.Unlock() return c.val, c.err }
????對的沒看錯, 就這么100行不到的代碼就能解決緩存擊穿的問題,這算是我寫過最愉快的一篇博了,同時也推薦大家去讀一讀groupCache這個項目的源碼,會有更多驚喜的發現
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/62074.html
摘要:前言分布式系統中經常會出現某個基礎服務不可用造成整個系統不可用的情況這種現象被稱為服務雪崩效應為了應對服務雪崩一種常見的做法是手動服務降級而的出現給我們提供了另一種選擇服務雪崩效應的定義服務雪崩效應是一種因服務提供者的不可用導致服務調用者的 前言 分布式系統中經常會出現某個基礎服務不可用造成整個系統不可用的情況, 這種現象被稱為服務雪崩效應. 為了應對服務雪崩, 一種常見的做法是手動服...
摘要:前言分布式系統中經常會出現某個基礎服務不可用造成整個系統不可用的情況這種現象被稱為服務雪崩效應為了應對服務雪崩一種常見的做法是手動服務降級而的出現給我們提供了另一種選擇服務雪崩效應的定義服務雪崩效應是一種因服務提供者的不可用導致服務調用者的 前言 分布式系統中經常會出現某個基礎服務不可用造成整個系統不可用的情況, 這種現象被稱為服務雪崩效應. 為了應對服務雪崩, 一種常見的做法是手動服...
摘要:解決方案通過布隆過濾器攔截。對空結果進行緩存,但是過期時間很短,不超過分鐘。緩存雪崩介紹緩存雪崩是指設置緩存采用了相同的過期時間,導致緩存在某一時刻同時失效,請求全部轉發到,瞬間壓力過重雪崩。 緩存穿透 介紹 緩存穿透是指查詢一個一定不存在的數據,由于緩存是不命中時被動寫,并且處于容錯考慮,如果從存儲層查不到數據則不寫入緩存,這將導致這個不存在的數據每次請求都要到存儲層去查詢,失去了緩...
摘要:完善緩存擊穿問題問題描述,分布式場景中,有時候存在高并發訪問,比如秒殺活動。在高并發訪問下請求全部懟到數據庫,可能導致數據庫掛掉,這就是緩存擊穿。緩存擊穿解決方案已經能解決日常情況,但還是有一定提升的空間的。 做人、做程序,變則通,不變只能一直死循環下去 ————尼古斯拉 Docker安裝官方Redis 參考文章:Docker安裝官方Redis鏡像并啟用密碼認證 拉取最新版...
閱讀 2436·2021-10-09 09:44
閱讀 3792·2021-09-22 15:43
閱讀 2925·2021-09-02 09:47
閱讀 2539·2021-08-12 13:29
閱讀 3871·2019-08-30 15:43
閱讀 1680·2019-08-30 13:06
閱讀 2189·2019-08-29 16:07
閱讀 2745·2019-08-29 15:23