<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          「GoCN酷Go推薦」高性能內(nèi)存緩存 ristretto

          共 4254字,需瀏覽 9分鐘

           ·

          2021-09-07 11:58

          背景

          ristrettodgraph 團隊開源的一款高性能內(nèi)存緩存庫,旨在解決高并發(fā)場景下的緩存性能和吞吐瓶頸。dgraph 專攻的方向是高性能圖數(shù)據(jù)庫,ristretto 就是其圖數(shù)據(jù)庫和 KV 數(shù)據(jù)庫產(chǎn)品的核心依賴。

          與 golang 社區(qū)常見的其他單進程內(nèi)存緩存類庫(groupcachebigcachefastcache 等)相比,ristretto 在緩存命中率和讀寫吞吐率上的綜合表現(xiàn)更優(yōu)。

          ristretto 簡介

          ristretto 主要有以下優(yōu)點:

          • 高命中率 - 特殊設(shè)計的錄入/驅(qū)逐政策
            • 驅(qū)逐(SampledLFU):與精確 LRU 相當,但在搜索和數(shù)據(jù)跟蹤上有更好的性能
            • 錄入(TinyLFU):以極小的內(nèi)存開銷獲取額外的性能提升
          • 高吞吐率
          • 權(quán)重感知的驅(qū)逐策略 - 價值權(quán)重大的條目可以驅(qū)逐多個價值權(quán)重小的條目
            • 依托權(quán)重可以擴展出緩存最大內(nèi)存占用、緩存最多條目數(shù)等場景
          • 完全并發(fā)支持
          • 性能指標 - 吞吐量、命中率及其他統(tǒng)計數(shù)據(jù)的性能指標
          • 用戶友好的 API 設(shè)計
            • 支持指定緩存失效時間

          ristretto 在 v0.1.0(2021-06-03) 版本發(fā)布時已正式標注為生產(chǎn)可用!

          ristretto 使用舉例

          構(gòu)建大小(條目數(shù))受限的緩存

          讓我們利用 ristretto 構(gòu)建一個緩存條目數(shù)最大為 10 的緩存試試看:

          package main

          import (
           "fmt"

           "github.com/dgraph-io/ristretto"
          )

          func main() {
           cache, err := ristretto.NewCache(&ristretto.Config{
            // num of keys to track frequency, usually 10*MaxCost
            NumCounters: 100,
            // cache size(max num of items)
            MaxCost: 10,
            // number of keys per Get buffer
            BufferItems: 64,
            // !important: always set true if not limiting memory
            IgnoreInternalCost: true,
           })
           if err != nil {
            panic(err)
           }

           // put 20(>10) items to cache
           for i := 0; i < 20; i++ {
            cache.Set(i, i, 1)
           }

           // wait for value to pass through buffers
           cache.Wait()

           cntCacheMiss := 0
           for i := 0; i < 20; i++ {
            if _, ok := cache.Get(i); !ok {
             cntCacheMiss++
            }
           }
           fmt.Printf("%d of 20 items missed\n", cntCacheMiss)
          }

          運行代碼可以發(fā)現(xiàn)最后只有 10 個條目還保存在緩存中

          $ go run main.go
          10 of 20 item missed

          注:當我們的緩存并非限制最大內(nèi)存占用時,IgnoreInternalCost 一定要設(shè)為 true,否則創(chuàng)建出的緩存將出現(xiàn)詭異的表現(xiàn)。

          測試緩存過期時間

          還是創(chuàng)建一個簡單的緩存,然后存一個過期時間為 1 秒的條目進去,看看接下來的緩存讀寫表現(xiàn):

          package main

          import (
           "log"
           "time"

           "github.com/dgraph-io/ristretto"
          )

          func main() {
           cache, err := ristretto.NewCache(&ristretto.Config{
            NumCounters:        100,
            MaxCost:            10,
            BufferItems:        64,
            IgnoreInternalCost: true,
           })
           if err != nil {
            panic(err)
           }

           // set item with 1s ttl
           cache.SetWithTTL("foo""bar"1, time.Second)

           // wait for value to pass through buffers
           cache.Wait()

           if val, ok := cache.Get("foo"); !ok {
            log.Printf("cache missing")
           } else {
            log.Printf("got foo: %v", val)
           }

           // sleep longer and try again
           time.Sleep(2 * time.Second)
           if val, ok := cache.Get("foo"); !ok {
            log.Printf("cache missing")
           } else {
            log.Printf("got foo: %v", val)
           }
          }

          運行代碼可以發(fā)現(xiàn)已過期的條目被正常清除出了緩存

          $ go run main.go
          2021/09/03 14:19:56 got foo: bar
          2021/09/03 14:19:58 cache missing

          總結(jié)

          ristretto 是支持高并發(fā)高吞吐的內(nèi)存緩存庫,尤其適用于數(shù)據(jù)庫、搜索引擎、文件系統(tǒng)等 io 密集場景。需要注意的是 ristretto 只適用于單機單進程的緩存方案,更像是 golang 中的 Caffeine (java),并不作為 redis 和 memcache 的替代品。

          大家趕快試試吧!

          參考資料

          • https://github.com/dgraph-io/ristretto
          • https://dgraph.io/blog/post/introducing-ristretto-high-perf-go-cache/
          • https://github.com/dgraph-io/badger
          • https://github.com/hashicorp/golang-lru
          • https://github.com/golang/groupcache

          《酷Go推薦》招募:


          各位Gopher同學,最近我們社區(qū)打算推出一個類似GoCN每日新聞的新欄目《酷Go推薦》,主要是每周推薦一個庫或者好的項目,然后寫一點這個庫使用方法或者優(yōu)點之類的,這樣可以真正的幫助到大家能夠?qū)W習到

          新的庫,并且知道怎么用。


          大概規(guī)則和每日新聞類似,如果報名人多的話每個人一個月輪到一次,歡迎大家報名!戳「閱讀原文」,即可報名


          掃碼也可以加入 GoCN 的大家族喲~


          瀏覽 51
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产激情小视频在线观看 | 欧美一级中文字幕 | 国产精品在线免费视频 | 18色美女 | 亚洲色图 自拍 |