golang高性能内存缓存插件theine的使用,支持主动TTL过期和泛型

Golang高性能内存缓存插件Theine的使用,支持主动TTL过期和泛型

Theine是一个高性能的内存缓存库,灵感来源于Caffeine,具有以下特点:

  • 高性能
  • 支持泛型
  • 采用自适应W-TinyLFU驱逐策略,实现高命中率
  • 使用分层计时轮自动移除过期数据
  • 简洁的API

安装

go get github.com/Yiling-J/theine-go

基本使用

简单缓存示例

import "github.com/Yiling-J/theine-go"

// 创建缓存客户端,key类型string,value类型string,最大容量1000
client, err := theine.NewBuilder[string, string](1000).Build()
if err != nil {
    panic(err)
}

// 设置缓存值,key="foo", value="bar", cost=1
success := client.Set("foo", "bar", 1)

// 获取缓存值
value, ok := client.Get("foo")

// 设置带TTL的缓存值,1秒后过期
success = client.SetWithTTL("foo", "bar", 1, 1*time.Second)

// 删除缓存
client.Delete("foo")

// 遍历缓存
client.Range(func(key, value string) bool {
    return true // 返回false停止遍历
})

// 获取缓存大小估算
size := client.EstimatedSize()

// 获取缓存统计信息
stats := client.Stats()

// 关闭客户端
client.Close()

加载缓存示例

import "github.com/Yiling-J/theine-go"

// 创建带加载器的缓存
client, err := theine.NewBuilder[string, string](1000).Loading(
    func(ctx context.Context, key string) (theine.Loaded[string], error) {
        return theine.Loaded[string]{Value: key, Cost: 1, TTL: 0}, nil
    },
).Build()
if err != nil {
    panic(err)
}

// 获取值,如果不存在会自动调用加载器
value, err := client.Get(ctx, "foo")

高级配置

builder := theine.NewBuilder[string, string](1000)

// 动态计算cost
builder.Cost(func(v string) int64 {
    return int64(len(v))
})

// 启用entryPool(默认false)
builder.UseEntryPool(true)

// 启用doorkeeper(默认false)
builder.Doorkeeper(true)

// 设置移除监听器
builder.RemovalListener(func(key string, value string, reason theine.RemoveReason) {
    // reason可能是REMOVED/EVICTED/EXPIRED
})

client, err := builder.Build()

缓存持久化

Theine支持将缓存持久化到io.Writer并从io.Reader恢复。使用Gob编码/解码数据,请确保你的key/value可以被Gob正确编码。

// 保存缓存
f, err := os.Create("test")
err := client.SaveCache(0, f)
f.Close()

// 加载缓存
f, err = os.Open("test")
require.Nil(t, err)
newClient, err := theine.NewBuilder[int, int](100).Build()
// 创建客户端后立即加载
err = newClient.LoadCache(0, f)
f.Close()

// 版本检查
err = newClient.LoadCache(1, f)
if err == theine.VersionMismatch {
    // 版本不匹配,忽略加载
} else if err != nil {
    // 处理错误
}

性能基准

Theine在性能测试中表现优异:

吞吐量测试结果(部分)

100%读操作(cpu 32):
BenchmarkCache/zipf_theine_reads=100%,writes=0%-32  118185849 10.45 ns/op 95703790 ops/s

75%读操作(cpu 32):
BenchmarkCache/zipf_theine_reads=75%,writes=25%-32  75969892 15.53 ns/op 64394679 ops/s

100%写操作(cpu 32):
BenchmarkCache/zipf_theine_reads=0%,writes=100%-32  1953358 526.1 ns/op 1900935 ops/s

内存分配(100%写操作)

BenchmarkCache/zipf_theine_reads=0%,writes=100%-32  0 B/op 0 allocs/op

二级缓存(实验性功能)

Theine支持二级缓存接口,可以将数据缓存在非易失性介质或其他形式的缓存中。

type SecondaryCache[K comparable, V any] interface {
    Get(key K) (value V, cost int64, expire int64, ok bool, err error)
    Set(key K, value V, cost int64, expire int64) error
    Delete(key K) error
    HandleAsyncError(err error)
}

目前有一个基于NVM的实现:theine-nvm

注意事项

  1. 持久化缓存时,请确保在创建客户端后立即加载
  2. 版本号在保存和加载时必须相同
  3. 二级缓存目前不支持Range/Len API
  4. 移除监听器只接收REMOVED事件(显式删除)

Theine是一个功能强大且高性能的Go缓存库,特别适合需要高吞吐量和低延迟的应用场景。


更多关于golang高性能内存缓存插件theine的使用,支持主动TTL过期和泛型的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang高性能内存缓存插件theine的使用,支持主动TTL过期和泛型的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang高性能内存缓存插件Theine的使用指南

Theine是一个高性能的Go内存缓存库,支持主动TTL过期和泛型特性。下面我将详细介绍它的使用方法和示例代码。

Theine的主要特性

  1. 支持泛型,可以缓存任意类型
  2. 支持主动TTL过期机制
  3. 高性能,基于高效的数据结构
  4. 支持多种淘汰策略
  5. 线程安全

安装Theine

go get github.com/Yiling-J/theine-go

基本使用示例

1. 创建缓存实例

package main

import (
	"fmt"
	"time"
	
	"github.com/Yiling-J/theine-go"
)

func main() {
	// 创建一个缓存实例,指定key类型为string,value类型为int
	// 10000是最大容量
	cache, err := theine.NewBuilder[string, int](10000).Build()
	if err != nil {
		panic(err)
	}
	
	// 设置缓存值,无TTL
	cache.Set("key1", 42, 0)
	
	// 获取缓存值
	value, ok := cache.Get("key1")
	if ok {
		fmt.Println("Value:", value) // 输出: Value: 42
	}
}

2. 使用TTL过期

func main() {
	cache, err := theine.NewBuilder[string, string](10000).Build()
	if err != nil {
		panic(err)
	}
	
	// 设置缓存值,5秒后过期
	cache.Set("key2", "hello", 5*time.Second)
	
	// 立即获取
	value, ok := cache.Get("key2")
	if ok {
		fmt.Println("Value:", value) // 输出: Value: hello
	}
	
	// 等待6秒后
	time.Sleep(6 * time.Second)
	
	// 再次获取
	value, ok = cache.Get("key2")
	if !ok {
		fmt.Println("Key expired") // 输出: Key expired
	}
}

3. 使用泛型支持不同类型

type User struct {
	Name string
	Age  int
}

func main() {
	// 创建缓存,key为string,value为User结构体
	cache, err := theine.NewBuilder[string, User](10000).Build()
	if err != nil {
		panic(err)
	}
	
	user := User{Name: "Alice", Age: 30}
	cache.Set("user1", user, 0)
	
	if value, ok := cache.Get("user1"); ok {
		fmt.Printf("User: %+v\n", value) // 输出: User: {Name:Alice Age:30}
	}
}

4. 高级配置

func main() {
	// 使用Builder进行高级配置
	cache, err := theine.NewBuilder[string, int](10000).
		// 设置淘汰策略为LFU(最近最少使用)
		WithLfu().
		// 设置并发级别
		WithCounter(32).
		// 设置TTL检查间隔
		WithTtlInterval(10 * time.Second).
		Build()
	
	if err != nil {
		panic(err)
	}
	
	// 使用缓存...
}

5. 批量操作

func main() {
	cache, err := theine.NewBuilder[string, int](10000).Build()
	if err != nil {
		panic(err)
	}
	
	// 批量设置
	items := map[string]int{
		"key1": 1,
		"key2": 2,
		"key3": 3,
	}
	cache.SetAll(items, 0)
	
	// 批量获取
	keys := []string{"key1", "key2", "key3"}
	results := cache.GetAll(keys)
	for k, v := range results {
		fmt.Printf("Key: %s, Value: %d\n", k, v)
	}
	
	// 删除多个key
	cache.DeleteAll([]string{"key1", "key2"})
}

性能优化建议

  1. 根据实际场景选择合适的容量大小
  2. 对于高并发场景,适当增加并发级别
  3. 合理设置TTL检查间隔,平衡精度和性能
  4. 根据访问模式选择合适的淘汰策略(LFU/LRU)

注意事项

  1. Theine目前不支持持久化功能
  2. 当缓存达到容量上限时,会根据淘汰策略移除部分数据
  3. TTL过期是主动检查机制,不是精确到毫秒的

Theine是一个简单高效的Go内存缓存解决方案,特别适合需要高性能和泛型支持的场景。通过合理配置,可以在大多数内存缓存需求中提供出色的性能表现。

回到顶部