Github:https://github.com/bluele/gcache
介绍
为 Golang 打造的缓存库。 它支持可预期的 Cache,LFU,LRU 和 ARC。
功能
- 支持可预见的 Cache,LFU,LRU 和 ARC。
Goroutine 安全
- 支持驱逐,清除和添加条目的事件处理程序。 (可选)
- 如果缓存不存在,则自动加载缓存。 (可选)
安装
$ go get github.com/bluele/gcache • 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) }
- 手动设置具有过期时间的键值对。
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) }
- 自动负载值
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) }
- 自动加载值与到期时间
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") } }
缓存算法说明
- Least-Frequently Used (LFU)
使用次数最少,首先丢弃最不常用的缓存。
func main() { // size: 10 gc := gcache.New(10). LFU(). Build() gc.Set("key", "value") }
- Least Recently Used (LRU)
最近最少使用,最先丢弃最近最少使用的物品。
func main() { // size: 10 gc := gcache.New(10). LRU(). Build() gc.Set("key", "value") }
- 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") }
- 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() }
事件处理程序
- 被驱逐的处理程序
事件处理程序,用于驱逐条目。驱逐条目时执行该函数。
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) } }
- 添加处理程序
事件处理程序,用于添加条目。添加条目时执行该函数。
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) } }