基于 Go 的分布式缓存中间件:请求优先命中本地内存,未命中时从数据源加载并写回(旁路缓存模式),支持多节点分布式部署,有效降低数据库访问压力。
- 缓存淘汰:实现 LRU 与 LRU-2 两级淘汰算法,高频访问项自动晋升二级缓存长期保留;LRU-2 按 key 哈希分 16 桶独立加锁,摊薄锁竞争
- 服务发现:基于 etcd 注册发现与租约保活,Watch 监听节点上下线自动更新一致性哈希环,宕机节点靠租约过期自动摘除
- 数据路由:一致性哈希通过虚拟节点路由 key,支持按机器能力静态加权
- 防击穿:SingleFlight 将同一 key 的并发未命中折叠为一次回源
- 节点通信:节点间 gRPC 通信(连接复用),本地 miss 后经一致性哈希路由跨节点取数
- 可扩展:统一 Store 接口 + 工厂模式,可扩展新的淘汰算法
├── cache.go # 缓存封装(统计、初始化、生命周期)
├── group.go # 缓存组(Getter 回源、SingleFlight、Peer 路由)
├── store/ # 淘汰算法:LRU、LRU-2(两级缓存 + 16 段分片锁)
├── consistenthash/ # 一致性哈希(虚拟节点、静态加权)
├── registry/ # etcd 注册与租约保活
├── peers.go # 节点发现与 Peer 选择
├── server.go # gRPC 服务端
├── client.go # gRPC 客户端
├── singleflight/ # 请求合并
├── pb/ # gRPC 协议定义
├── cmd/
│ ├── node/ # 缓存节点入口
│ └── bench/ # 压测工具
└── example/ # 使用示例
- Go 1.22+
- etcd(默认连接
localhost:2379)
E:\etcd\etcd-v3.5.16-windows-amd64\etcd.exe --data-dir E:\etcd\data验证:etcdctl endpoint health 返回 healthy 即可。
每个节点是一个独立进程,启动后通过 etcd 注册(租约 10 秒 + KeepAlive 续租),进程退出时主动注销,节点之间通过一致性哈希路由 + gRPC 互取数据:
go build -o bin\node.exe ./cmd/node
bin\node.exe -addr 127.0.0.1:8010 -node A
bin\node.exe -addr 127.0.0.1:8011 -node B
bin\node.exe -addr 127.0.0.1:8012 -node C# 引擎级 Benchmark(LRU / LRU-2 读命中与写入)
go test ./store -bench . -benchtime=2s -run NONE
# Group 层:本地命中、未命中回源(SingleFlight + getter)
go test . -bench . -benchtime=2s -run NONE
# 端到端压测工具
go build -o bin\bench.exe ./cmd/bench
# 本地命中:预填充 10 万 key,50 并发压测 5 秒
bin\bench.exe -mode local -c 50 -d 5 -keys 100000
# 分布式寻址:3 节点,每个 key 唯一,走"本地 miss → 一致性哈希路由 → gRPC 跨节点取数"全链路
bin\bench.exe -mode dist -c 50 -d 5 -nodes 3参数说明:-c 并发数、-d 压测秒数、-keys 预填充 key 数(local)、-nodes 期望发现节点数(dist)。
本机 i7-13700HX / Go 1.22 / 50 并发 / 5 秒:
| 场景 | QPS | Avg | P50 | P90 | P99 | 成功率 |
|---|---|---|---|---|---|---|
| 单机纯内存命中(local) | 2,255,462 | 0.02 ms | <0.01 ms | <0.01 ms | 1.00 ms | 100% |
| 跨进程 gRPC 分布式寻址(dist,3 节点) | 113,188 | 0.44 ms | 0.52 ms | 0.86 ms | 1.59 ms | 100% |
| 引擎级 LRU2 读命中 | 约 1550 万 ops/s | 64.5 ns/op | — | — | — | — |
| 引擎级 LRU2 写入 | 约 780 万 ops/s | 128.5 ns/op | — | — | — | — |
| Group 未命中回源 | 约 205 万 ops/s | 487 ns/op | — | — | — | — |
数字可在本机直接复现,压测前请先启动 etcd 并等待节点注册完成(dist 模式会自动等待节点发现)。
- 一致性哈希为纯静态虚拟节点(默认每节点 50 个):运行时哈希环绝不变化,避免各节点环不一致导致的跨节点路由成环;按机器能力静态加权可使用
AddWithReplicas(node, replicas)(如 16 核 200 个、4 核 50 个)。 - 分布式寻址链路:本地缓存 miss → 一致性哈希定位归属节点 → 归属其他节点则 gRPC 取数,归属自己则 getter 回源加载并写回。
- 压测中修复的已知问题:lru2 调试打印、两级缓存 L1→L2 淘汰转移(含墓碑过滤)、一致性哈希并发读写 panic 与重平衡死锁、节点自身未入环导致的跨节点路由递归。
MIT License