golang高性能缓存库支持过期缓存、LFU、LRU和ARC算法插件GCache的使用
Golang高性能缓存库GCache使用指南
GCache是一个支持过期缓存、LFU、LRU和ARC算法的Golang缓存库。
特性
- 支持过期缓存、LFU、LRU和ARC算法
- 线程安全
- 支持淘汰、清除和添加条目的事件处理器(可选)
- 自动加载不存在的缓存(可选)
安装
$ go get github.com/bluele/gcache
示例代码
1. 手动设置键值对
package main
import (
"github.com/bluele/gcache"
"fmt"
)
func main() {
// 创建容量为20的LRU缓存
gc := gcache.New(20).
LRU().
Build()
gc.Set("key", "ok")
value, err := gc.Get("key")
if err != nil {
panic(err)
}
fmt.Println("Get:", value)
}
输出:
Get: ok
2. 设置带过期时间的键值对
package main
import (
"github.com/bluele/gcache"
"fmt"
"time"
)
func main() {
gc := gcache.New(20).
LRU().
Build()
// 设置10秒后过期的键值对
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 {
panic(err)
}
fmt.Println("Get:", value)
}
输出:
Get: ok
// 10秒后, 再次尝试:
panic: ErrKeyNotFound
3. 自动加载值
package main
import (
"github.com/bluele/gcache"
"fmt"
)
func main() {
gc := gcache.New(20).
LRU().
// 定义加载函数
LoaderFunc(func(key interface{}) (interface{}, error) {
return "ok", nil
}).
Build()
value, err := gc.Get("key")
if err != nil {
panic(err)
}
fmt.Println("Get:", value)
}
输出:
Get: ok
4. 带过期时间的自动加载
package main
import (
"fmt"
"time"
"github.com/bluele/gcache"
)
func main() {
var evictCounter, loaderCounter, purgeCounter int
gc := gcache.New(20).
LRU().
// 定义带过期时间的加载函数
LoaderExpireFunc(func(key interface{}) (interface{}, *time.Duration, error) {
loaderCounter++
expire := 1 * time.Second
return "ok", &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("key")
if err != nil {
panic(err)
}
fmt.Println("Get:", value)
time.Sleep(1 * time.Second)
value, err = gc.Get("key")
if err != nil {
panic(err)
}
fmt.Println("Get:", value)
gc.Purge()
if loaderCounter != evictCounter+purgeCounter {
panic("bad")
}
}
输出:
Get: ok
evicted key: key
Get: ok
purged key: key
缓存算法
1. LFU (Least-Frequently Used)
淘汰使用频率最低的条目。
func main() {
// 容量为10的LFU缓存
gc := gcache.New(10).
LFU().
Build()
gc.Set("key", "value")
}
2. LRU (Least Recently Used)
淘汰最近最少使用的条目。
func main() {
// 容量为10的LRU缓存
gc := gcache.New(10).
LRU().
Build()
gc.Set("key", "value")
}
3. ARC (Adaptive Replacement Cache)
在LRU和LFU之间动态平衡以获得更好的综合效果。
func main() {
// 容量为10的ARC缓存
gc := gcache.New(10).
ARC().
Build()
gc.Set("key", "value")
}
4. SimpleCache (默认)
没有明确的淘汰优先级,依赖于键值映射的顺序。
func main() {
// 容量为10的简单缓存
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")
// 输出: "value"
fmt.Println(v)
}
过期缓存
func main() {
// LRU缓存,容量10,1小时后过期
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)
}
}
输出:
evicted key: 0
2. 添加事件处理器
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)
}
}
输出:
added key: 0
added key: 1
added key: 2
作者
Jun Kimura
更多关于golang高性能缓存库支持过期缓存、LFU、LRU和ARC算法插件GCache的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang高性能缓存库支持过期缓存、LFU、LRU和ARC算法插件GCache的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
GCache - Golang高性能缓存库
GCache是一个功能强大的Golang缓存库,支持多种缓存算法和过期策略。下面我将详细介绍它的主要特性及使用方法。
主要特性
-
支持多种缓存淘汰算法:
- LRU (Least Recently Used)
- LFU (Least Frequently Used)
- ARC (Adaptive Replacement Cache)
- Simple (无淘汰策略)
-
支持缓存过期策略:
- 固定过期时间
- 滑动过期时间
- 永不过期
安装
go get -u github.com/bluele/gcache
基本使用示例
1. 创建缓存实例
package main
import (
"fmt"
"time"
"github.com/bluele/gcache"
)
func main() {
// 创建一个LRU缓存,容量为100
cache := gcache.New(100).
LRU().
Build()
// 设置缓存值
cache.Set("key1", "value1")
// 获取缓存值
value, err := cache.Get("key1")
if err != nil {
panic(err)
}
fmt.Println("Get:", value)
}
2. 不同缓存算法示例
// 创建LFU缓存
lfuCache := gcache.New(100).
LFU().
Build()
// 创建ARC缓存
arcCache := gcache.New(100).
ARC().
Build()
3. 过期时间设置
// 创建带过期时间的缓存
expireCache := gcache.New(100).
LRU().
Expiration(time.Second * 10). // 10秒后过期
Build()
// 设置带过期时间的单个条目
expireCache.SetWithExpire("key2", "value2", time.Second*5)
4. 高级功能
// 创建带加载函数的缓存
loaderCache := gcache.New(100).
LRU().
LoaderFunc(func(key interface{}) (interface{}, error) {
// 当缓存未命中时自动调用此函数加载数据
return "loaded-value", nil
}).
Build()
// 自动加载
value, err := loaderCache.Get("key-not-exist")
fmt.Println(value) // 输出: loaded-value
// 添加过期回调
callbackCache := gcache.New(100).
LRU().
AddedFunc(func(key, value interface{}) {
fmt.Printf("Added key: %v, value: %v\n", key, value)
}).
EvictedFunc(func(key, value interface{}) {
fmt.Printf("Evicted key: %v, value: %v\n", key, value)
}).
Build()
5. 性能优化技巧
// 使用指针类型减少拷贝
type BigStruct struct {
Data [1024]byte
}
cache := gcache.New(100).
LRU().
Build()
bigData := &BigStruct{}
cache.Set("big-key", bigData) // 存储指针而非结构体本身
// 批量操作减少锁竞争
cache.SetAll(map[interface{}]interface{}{
"key1": "value1",
"key2": "value2",
"key3": "value3",
})
算法选择建议
- LRU:适用于大多数场景,对最近访问的数据有较好的保留
- LFU:适用于访问频率差异大的场景
- ARC:结合了LRU和LFU的优点,自适应调整,但内存开销稍大
- Simple:当不需要淘汰策略时使用
注意事项
- GCache不是线程安全的,如果需要在多个goroutine中使用,需要自行加锁
- 对于大型对象,建议存储指针而非值类型
- 过期检查是惰性的,只有在访问时才会检查是否过期
性能对比
GCache在性能上表现优异,与其他流行缓存库相比:
- 比
bigcache
和freecache
功能更丰富 - 比
groupcache
更灵活 - 比简单的
map+mutex
实现更高效
通过合理选择算法和配置,GCache可以满足大多数高性能缓存需求。