使用 Golang 实现 etcd / Redis / ZooKeeper 分布式锁, 在本地通过 docker-compose 对比三种锁的性能。
.
├── cmd/
│ └── qps/ # 单客户端 QPS 测试入口
├── internal/
│ └── lock/ # etcd / Redis / ZooKeeper 实现 + 通用接口
├── docker-compose.yml # 本地 3 节点 etcd/Redis/ZooKeeper 集群
├── Makefile
└── README.md
- Go
- Docker
- docker compose
仓库自带的 docker-compose.yml 会启动:
-
三节点 etcd 集群(
2379/22379/32379) -
三个独立 Redis 实例(
6379/6380/6381) -
三节点 ZooKeeper 集群(
12181/12182/12183) -
启动:
docker compose up -d -
停止:
docker compose down
目前仓库提供 单客户端 QPS 测试入口(cmd/qps),用于衡量单个实例在“反复 Acquire→work→Release”场景下的吞吐。命令行/Makefile 会根据锁类型自动选择对应实现:
# etcd(三节点)
go run ./cmd/qps --lock=etcd --duration=60s --endpoints=http://127.0.0.1:2379,http://127.0.0.1:22379,http://127.0.0.1:32379 --ttl=30s --work=0s
make qps-etcd DURATION=60s TTL=30s WORK=0s ENDPOINTS=http://127.0.0.1:2379,http://127.0.0.1:22379,http://127.0.0.1:32379
# Redis(多实例)
go run ./cmd/qps --lock=redis --duration=60s --endpoints=127.0.0.1:6379,127.0.0.1:6380,127.0.0.1:6381 --ttl=10s --work=0s
make qps-redis DURATION=60s TTL=10s WORK=0s REDIS_ENDPOINTS=127.0.0.1:6379,127.0.0.1:6380,127.0.0.1:6381
# ZooKeeper(三节点)
go run ./cmd/qps --lock=zk --duration=60s --endpoints=127.0.0.1:12181,127.0.0.1:12182,127.0.0.1:12183 --ttl=30s --work=0s
make qps-zk DURATION=60s TTL=30s WORK=0s ZK_ENDPOINTS=127.0.0.1:12181,127.0.0.1:12182,127.0.0.1:12183--lock: 指定锁类型,可选etcd、redis、zk--duration: 测试持续时间(默认 5s,运行更长时间可在命令行传参)--timeout: 单次操作的超时时间(默认不限制)--ttl: 锁的租约 TTL(默认 30s)--endpoints: 后端地址列表--work: 持锁期间模拟的工作时间,默认 0s
ttl同时控制 etcd session 续租、Redis 锁过期与 ZooKeeper 临时节点 TTL(通过等待时间体现),需要更长排队时请调大。
常用 make 命令:
# 启动/关闭本地 etcd 集群
make compose-up
make compose-down
# 单客户端 QPS 测试(默认会把所有节点地址串起来)
make qps-etcd DURATION=60s TTL=30s WORK=0s
make qps-redis DURATION=60s TTL=10s WORK=0s
make qps-zk DURATION=60s TTL=30s WORK=0scmd/qps 会实时打印:
- 每秒成功/失败次数与即时 QPS(
[qps] elapsed=...) - 结束时的总尝试次数、成功/失败计数,以及平均 QPS