背景

ristrettodgraphdgraphristretto
groupcachebigcachefastcacheristretto

ristretto 简介

ristretto
  • 高命中率 - 特殊设计的录入/驱逐政策

    • 驱逐(SampledLFU):与精确 LRU 相当,但在搜索和数据跟踪上有更好的性能

    • 录入(TinyLFU):以极小的内存开销获取额外的性能提升

  • 高吞吐率

  • 权重感知的驱逐策略 - 价值权重大的条目可以驱逐多个价值权重小的条目

    • 依托权重可以扩展出缓存最大内存占用、缓存最多条目数等场景

  • 完全并发支持

  • 性能指标 - 吞吐量、命中率及其他统计数据的性能指标

  • 用户友好的 API 设计

    • 支持指定缓存失效时间

ristretto

ristretto 使用举例

构建大小(条目数)受限的缓存

ristretto
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)
}

运行代码可以发现最后只有 10 个条目还保存在缓存中

$ go run main.go
10 of 20 item missed
IgnoreInternalCosttrue

测试缓存过期时间

还是创建一个简单的缓存,然后存一个过期时间为 1 秒的条目进去,看看接下来的缓存读写表现:

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)
 }
}

运行代码可以发现已过期的条目被正常清除出了缓存

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

总结

ristrettoristrettoCaffeine

大家赶快试试吧!

参考资料

  • 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同学,最近我们社区打算推出一个类似GoCN每日新闻的新栏目《酷Go推荐》,主要是每周推荐一个库或者好的项目,然后写一点这个库使用方法或者优点之类的,这样可以真正的帮助到大家能够学习到

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

大概规则和每日新闻类似,如果报名人多的话每个人一个月轮到一次,欢迎大家报名!戳「阅读原文」,即可报名

扫码也可以加入 GoCN 的大家族哟~