Go --- GCache缓存官方例子

简介: Go --- GCache缓存官方例子

Github:https://github.com/bluele/gcache

介绍

为 Golang 打造的缓存库。 它支持可预期的 Cache,LFU,LRU 和 ARC。

功能

  • 支持可预见的 Cache,LFU,LRU 和 ARC。
  • Goroutine 安全
  • 支持驱逐,清除和添加条目的事件处理程序。 (可选)
  • 如果缓存不存在,则自动加载缓存。 (可选)

安装

$ go get github.com/bluele/gcache
• 1

例子

  1. 手工配置键值对
package main
import (
   "fmt"
   "github.com/bluele/gcache"
)
func main() {
     // size为设置的每小时的字节数,单位是 MB
  // func New(size int) *CacheBuilder {
  //  return &CacheBuilder{
  //    clock: NewRealClock(),
  //    tp:    TYPE_SIMPLE,
  //    size:  size,
  //  }
  // }
   gc := gcache.New(20).
      LRU().
      Build()
   gc.Set("key", "你好")
   value, err := gc.Get("key")
   if err != nil {
      panic(err)
   }
   fmt.Println("Get:", value)
}
  1. 手动设置具有过期时间的键值对。
package main
import (
   "fmt"
   "github.com/bluele/gcache"
   "log"
   "time"
)
func main() {
   gc := gcache.New(20).
      LRU().
      Build()
   // 设置并带上过期时间
   gc.SetWithExpire("key", "ok", time.Second*10)
   value, _ := gc.Get("key")
   fmt.Println("Get:", value)
   // 等待值过期
   time.Sleep(time.Second*10)
   value, err := gc.Get("key")
   if err != nil {
      // Key not found.
      log.Println(err)
   }
   fmt.Println("Get:", value)
}
  1. 自动负载值
package main
import (
   "fmt"
   "github.com/bluele/gcache"
   "time"
)
func main() {
   gc := gcache.New(20).
      LRU().
      // loaderFunc:当缓存值过期时,使用此函数创建一个新值。
      LoaderFunc(func(key interface{}) (interface{}, error) {
         return "默认值", nil
      }).
      Build()
   value1, err := gc.Get("张三")
   if err != nil {
      panic(err)
   }
   value2, err := gc.Get("李四")
   if err != nil {
      panic(err)
   }
   fmt.Println("张三:", value1)
   fmt.Println("李四:", value2)
   _ = gc.SetWithExpire("王五", "虽然可以修改", 5*time.Second)
   value3, err := gc.Get("王五")
   if err != nil {
      panic(err)
   }
   fmt.Print("王五:", value3)
   time.Sleep(5*time.Second)
   value4, err := gc.Get("王五")
   if err != nil {
      panic(err)
   }
   fmt.Println(" 但是过期了重新赋为", value4)
}
  1. 自动加载值与到期时间
package main
import (
   "fmt"
   "time"
   "github.com/bluele/gcache"
)
func main() {
   var evictCounter, loaderCounter, purgeCounter int
   gc := gcache.New(20).
      LRU().
      // loaderExpireFunc:当缓存值过期时,使用此函数创建一个新值。
      // 如果*time.Duration返回nil而不是时间。loaderExpireFunc比value的持续时间永远不会过期。
      LoaderExpireFunc(func(key interface{}) (interface{}, *time.Duration, error) {
         loaderCounter++
         expire := 1 * time.Second
         // return interface{}, *time.Duration, error
         return "好好吃饭", &expire, nil
      }).
      // 如果有新的键和老的键冲突了,那么将会驱逐老的键
      EvictedFunc(func(key, value interface{}) {
         evictCounter++
         fmt.Println("evicted key:", key)
      }).
      PurgeVisitorFunc(func(key, value interface{}) {
         purgeCounter++
      fmt.Println("purged key:", key)
      }).
      Build()
   value, err := gc.Get("规律作息")
   if err != nil {
      panic(err)
   }
   fmt.Println("规律作息:", value)
   time.Sleep(1 * time.Second)
   value, err = gc.Get("规律作息")
   if err != nil {
      panic(err)
   }
   fmt.Println("规律作息:", value)
   // 手动配置键值对
   _ = gc.Set("麦", "当")
   value, err = gc.Get("麦")
   if err != nil {
      panic(err)
   }
   fmt.Println("麦:", value)
   // 清理缓存
   gc.Purge()
   // 因为我们手动配置了键值对,所以将会执行下方的panic
   if loaderCounter != evictCounter+purgeCounter {
      fmt.Println("负载计数器:",loaderCounter)
      fmt.Println("驱逐计数器:",evictCounter)
      fmt.Println("清除计数器:",purgeCounter)
      panic("bad")
   }
}

缓存算法说明

  1. Least-Frequently Used (LFU)
    使用次数最少,首先丢弃最不常用的缓存。
func main() {
  // size: 10
  gc := gcache.New(10).
    LFU().
    Build()
  gc.Set("key", "value")
}
  1. Least Recently Used (LRU)
    最近最少使用,最先丢弃最近最少使用的物品。
func main() {
  // size: 10
  gc := gcache.New(10).
    LRU().
    Build()
  gc.Set("key", "value")
}
  1. daptive Replacement Cache (ARC)
    自适应替换缓存,不断平衡LRU和LFU,提高组合效果。
    详细情况参考: http://en.wikipedia.org/wiki/Adaptive_replacement_cache
func main() {
  gc := gcache.New(10).
    ARC().
    Build()
  gc.Set("key", "value")
}
  1. SimpleCache (Default)
    SimpleCache没有明确的退出缓存优先级。它取决于键-值映射顺序。
func main() {
  gc := gcache.New(10).Build()
  gc.Set("key", "value")
  v, err := gc.Get("key")
  if err != nil {
    panic(err)
  }
}

加载缓存

如果指定了LoaderFunc,值将由缓存自动加载,并存储在缓存中,直到驱逐或手动失效。

func main() {
  gc := gcache.New(10).
    LRU().
    LoaderFunc(func(key interface{}) (interface{}, error) {
      return "value", nil
    }).
    Build()
  v, _ := gc.Get("key")
  fmt.Println(v)
}

GCache协调缓存填充,使整个复制的进程集中的一个进程中只有一个加载填充缓存,然后将加载的值复用给所有调用者。

为缓存设置过期时间

func main() {
  // LRU 缓存, 大小:10MB, 过期时间: 一小时后
  gc := gcache.New(10).
    LRU().
    Expiration(time.Hour).
    Build()
}

事件处理程序

  1. 被驱逐的处理程序
    事件处理程序,用于驱逐条目。驱逐条目时执行该函数。
func main() {
  gc := gcache.New(2).
    EvictedFunc(func(key, value interface{}) {
      fmt.Println("evicted key:", key)
    }).
    Build()
  for i := 0; i < 3; i++ {
    gc.Set(i, i*i)
  }
}
  1. 添加处理程序
    事件处理程序,用于添加条目。添加条目时执行该函数。
func main() {
  gc := gcache.New(2).
    AddedFunc(func(key, value interface{}) {
      fmt.Println("added key:", key)
    }).
    Build()
  for i := 0; i < 3; i++ {
    gc.Set(i, i*i)
  }
}


相关文章
|
7月前
|
存储 缓存 安全
Go 简单设计和实现可扩展、高性能的泛型本地缓存
本文将会探讨如何极简设计并实现一个可扩展、高性能的本地缓存。支持多样化的缓存策略,例如 最近最少使用(LRU)等。
107 0
Go 简单设计和实现可扩展、高性能的泛型本地缓存
|
7月前
|
缓存 Go API
Go 实现一个支持多种过期、淘汰机制的本地缓存的核心原理
本文旨在探讨实现一个支持多种 过期、淘汰 机制的 go 本地缓存的核心原理,我将重点讲解如何支持多样化的过期和淘汰策略。
169 0
|
存储 缓存 Go
Go语言开发者必读:内存缓存技巧
Go语言开发者必读:内存缓存技巧
133 0
|
7月前
|
存储 缓存 NoSQL
【Go语言专栏】Go语言中的Redis操作与缓存应用
【4月更文挑战第30天】本文探讨了在Go语言中使用Redis进行操作和缓存应用的方法。文章介绍了Redis作为高性能键值存储系统,用于提升应用性能。推荐使用`go-redis/redis`库,示例代码展示了连接、设置、获取和删除键值对的基本操作。文章还详细阐述了缓存应用的步骤及常见缓存策略,包括缓存穿透、缓存击穿和缓存雪崩的解决方案。利用Redis和合适策略可有效优化应用性能。
149 0
|
4月前
|
缓存 NoSQL 数据库
go-zero微服务实战系列(五、缓存代码怎么写)
go-zero微服务实战系列(五、缓存代码怎么写)
|
4月前
|
存储 缓存 NoSQL
在 Go 中使用接口进行灵活缓存
在 Go 中使用接口进行灵活缓存
|
4月前
|
缓存 编解码 测试技术
使用Go实现健壮的内存型缓存
使用Go实现健壮的内存型缓存
72 2
|
4月前
|
消息中间件 缓存 监控
go-zero微服务实战系列(六、缓存一致性保证)
go-zero微服务实战系列(六、缓存一致性保证)
|
4月前
|
缓存 监控 Go
[go 面试] 缓存策略与应对数据库压力的良方
[go 面试] 缓存策略与应对数据库压力的良方
|
6月前
|
缓存 安全 算法
Go 中使用 map 实现高效的数据缓存
Go 中使用 map 实现高效的数据缓存