nerdsane/redis-rust
GitHub: nerdsane/redis-rust
这是一个用 Rust 编写的实验性 Redis 兼容内存数据存储,具备基于 CRDT 的多节点复制和确定性仿真测试能力。
Stars: 46 | Forks: 17
[](https://github.com/nerdsane/redis-rust/actions/workflows/ci.yml)
[](LICENSE)
[](https://www.rust-lang.org/)
[](#what-works)
[](#replication)
# redis-rust
一个用 Rust 编写的实验性、兼容 Redis 的内存数据存储,具有基于 CRDT 的多节点复制。由 [Claude Code](https://claude.ai/claude-code) (Opus 4.5 → Opus 4.6) 共同编写,作为 [AI-Driven Research for Systems](https://adrs-ucb.notion.site/datadog) (ADRS) 的练习。另请参阅:[BitsEvolve](https://www.datadoghq.com/blog/engineering/self-optimizing-system/) 了解生产环境感知的自优化系统。阅读 [完整论文](docs/PAPER.md) 了解架构、验证方法和经验教训。
## 已实现功能
**75+ Redis 命令**,涵盖字符串、列表、集合、哈希、有序集合、事务、过期、Lua 脚本和服务器内省。兼容 RESP2 线路协议,适用于所有标准 Redis 客户端。
**Tcl 兼容性测试结果**(官方 Redis 测试套件):
| 测试套件 | 结果 |
|-------|--------|
| `unit/type/incr` | **28/28 通过** |
| `unit/expire` | **全部通过** |
| `unit/type/string` | **72 通过,0 错误** (止于 LCS - 未实现) |
| `unit/multi` | 20/56 通过 (止于 SWAPDB - 未实现数据库交换) |
**性能**(Docker,2 CPUs,1GB RAM,50 客户端,`redis-benchmark`):
| | Redis 7.4 | redis-rust | |
|---|-----------|------------|---|
| SET P=1 | 148K rps | 147K rps | 99% |
| GET P=1 | 154K rps | 119K rps | 77% |
| SET P=16 | 1.02M rps | 813K rps | 80% |
| GET P=16 | 840K rps | 709K rps | 84% |
最佳分片数取决于可用核心数。使用 2 CPUs 时,2-4 个分片在流水线模式下峰值可达约 1M SET/s。
## 未实现功能
- **不支持 bitmap、stream、pub/sub、HyperLogLog 或 geo 命令。**
- **不支持阻塞操作**(BLPOP、BRPOP 等)。
- **不支持 RESP3。** 仅支持 RESP2。
- **无持久化保证。** 仅内存模式。流式持久化到 S3 的功能已存在但处于实验阶段。
- **多节点复制仅支持最终一致性。** 基于 CRDT(LWW 寄存器、向量时钟、gossip)。通过 Maelstrom 和 87 个确定性模拟测试(注入分区/丢失)进行了验证。设计上跨节点不可线性化。
- **MULTI/EXEC 可用但存在限制。** 事务状态在连接级别跟踪。WATCH 使用值快照比较,而非 Redis 的内部脏键跟踪。
## 快速开始
```
# 构建并运行
cargo run --bin redis-server-optimized --release
# 使用任意 Redis 客户端连接
redis-cli -p 6379
```
默认端口为 6379(标准 Redis 端口)。可通过 `REDIS_PORT=3000` 覆盖。
## 测试
完整的验证指南请参阅 [docs/HARNESS.md](docs/HARNESS.md) —— 包括每一层测试的内容、预期输出、陷阱以及如何在不破坏现有功能的情况下添加新命令。
```
# 单元测试(507 个测试,包括 87 个复制测试)
cargo test --lib
# CRDT 收敛测试(100 个 seeds、分区、丢包)
cargo test crdt_dst --lib
cargo test multi_node --lib
# Tcl 兼容性(需要 git submodule)
git submodule update --init
./scripts/run-redis-compat.sh
# Maelstrom 线性一致性(需要 Java 11+)
cargo build --release --bin maelstrom-kv-replicated
/opt/homebrew/opt/openjdk@17/bin/java -Djava.awt.headless=true \
-jar maelstrom/maelstrom/lib/maelstrom.jar test -w lin-kv \
--bin ./target/release/maelstrom-kv-replicated \
--node-count 5 --time-limit 30 --concurrency 10 --rate 50
# Docker 基准测试
cd docker-benchmark && ./run-benchmarks.sh
```
## 架构
每个分片对应一个 Actor 的设计。每个分片都是一个独立的 tokio task,拥有其 `CommandExecutor`。无锁 —— 所有通信通过 `mpsc` 通道进行。连接处理器解析 RESP,通过键哈希路由到正确的分片,并等待响应。
```
Connections ──> [RESP Parser] ──> hash(key) ──> [Shard Actor 0..N] ──> [CommandExecutor]
```
分片数量可通过 `perf_config.toml` 配置。事务状态(MULTI/EXEC/WATCH)位于连接级别而非分片级别,因此事务可以跨分片正常工作。
## 复制
采用 Anna KVS 风格的 CRDT 复制和 gossip 协议。每个节点维护带有 Lamport 时钟的 LWW 寄存器。CRDT 合并属性(可交换、可结合、幂等)保证收敛 —— 通过 Stateright 穷举模型检查和 100 种种子的确定性模拟(包含网络分区和消息丢失)进行验证。
```
Node 1 Node 2 Node 3
| | |
[LWW Register] <--Gossip--> [LWW Register] <--Gossip--> [LWW Register]
| | |
[Vector Clock] [Vector Clock] [Vector Clock]
```
组件:`src/replication/` (CRDTs、gossip、反熵、哈希环)、`src/production/replicated_shard_actor.rs` (基于 actor 的复制)、`src/bin/maelstrom_kv_replicated.rs` (多节点概念验证)。
**一致性模型:** 最终一致性 (LWW) 或 因果一致性 (向量时钟)。跨节点不可线性化。单节点操作可线性化。
**Maelstrom/Jepsen 结果**(Knossos 线性化检查器):
| 节点数 | 操作数 | 读取 | 写入 | CAS | 线性化 | 异常 |
|-------|-----------|-------|--------|-----|-------------|-----------|
| 1 | ~150 | 全部正常 | 全部正常 | 全部正常 | **有效** | 0 |
| 3 | 190 | 98/98 正常 | 29/29 正常 | 13/63 正常 | **有效** | 0 |
| 5 | 1,301 | 670/677 正常 | 201/201 正常 | 80/423 正常 | **有效** | 0 |
CAS 失败率是预期的 —— 最终一致性意味着 CAS 经常会看到陈旧值。在低负载下,Knossos 会发现有效的线性化顺序,因为 gossip 收敛很快。在高负载或慢速 CI 运行器上,Knossos 可能会发现线性化违规,即读取在 gossip 传播写入之前到达。**这些违规对于最终一致性系统来说是正确的行为,并非 bug。** CI 容忍线性化违规,但在出现异常、崩溃或协议错误时会失败。
**测试覆盖率:** 87 个复制测试、10 个 CRDT DST 测试套件(每个 100 个种子)、6 个多节点模拟测试(分区、丢包、收敛)、针对合并可交换/可结合/幂等性的 Stateright 模型检查、4 个 TLA+ 规范(gossip、反熵、复制收敛、流式持久化)。
## 配置
工作目录中的 `perf_config.toml`(或 `PERF_CONFIG_PATH` 环境变量):
```
num_shards = 4 # power of 2, tune to your CPU count
[response_pool]
capacity = 576
prewarm = 96
[buffers]
read_size = 8192
max_size = 536870912 # 512MB max request size
[batching]
min_pipeline_buffer = 70
batch_threshold = 6
```
根目录 `perf_config.toml` 使用 `num_shards = 1` 以兼容 Tcl 测试(Lua 脚本需要所有键在同一个分片上)。`docker-benchmark/perf_config.toml` 使用 `num_shards = 16` 进行吞吐量测试。**如果你修改了一个,另一个不会改变。** Docker 构建从 `docker-benchmark/perf_config.toml` 复制。
## 安全
可选,通过 feature flags 启用:
```
cargo build --release --features tls # TLS encryption (rustls)
cargo build --release --features acl # Redis 6.0+ ACL auth
cargo build --release --features security # both
```
TLS:设置 `TLS_CERT_PATH`、`TLS_KEY_PATH`,可选 `TLS_CA_PATH` + `TLS_REQUIRE_CLIENT_CERT`。
ACL:设置 `REDIS_REQUIRE_PASS` 进行简单认证,或设置 `ACL_FILE` 进行完整的用户管理。
## 项目结构
| 路径 | 说明 |
|------|------|
| `src/redis/command.rs` | Command 枚举(所有 75+ 命令) |
| `src/redis/parser.rs`、`commands.rs` | RESP 解析(标准 + 零拷贝) |
| `src/redis/executor/` | 命令执行(`*_ops.rs` 文件) |
| `src/production/sharded_actor.rs` | 分片路由和聚合 |
| `src/production/connection_optimized.rs` | 连接处理器、MULTI/EXEC 状态 |
| `src/replication/` | CRDT、gossip 协议、反熵、哈希环 |
| `src/production/replicated_shard_actor.rs` | 基于 actor 的多节点复制 |
| `src/bin/maelstrom_kv_replicated.rs` | 多节点 Maelstrom 概念验证 |
| `src/simulator/` | 确定性模拟测试工具 |
| `src/buggify/` | 故障注入(FoundationDB 风格) |
| `specs/tla/` | TLA+ 规范(gossip、反熵、收敛) |
| `tests/redis-tests/` | 官方 Redis Tcl 测试套件(git 子模块) |
| `scripts/run-redis-compat.sh` | Tcl 测试运行器 |
| `docker-benchmark/` | 基于 Docker 的基准测试 |
| `perf_config.toml` | 服务器调优(根目录 = 1 分片,docker-benchmark/ = 16 分片) |
## 许可证
MIT
标签:Actor模型, CRDT, DNS解析, Lua脚本, Redis, RESP2协议, Rust, 中间件, 事务处理, 内存数据库, 分布式系统, 分片架构, 可视化界面, 响应大小分析, 多节点复制, 开源项目, 形式化验证, 数据一致性, 数据库, 无冲突复制数据类型, 确定性模拟测试, 系统编程, 缓存, 网络流量审计, 请求拦截, 通知系统, 键值存储