日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

Golang 高性能無 GC 的緩存庫 bigcache 是怎么實現(xiàn)的?

來源: 責編: 時間:2024-02-29 14:44:20 354觀看
導讀我們寫代碼的時候,經常會需要從數(shù)據(jù)庫里讀取一些數(shù)據(jù),比如配置信息或者諸如每周熱點商品之類的數(shù)據(jù)。應用讀取數(shù)據(jù)庫如果這些數(shù)據(jù)既不經常變化,又需要頻繁讀取,那比起每次都去讀數(shù)據(jù)庫,更優(yōu)的解決方案就是將它們放到應用的

我們寫代碼的時候,經常會需要從數(shù)據(jù)庫里讀取一些數(shù)據(jù),比如配置信息或者諸如每周熱點商品之類的數(shù)據(jù)。6ph28資訊網——每日最新資訊28at.com

6ph28資訊網——每日最新資訊28at.com

應用讀取數(shù)據(jù)庫6ph28資訊網——每日最新資訊28at.com

如果這些數(shù)據(jù)既不經常變化,又需要頻繁讀取,那比起每次都去讀數(shù)據(jù)庫,更優(yōu)的解決方案就是將它們放到應用的本地內存里,這樣可以省下不少數(shù)據(jù)庫 IO,性能嘎一下就上來了。6ph28資訊網——每日最新資訊28at.com

6ph28資訊網——每日最新資訊28at.com

應用優(yōu)先讀緩存6ph28資訊網——每日最新資訊28at.com

那么現(xiàn)在問題就來了,假設我要在某個服務應用里實現(xiàn)一個緩存組件去存各種類型的數(shù)據(jù),該怎么實現(xiàn)這個組件呢?6ph28資訊網——每日最新資訊28at.com

從一個 map 說起

最簡單的的方案就是使用 map,也就是字典,將需要保存的結構以 key-value 的形式,保存到內存中。比如系統(tǒng)配置,key 就叫 system_config,value 就是具體的配置內容。需要讀取數(shù)據(jù)就用 v = m[key]來獲取數(shù)據(jù),需要寫數(shù)據(jù)就執(zhí)行m[key] = v.6ph28資訊網——每日最新資訊28at.com

6ph28資訊網——每日最新資訊28at.com

單線程讀寫map6ph28資訊網——每日最新資訊28at.com

這樣看起來在單線程下是滿足需求了。但如果我想在多個線程(協(xié)程)里并發(fā)讀寫這個緩存呢?那必然會發(fā)生競態(tài)問題。這就需要加個讀寫鎖了。讀操作前后要加鎖和解鎖,也就是改成下面這樣。6ph28資訊網——每日最新資訊28at.com

RLock()v = m[key]RUnLock()

寫操作也需要相應修改:6ph28資訊網——每日最新資訊28at.com

Lock()m[key] = vUnLock()

6ph28資訊網——每日最新資訊28at.com

多線程加鎖讀寫map6ph28資訊網——每日最新資訊28at.com

這在讀寫不頻繁的場景下是完全 ok 的,如果沒有什么性能要求,服務也沒出現(xiàn)什么瓶頸,就算新來的實習生笑它很 low,你也要有自信,這就是個好用的緩存組件。架構就是這樣,能快速滿足需求,不出錯就行。6ph28資訊網——每日最新資訊28at.com

但其實這個方案其實也有很大的問題,如果讀寫 qps 非常高,那么就會有一堆請求爭搶同一個 map 鎖,這對性能影響太大了。怎么解決呢?6ph28資訊網——每日最新資訊28at.com

將鎖粒度變小

上面的方案中,最大的問題是所有讀寫請求,都搶的同一個鎖,所以競爭才大,如果能將一部分請求改為搶 A 鎖,另一部分請求改為搶 B 鎖,那競爭就變小了。于是,我們可以將原來的一個 map,進行分片,變成多個 map,每個 map 都有自己的鎖。發(fā)生讀寫操作時,第一步先對 key 進行 hash 分片,獲取分片對應的鎖后,再對分片 map 進行讀寫。只有落在同一個分片的請求才會發(fā)生鎖爭搶。也就是說 map 拆的越細,鎖競爭就越小。6ph28資訊網——每日最新資訊28at.com

6ph28資訊網——每日最新資訊28at.com

分片鎖6ph28資訊網——每日最新資訊28at.com

像這種將資源分割成多個獨立的分片(segments/shard),每個段都有一個對應的鎖來控制并發(fā)訪問的控制機制, 其實就是所謂的分片(段)鎖。看起來很完美,但其實還有問題。6ph28資訊網——每日最新資訊28at.com

gc 帶來的問題

像 C/C++這類語言中,用戶申請的內存需要由用戶自己寫代碼去釋放,一不小心忘了釋放那就會發(fā)生內存泄露,給程序員帶來了很大的心智負擔。為了避免這樣的問題,一般高級語言里都會自帶 GC,也就是垃圾回收(Garbage Collection),說白了就是程序員只管申請內存,用完了系統(tǒng)會自動回收釋放這些內存。比如 golang,它會每隔一段時間就去掃描哪些變量內存是可以被回收的。對于指針類型,golang 會先掃指針,再掃描指針指向的對象里的內容。map緩存里放的東西少還好說,緩存里的 key-value 一多,那就喜提多遍瘋狂掃描,浪費,全是浪費,golang 你糊涂啊。6ph28資訊網——每日最新資訊28at.com

6ph28資訊網——每日最新資訊28at.com

gc掃描指針對象6ph28資訊網——每日最新資訊28at.com

那有沒有辦法可以減少這部分 gc 掃描 成本呢?有。golang 對于key 和 value 都不含指針的的map,會選擇跳過,不進行 gc 掃描。所以我們需要想辦法將 map 里的內容改成完全不含指針。原來 map 中放的 key-value,key和value 都可能是指針結構體。6ph28資訊網——每日最新資訊28at.com

1.對于 key

原來 key 是用的字符串,在 golang 中字符串本質上也是指針,于是我們將它進行 hash 操作,將字符串轉為整形。信息經過 hash 操作后,有可能會丟掉部分信息,為了避免hash沖突時分不清具體是哪個 key-value,我們會將 key 放到 value 中一起處理,繼續(xù)看下面。6ph28資訊網——每日最新資訊28at.com

2.對于 value

我們可以構造一個超大的 byte 數(shù)組 buf,將原來的 key value 等信息經過序列化,變成二進制01串。將它存放到這個超大 buf 中,并記錄它在 超大 buf 中的位置 index。然后將這個位置 index 信息放到 map 的 value 位置上,也就是從 key-velue,變成了 key-index。6ph28資訊網——每日最新資訊28at.com

6ph28資訊網——每日最新資訊28at.com

引入buf減少gc掃描6ph28資訊網——每日最新資訊28at.com

同時為了防止 buf 數(shù)組變得過大,占用過多內存導致應用oom,還可以采用 ringbuf 的結構,寫到尾部就重頭開始寫,如果 ringbuf 空間不夠,還能對它進行擴容。6ph28資訊網——每日最新資訊28at.com

6ph28資訊網——每日最新資訊28at.com

ringbuf擴容6ph28資訊網——每日最新資訊28at.com

3.寫操作

對于寫操作,程序先將 key 進行 hash,得到所在分片 map,加鎖。6ph28資訊網——每日最新資訊28at.com

  • 如果不能從分片 map 里拿到 index,也就是 map 中沒舊數(shù)據(jù),那就找到 ringbuf 里的空位置后寫入 value,再將index寫入map。
  • 如果能從分片 map 里拿到 index,也就是 map 中有舊數(shù)據(jù),那就覆蓋寫 ringbuf。

然后解鎖,結束流程。6ph28資訊網——每日最新資訊28at.com

6ph28資訊網——每日最新資訊28at.com

寫分片map流程6ph28資訊網——每日最新資訊28at.com

4.讀操作

對于讀操作,程序同樣先對 key 進行 hash,得到分片 map。加鎖,從分片 map 里拿到 value 對應的 index,拿著這個 index 到 ringbuf 數(shù)組中去獲取到 value 的值,然后解鎖,結束流程。6ph28資訊網——每日最新資訊28at.com

6ph28資訊網——每日最新資訊28at.com

讀分片map流程6ph28資訊網——每日最新資訊28at.com

到這里,我們可以發(fā)現(xiàn) map 的 key 和 value 都被改成了整形數(shù)字,也就省下了大量的 gc 掃描,大大提升了組件性能。其實這就是有名的高性能無 GC 的緩存庫 github.com/allegro/bigcache 的實現(xiàn)原理。6ph28資訊網——每日最新資訊28at.com

bigcache 的使用

它的使用方法大概像下面這樣。6ph28資訊網——每日最新資訊28at.com

package mainimport (    "fmt"    "github.com/allegro/bigcache/v3")func main() {    // 設置 bigcache 配置參數(shù)    cacheConfig := bigcache.Config{        Shards: 1024, // 分片數(shù)量,提高并發(fā)性    }    // 初始化 bigcache    cache, _ := bigcache.NewBigCache(cacheConfig)    // 寫緩存數(shù)據(jù)    key := "歡迎關注"    value := []byte("小白debug")    cache.Set(key, value)    // 讀緩存數(shù)據(jù)    entry, _ := cache.Get(key)    fmt.Printf("Entry: %s/n", entry)}

說白了就是 Get 方法讀緩存數(shù)據(jù),Set 方法寫緩存數(shù)據(jù),比較簡單。現(xiàn)在,大概原理和使用方法我們都懂了,我們再來看下 bigcache 中,兩個我認為挺巧妙的設計點。6ph28資訊網——每日最新資訊28at.com

ringbuf 中的數(shù)據(jù)格式

在前面的介紹中,我猜你心里可能有疑問,程序從 ringbuf 讀寫 value 的時候,ringbuf里面放的都是 01 二進制數(shù)組,程序怎么知道該讀多少bit才算一個完整 value?bigcache 的解法非常值得學習,它重新定義了一個新的數(shù)據(jù)格式。6ph28資訊網——每日最新資訊28at.com

6ph28資訊網——每日最新資訊28at.com

ringbuf內數(shù)據(jù)格式6ph28資訊網——每日最新資訊28at.com

  • length 表示 header 到 data 的數(shù)據(jù)長度
  • header 是固定長度
  • data 則是 key 和 value 的完整數(shù)據(jù)。

當讀取 ringbuf 時,我們會先讀到 length,有了它,我們就能在 ringbuf 里拿到 header 和 data,header 里又含有 key 的長度,這樣就能在 data 里將 key 和 value 完整區(qū)分開來。6ph28資訊網——每日最新資訊28at.com

很多網絡傳輸框架中都會用到類似的方案,后面有機會跟大家細聊。6ph28資訊網——每日最新資訊28at.com

ringbuffer 的第 0 位

另外,還有個巧妙的設計是,在 bigcache 中, ringbuffer 的第 0 位并不用來存放任何數(shù)據(jù),這樣如果發(fā)現(xiàn) 分片 map 中得到數(shù)據(jù)的 index 為 0,就可以直接認為沒有對應的緩存數(shù)據(jù),那就不需要跑到 ringbuffer 里去撈一遍數(shù)據(jù)了,覺得學到了,記得在右下角給我點個贊。6ph28資訊網——每日最新資訊28at.com

6ph28資訊網——每日最新資訊28at.com

ringbuf不使用第0位6ph28資訊網——每日最新資訊28at.com

bigcache 的缺點

bigcache 性能非常好,但也不是完全沒有問題。比較明顯的是,它讀寫數(shù)據(jù)時,用的都是byte數(shù)組,但我們平時寫代碼用的都是結構體,為了讓結構體和 byte 數(shù)組互轉,我們就需要用到序列化和反序列化,這些都是成本。6ph28資訊網——每日最新資訊28at.com

另外它的緩存淘汰策略也比較粗暴,用的是 FIFO,不支持 LRU 或 LFU 的淘汰策略。6ph28資訊網——每日最新資訊28at.com

總結

  • 對于不頻繁讀寫的場景,加鎖讀寫 map 就夠了。
  • 對于需要頻繁讀寫的場景,可以使用分片鎖,減少鎖競爭。
  • 對于 golang,map 中含指針的話會引發(fā) gc 掃描,為了降低這部分成本,引入了 ringbuf,map 的 value 則改為緩存對象在 ringbuf 中的 index,以此提升組件性能。以后面試官問你看沒看過哪些優(yōu)秀組件的源碼的時候,你知道該怎么回答了吧?

本文鏈接:http://m.www897cc.com/showinfo-26-75379-0.htmlGolang 高性能無 GC 的緩存庫 bigcache 是怎么實現(xiàn)的?

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 變革性趨勢:生成式人工智能及其對軟件開發(fā)的影響

下一篇: 不可變與可變,Python數(shù)據(jù)類型大揭秘!

標簽:
  • 熱門焦點
Top 日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不
欧美午夜片在线观看| 91久久久久久国产精品| 欧美日韩中文另类| 国产精品第十页| 国产亚洲综合性久久久影院| 亚洲电影欧美电影有声小说| 亚洲精品一区二区三区樱花| 亚洲在线黄色| 久久久成人网| 免费成年人欧美视频| 欧美日韩精品伦理作品在线免费观看| 国产精品久久久久aaaa| 国内精品久久久久伊人av| 亚洲第一搞黄网站| 亚洲美女少妇无套啪啪呻吟| 亚洲一区国产一区| 久久久久一区二区三区| 欧美精品综合| 国产精品久久久久久妇女6080 | 欧美激情欧美狂野欧美精品| 欧美亚日韩国产aⅴ精品中极品| 国产亚洲福利一区| 亚洲看片网站| 久久久国产一区二区| 欧美日韩精品一本二本三本| 国语自产精品视频在线看一大j8| 日韩午夜精品| 久久久精品免费视频| 欧美日韩一区不卡| 伊人成综合网伊人222| 国产精品99久久久久久久女警| 久久激情综合| 欧美视频在线观看一区| 在线不卡a资源高清| 亚洲欧美国产毛片在线| 欧美成人久久| 国产亚洲一区在线| 在线视频欧美精品| 蜜桃av一区二区| 国产欧美日韩一级| 在线一区观看| 欧美大片91| 欧美激情影院| 国产一区二区三区免费在线观看 | 国产性色一区二区| 亚洲网站视频| 欧美激情一区二区三区全黄| 国产一区视频观看| 亚洲在线观看免费| 欧美日韩国产黄| 亚洲高清不卡| 久久精品国产免费| 国产精品国码视频| 亚洲美女精品一区| 久久野战av| 国产一区二区三区成人欧美日韩在线观看| 一本久久综合亚洲鲁鲁| 美女脱光内衣内裤视频久久影院| 国产欧美亚洲精品| 亚洲网站视频| 欧美日韩国产一区精品一区 | 亚洲精品一区二区三区福利| 久久嫩草精品久久久久| 国产精品一区二区在线观看网站| 亚洲精品在线看| 免费久久99精品国产自在现线 | 亚洲一区二区三区高清不卡| 欧美精品入口| 亚洲激情欧美激情| 免费观看在线综合| 亚洲大片免费看| 久久综合激情| 激情国产一区二区| 久久久久久久久久久久久女国产乱 | 欧美成人福利视频| 在线观看欧美日韩| 久久久久综合网| 国内外成人在线视频| 欧美一级午夜免费电影| 国产精品三上| 亚洲综合日韩在线| 国产精品视频精品视频| 亚洲女ⅴideoshd黑人| 国产精品美女主播在线观看纯欲| 亚洲视频中文| 欧美午夜美女看片| 亚洲一区二区三区精品在线观看| 欧美日韩一区二区三| 日韩一级精品| 欧美日韩在线不卡| 亚洲图片在线| 国产精品美女久久久久av超清| 亚洲一区二区欧美日韩| 国产精品久久久久久户外露出 | 销魂美女一区二区三区视频在线| 国产精品欧美久久久久无广告| 亚洲一区二区三区乱码aⅴ| 国产精品久久久久久久久久三级| 亚洲一区二区三区精品动漫| 国产精品一二一区| 久久成人18免费网站| 激情文学综合丁香| 免费欧美高清视频| 亚洲另类自拍| 国产精品成人播放| 欧美一进一出视频| 影音先锋在线一区| 欧美精品18+| 亚洲一区观看| 国产一区二区三区久久久| 麻豆9191精品国产| 亚洲美女区一区| 国产精品色婷婷| 久久精品一区二区国产| 亚洲盗摄视频| 欧美日韩在线观看一区二区| 亚洲欧美激情视频在线观看一区二区三区 | 国内激情久久| 欧美gay视频激情| 一本久久精品一区二区| 国产精品视频在线观看| 欧美在线亚洲综合一区| 亚洲国产另类久久久精品极度| 欧美另类在线播放| 亚洲欧美日韩国产综合精品二区| 国内成人精品一区| 欧美二区在线播放| 亚洲曰本av电影| 尤妮丝一区二区裸体视频| 欧美区二区三区| 欧美亚洲在线观看| 亚洲丰满在线| 欧美性猛片xxxx免费看久爱| 欧美中文字幕在线观看| 亚洲国产一二三| 国产精品乱码一区二区三区 | 欧美1区2区3区| 亚洲小说欧美另类社区| 国内一区二区三区在线视频| 欧美经典一区二区| 校园春色综合网| 亚洲人www| 国产美女精品| 欧美黑人多人双交| 午夜免费日韩视频| 亚洲黄色成人网| 国产欧美精品一区aⅴ影院| 欧美www视频| 欧美一级理论片| 日韩一级大片在线| 国产在线麻豆精品观看| 欧美日韩一区二区三区视频 | 久久电影一区| 99在线热播精品免费| 国内精品久久久久影院色 | 欧美成人亚洲成人日韩成人| 午夜精品久久久久久久99樱桃| 亚洲国产美女久久久久| 国产免费成人在线视频| 欧美激情一区二区三区高清视频| 久久av在线| 国产精品99久久久久久久vr| 亚洲二区视频在线| 国产欧美精品一区| 欧美日韩一区成人| 欧美成人蜜桃| 久久精品国产亚洲一区二区| 亚洲天堂成人| 亚洲人午夜精品| 激情六月婷婷综合| 国产精品一级二级三级| 欧美三级欧美一级| 欧美成在线视频| 久久久久久亚洲精品杨幂换脸 | 日韩午夜黄色| 亚洲国产欧美日韩精品| 国产一区二区三区久久久| 国产精品国产亚洲精品看不卡15| 欧美成人影音| 久久一二三四| 久久久国产精品一区二区三区| 亚洲综合不卡| 一区二区三区四区五区精品视频 | 亚洲国产精品va在线观看黑人| 国产欧美一区二区精品婷婷| 欧美午夜电影在线| 欧美精品自拍| 欧美福利专区| 麻豆成人精品| 久久久久久一区| 久久国产精品电影| 性欧美精品高清| 亚洲欧美精品伊人久久| 中国女人久久久| 一区二区三区三区在线| 99re6热只有精品免费观看 | 国产精品久久久久999| 欧美日韩视频在线一区二区观看视频| 欧美激情按摩| 欧美理论电影在线播放| 欧美欧美在线| 欧美日韩国产综合久久| 欧美日韩在线三级| 国产精品久久久久国产精品日日|