亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

golang防緩存擊穿利器--singleflight

keithyau / 1505人閱讀

摘要:緩存擊穿給緩存加一個(gè)過期時(shí)間,下次未命中緩存時(shí)再去從數(shù)據(jù)源獲取結(jié)果寫入新的緩存,這個(gè)是后端開發(fā)人員再熟悉不過的基操。

緩存擊穿

????給緩存加一個(gè)過期時(shí)間,下次未命中緩存時(shí)再去從數(shù)據(jù)源獲取結(jié)果寫入新的緩存,這個(gè)是后端開發(fā)人員再熟悉不過的基操。本人之前在做直播平臺(tái)活動(dòng)業(yè)務(wù)的時(shí)候,當(dāng)時(shí)帶著這份再熟練不過的自信,把復(fù)雜的數(shù)據(jù)庫鏈表語句寫好,各種微服務(wù)之間調(diào)用撈數(shù)據(jù)最后算好的結(jié)果,丟進(jìn)了緩存然后設(shè)了一個(gè)過期時(shí)間,當(dāng)時(shí)噼里啪啦兩下寫完代碼覺得穩(wěn)如鐵蛋,結(jié)果在活動(dòng)快結(jié)束之前,數(shù)據(jù)庫很友好的掛掉了。當(dāng)時(shí)回去查看監(jiān)控后發(fā)現(xiàn),是在活動(dòng)快結(jié)束前,大量用戶都在瘋狂的刷活動(dòng)頁,導(dǎo)致緩存過期的瞬間有大量未命中緩存的請(qǐng)求直接打到數(shù)據(jù)庫上所導(dǎo)致的,所以這個(gè)經(jīng)典的問題稍不注意還是害死人

????防緩存擊穿的方式有很多種,比如通過計(jì)劃任務(wù)來跟新緩存使得從前端過來的所有請(qǐng)求都是從緩存讀取等等。之前讀過 groupCache的源碼,發(fā)現(xiàn)里面有一個(gè)很有意思的庫,叫singleFlight, 因?yàn)間roupCache從節(jié)點(diǎn)上獲取緩存如果未命中,則會(huì)去其他節(jié)點(diǎn)尋找,其他節(jié)點(diǎn)還沒有的話再從數(shù)據(jù)源獲取,所以這個(gè)步驟對(duì)于防擊穿非常有必要。singleFlight使得groupCache在多個(gè)并發(fā)請(qǐng)求對(duì)一個(gè)失效的key進(jìn)行源數(shù)據(jù)獲取時(shí),只讓其中一個(gè)得到執(zhí)行,其余阻塞等待到執(zhí)行的那個(gè)請(qǐng)求完成后,將結(jié)果傳遞給阻塞的其他請(qǐng)求達(dá)到防止擊穿的效果。

SingleFlight 使用Demo

本文模擬一個(gè)數(shù)據(jù)源是從調(diào)用rpc獲取的場(chǎng)景

然后再模擬一百個(gè)并發(fā)請(qǐng)求在緩存失效的瞬間同時(shí)調(diào)用rpc訪問源數(shù)據(jù)

效果

可以看到100個(gè)并發(fā)請(qǐng)求從源數(shù)據(jù)獲取時(shí),rpcServer端只收到了來自client 17的請(qǐng)求,而其余99個(gè)最后也都得到了正確的返回值。

SingleFlight 源碼剖析

在看完singleFlight的實(shí)際效果后,欣喜若狂,想必其實(shí)現(xiàn)應(yīng)該相當(dāng)復(fù)雜吧, 結(jié)果翻看源碼一看, 100行不到的代碼就解決了這么個(gè)業(yè)務(wù)痛點(diǎn), 不得不佩服。

package singlefilght

import "sync"

type Group struct {
    mu sync.Mutex
    m map[string]*Call // 對(duì)于每一個(gè)需要獲取的key有一個(gè)對(duì)應(yīng)的call
}

// call代表需要被執(zhí)行的函數(shù)
type Call struct {
    wg sync.WaitGroup // 用于阻塞這個(gè)調(diào)用call的其他請(qǐng)求
    val interface{} // 函數(shù)執(zhí)行后的結(jié)果
    err error         // 函數(shù)執(zhí)行后的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)
    }
    
    // 如果獲取當(dāng)前key的函數(shù)正在被執(zhí)行,則阻塞等待執(zhí)行中的,等待其執(zhí)行完畢后獲取它的執(zhí)行結(jié)果
    if c, ok := g.m[key]; ok {
        g.mu.Unlock()
        c.wg.Wait()
        return c.val, c.err
    }

    // 初始化一個(gè)call,往map中寫后就解
    c := new(Call)
    c.wg.Add(1)
    g.m[key] = c
    g.mu.Unlock()
    
  // 執(zhí)行獲取key的函數(shù),并將結(jié)果賦值給這個(gè)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

}

????對(duì)的沒看錯(cuò), 就這么100行不到的代碼就能解決緩存擊穿的問題,這算是我寫過最愉快的一篇博了,同時(shí)也推薦大家去讀一讀groupCache這個(gè)項(xiàng)目的源碼,會(huì)有更多驚喜的發(fā)現(xiàn)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/62074.html

相關(guān)文章

  • 雪崩利器:熔斷器 Hystrix 的原理與使用

    摘要:前言分布式系統(tǒng)中經(jīng)常會(huì)出現(xiàn)某個(gè)基礎(chǔ)服務(wù)不可用造成整個(gè)系統(tǒng)不可用的情況這種現(xiàn)象被稱為服務(wù)雪崩效應(yīng)為了應(yīng)對(duì)服務(wù)雪崩一種常見的做法是手動(dòng)服務(wù)降級(jí)而的出現(xiàn)給我們提供了另一種選擇服務(wù)雪崩效應(yīng)的定義服務(wù)雪崩效應(yīng)是一種因服務(wù)提供者的不可用導(dǎo)致服務(wù)調(diào)用者的 前言 分布式系統(tǒng)中經(jīng)常會(huì)出現(xiàn)某個(gè)基礎(chǔ)服務(wù)不可用造成整個(gè)系統(tǒng)不可用的情況, 這種現(xiàn)象被稱為服務(wù)雪崩效應(yīng). 為了應(yīng)對(duì)服務(wù)雪崩, 一種常見的做法是手動(dòng)服...

    jayzou 評(píng)論0 收藏0
  • 雪崩利器:熔斷器 Hystrix 的原理與使用

    摘要:前言分布式系統(tǒng)中經(jīng)常會(huì)出現(xiàn)某個(gè)基礎(chǔ)服務(wù)不可用造成整個(gè)系統(tǒng)不可用的情況這種現(xiàn)象被稱為服務(wù)雪崩效應(yīng)為了應(yīng)對(duì)服務(wù)雪崩一種常見的做法是手動(dòng)服務(wù)降級(jí)而的出現(xiàn)給我們提供了另一種選擇服務(wù)雪崩效應(yīng)的定義服務(wù)雪崩效應(yīng)是一種因服務(wù)提供者的不可用導(dǎo)致服務(wù)調(diào)用者的 前言 分布式系統(tǒng)中經(jīng)常會(huì)出現(xiàn)某個(gè)基礎(chǔ)服務(wù)不可用造成整個(gè)系統(tǒng)不可用的情況, 這種現(xiàn)象被稱為服務(wù)雪崩效應(yīng). 為了應(yīng)對(duì)服務(wù)雪崩, 一種常見的做法是手動(dòng)服...

    JessYanCoding 評(píng)論0 收藏0
  • 緩存穿透,緩存擊穿,緩存雪崩解決方案分析

    摘要:解決方案通過布隆過濾器攔截。對(duì)空結(jié)果進(jìn)行緩存,但是過期時(shí)間很短,不超過分鐘。緩存雪崩介紹緩存雪崩是指設(shè)置緩存采用了相同的過期時(shí)間,導(dǎo)致緩存在某一時(shí)刻同時(shí)失效,請(qǐng)求全部轉(zhuǎn)發(fā)到,瞬間壓力過重雪崩。 緩存穿透 介紹 緩存穿透是指查詢一個(gè)一定不存在的數(shù)據(jù),由于緩存是不命中時(shí)被動(dòng)寫,并且處于容錯(cuò)考慮,如果從存儲(chǔ)層查不到數(shù)據(jù)則不寫入緩存,這將導(dǎo)致這個(gè)不存在的數(shù)據(jù)每次請(qǐng)求都要到存儲(chǔ)層去查詢,失去了緩...

    Soarkey 評(píng)論0 收藏0
  • Redis實(shí)現(xiàn)廣告緩存、并完善緩存擊穿

    摘要:完善緩存擊穿問題問題描述,分布式場(chǎng)景中,有時(shí)候存在高并發(fā)訪問,比如秒殺活動(dòng)。在高并發(fā)訪問下請(qǐng)求全部懟到數(shù)據(jù)庫,可能導(dǎo)致數(shù)據(jù)庫掛掉,這就是緩存擊穿。緩存擊穿解決方案已經(jīng)能解決日常情況,但還是有一定提升的空間的。 做人、做程序,變則通,不變只能一直死循環(huán)下去 ————尼古斯拉 Docker安裝官方Redis 參考文章:Docker安裝官方Redis鏡像并啟用密碼認(rèn)證 拉取最新版...

    KitorinZero 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<