golang高性能内存键值存储与指针缓存插件库go-mcache的使用
Golang高性能内存键值存储与指针缓存插件库go-mcache的使用
简介
go-mcache是一个高性能、线程安全的内存键值缓存库,支持过期时间和最小GC压力。
特性
- 分片存储:256个可配置分片,减少锁竞争并支持水平扩展
- 单一过期调度器:使用一个后台goroutine和最小堆处理所有TTL,避免每个键使用定时器
- 零分配热路径:使用池化条目和直接值存储,避免反射并减少GC压力
- 原子计数器:O(1)复杂度获取长度,无需遍历分片
- 标准接口:可作为
map[string]interface{}
的替代品,提供以下方法:Set(key string, value interface{}, ttl time.Duration) error
Get(key string) (value interface{}, ok bool)
Delete(key string)
Len() int
Close() map[string]interface{}
- 优雅关闭:
Close
方法会停止过期调度器并返回剩余条目 - 自定义选项:
WithShardCount(n int)
调整分片数量(必须是2的幂)WithPollInterval(d time.Duration)
设置GC轮询间隔
- 全面的测试和基准测试:内置线程安全测试和微基准测试用于吞吐量分析
安装
go get -u github.com/OrlovEvgeny/go-mcache
使用示例
package main
import (
"fmt"
"log"
"time"
"github.com/OrlovEvgeny/go-mcache"
)
type User struct {
Name string
Age int
}
func main() {
// 创建默认配置的缓存(256分片)
cache := mcache.New()
defer func() {
// 停止内部调度器并获取剩余条目
items := cache.Close()
fmt.Printf("Remaining entries: %d\n", len(items))
}()
// 存储一个结构体指针,TTL为20分钟
key := "user:123"
user := &User{Name: "Alice", Age: 30}
if err := cache.Set(key, user, 20*time.Minute); err != nil {
log.Fatalf("Set error: %v", err)
}
// 获取值
if v, ok := cache.Get(key); ok {
loaded := v.(*User)
fmt.Printf("Loaded user: %s (age %d)\n", loaded.Name, loaded.Age)
} else {
fmt.Println("Key expired or not found")
}
// 删除条目
cache.Delete(key)
}
高级配置
// 512分片和30秒GC间隔
cache := mcache.New(
mcache.WithShardCount(512),
mcache.WithPollInterval(30*time.Second),
)
基准测试
运行基准测试命令:
go test -bench . -benchmem
Apple M1 Pro上的典型结果:
goos: darwin
goarch: arm64
pkg: github.com/OrlovEvgeny/go-mcache
cpu: Apple M1 Pro
BenchmarkCacheOperations
BenchmarkCacheOperations/Write
BenchmarkCacheOperations/Write-8 1836590 663.0 ns/op 605 B/op 3 allocs/op
BenchmarkCacheOperations/Read
BenchmarkCacheOperations/Read-8 6350031 167.5 ns/op 85 B/op 1 allocs/op
BenchmarkCacheOperations/WriteRead
BenchmarkCacheOperations/WriteRead-8 1786278 704.6 ns/op 665 B/op 4 allocs/op
BenchmarkCacheOperations/ParallelReadWrite
BenchmarkCacheOperations/ParallelReadWrite-8 4477581 288.0 ns/op 227 B/op 5 allocs/op
贡献
欢迎贡献代码!请fork项目,改进后提交pull request。确保新代码包含测试并遵循Go标准(go fmt, go vet)。
许可证
本项目采用MIT许可证。
更多关于golang高性能内存键值存储与指针缓存插件库go-mcache的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang高性能内存键值存储与指针缓存插件库go-mcache的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Go-MCache:高性能内存键值存储与指针缓存库
Go-MCache 是一个高性能的 Golang 内存键值存储库,特别适合需要快速访问缓存数据的场景。它提供了类似 Redis 的接口但完全在内存中运行,避免了网络开销。
主要特性
- 极高性能:基于哈希表实现,O(1)时间复杂度
- 内存高效:自动过期和内存回收机制
- 并发安全:内置读写锁,支持高并发
- 丰富API:支持设置过期时间、批量操作等
基本使用
首先安装 go-mcache:
go get github.com/OrlovEvgeny/go-mcache
基础示例
package main
import (
"fmt"
"time"
"github.com/OrlovEvgeny/go-mcache"
)
func main() {
// 创建缓存实例
cache := mcache.New()
// 设置键值对,不带过期时间
cache.Set("username", "john_doe")
// 设置带过期时间的键值对(10秒后过期)
cache.SetEx("session_token", "abc123", 10*time.Second)
// 获取值
if value, ok := cache.Get("username"); ok {
fmt.Println("Username:", value) // 输出: Username: john_doe
}
// 检查键是否存在
if cache.Has("session_token") {
fmt.Println("Session token exists")
}
// 删除键
cache.Delete("username")
// 等待过期
time.Sleep(11 * time.Second)
if !cache.Has("session_token") {
fmt.Println("Session token has expired")
}
}
高级功能
指针缓存
Go-MCache 特别适合缓存指针类型,避免值拷贝:
type User struct {
ID int
Username string
Email string
}
func main() {
cache := mcache.New()
user := &User{
ID: 1,
Username: "johndoe",
Email: "john@example.com",
}
// 存储指针
cache.Set("user:1", user)
// 获取指针
if val, ok := cache.Get("user:1"); ok {
retrievedUser := val.(*User)
fmt.Printf("User: %+v\n", retrievedUser)
}
}
批量操作
func main() {
cache := mcache.New()
// 批量设置
items := map[string]interface{}{
"key1": "value1",
"key2": "value2",
"key3": "value3",
}
cache.MSet(items)
// 批量获取
keys := []string{"key1", "key2", "key3"}
values := cache.MGet(keys...)
for i, key := range keys {
if val, ok := values[i]; ok {
fmt.Printf("%s: %v\n", key, val)
}
}
}
自动删除回调
func main() {
cache := mcache.New()
// 设置删除回调函数
cache.SetOnDeletedCallback(func(key string, value interface{}) {
fmt.Printf("Key %s with value %v was deleted\n", key, value)
})
cache.SetEx("temp_data", "some value", 2*time.Second)
time.Sleep(3 * time.Second) // 等待过期触发回调
}
性能优化建议
- 合理设置过期时间:避免内存无限增长
- 批量操作:减少锁竞争
- 指针存储:对于大型结构体,存储指针而非值
- 避免频繁创建/销毁:重用缓存实例
与标准库 sync.Map 对比
特性 | go-mcache | sync.Map |
---|---|---|
过期时间支持 | ✓ | ✗ |
内存回收 | ✓ | ✗ |
回调通知 | ✓ | ✗ |
原生Go实现 | ✓ | ✓ |
批量操作 | ✓ | ✗ |
适用场景
- Web 会话存储
- API 响应缓存
- 频繁访问的配置数据
- 临时计算结果的缓存
Go-MCache 通过其简单而强大的 API 为 Golang 应用程序提供了高效的内存缓存解决方案,特别适合需要快速键值访问的中小型数据缓存场景。