PingCAP Talent Plan Rust 课程实践项目,实现了一个基于 Bitcask 存储模型的多线程持久化键值存储引擎,支持客户端-服务端网络架构、可插拔存储引擎和线程池并发处理。
| 阶段 | 状态 | 描述 |
|---|---|---|
| Project 1 | ✅ 完成 | 内存键值存储 + CLI 框架 |
| Project 2 | ✅ 完成 | 日志结构化文件 I/O + 压缩 |
| Project 3 | ✅ 完成 | 同步客户端-服务端网络 + 可插拔引擎 |
| Project 4 | ✅ 完成 | 并发与并行:线程池 + 无锁读取 |
| Project 5 | 🔲 待开始 | 异步 I/O |
project/
├── Cargo.toml
├── src/
│ ├── lib.rs # 库入口,模块导出
│ ├── error.rs # 自定义错误类型 (thiserror)
│ ├── common.rs # 客户端-服务端通信协议 (Request/Response)
│ ├── server.rs # KvsServer<E, P> — 多线程 TCP 服务端
│ ├── client.rs # KvsClient — TCP 客户端
│ ├── engines/
│ │ ├── mod.rs # KvsEngine trait (Clone + Send + 'static)
│ │ ├── kvs.rs # KvStore — Bitcask 引擎 (无锁并发读)
│ │ └── sled_engine.rs # SledKvsEngine 适配器
│ ├── thread_pool/
│ │ ├── mod.rs # ThreadPool trait
│ │ ├── naive.rs # NaiveThreadPool (每任务新线程)
│ │ ├── shared_queue.rs # SharedQueueThreadPool (MPMC 共享队列)
│ │ └── rayon_pool.rs # RayonThreadPool (work-stealing)
│ └── bin/
│ ├── kvs-server.rs # 服务端 CLI
│ └── kvs-client.rs # 客户端 CLI
├── tests/
│ ├── kv_store.rs # 存储引擎集成测试 (8 个,含并发测试)
│ ├── thread_pool.rs # 线程池测试 (4 个,含 panic 恢复)
│ └── cli.rs # 客户端-服务端 CLI 测试 (11 个)
├── benches/
│ └── engine_bench.rs # kvs vs sled 性能基准测试
└── examples/
├── tcp_json_client.rs # TCP + JSON 流式协议示例
└── tcp_json_server.rs
┌──────────────┐ TCP/JSON ┌──────────────────────────────────┐
│ KvsClient │◄────────────────────────►│ KvsServer<E, P> │
│ │ Request { Set/Get/Rm } │ │
│ kvs-client │ Response { Ok/Err } │ ┌──────────────────────────┐ │
└──────────────┘ │ │ ThreadPool trait (P) │ │
│ │ Naive │ SharedQ │ Rayon │ │
│ └──────────┬───────────────┘ │
│ │ spawn(job) │
│ ┌──────────▼───────────────┐ │
│ │ KvsEngine trait (E) │ │
│ │ Clone + Send + 'static │ │
│ ├──────────────────────────┤ │
│ │ KvStore │ SledKvs │ │
│ │ (Bitcask) │ (sled) │ │
│ │ 无锁并发读 │ 内置并发 │ │
│ └──────────────────────────┘ │
└──────────────────────────────────┘
核心并发机制 (KvStore):
- 无锁读取:每个线程持有独立的
RefCell<HashMap<u64, BufReader>>文件句柄,读操作无需加锁 - 写入串行化:
Arc<Mutex<KvStoreWriter>>保证写入原子性,防止 TOCTOU 竞态 - 共享索引:
Arc<RwLock<HashMap>>读写锁保护内存索引,读多写少场景高效 - 安全点机制:
AtomicU64safe_point 标记压缩进度,读线程惰性清理过期文件句柄
线程池实现:
- NaiveThreadPool:每任务创建新线程,基线对照
- SharedQueueThreadPool:crossbeam MPMC 通道 +
catch_unwindpanic 恢复 - RayonThreadPool:work-stealing 调度,生产推荐
| 依赖 | 用途 |
|---|---|
clap v4.5 (derive) |
CLI 参数解析 |
serde + serde_json |
命令序列化/反序列化 + TCP 流式协议 |
thiserror v2.0 |
声明式错误类型 |
env_logger + log |
日志记录 |
sled v0.34 |
嵌入式数据库引擎 |
crossbeam v0.8 |
MPMC 无锁通道 (线程池) |
rayon v1 |
work-stealing 线程池 |
num_cpus |
CPU 核心数检测 |
criterion v0.5 |
性能基准测试 |
# 启动服务端 (默认 kvs 引擎,监听 127.0.0.1:4000)
cargo run --bin kvs-server
# 启动服务端 (指定 sled 引擎和地址)
cargo run --bin kvs-server -- --engine sled --addr 127.0.0.1:5000
# 客户端操作
cargo run --bin kvs-client -- set mykey myvalue
cargo run --bin kvs-client -- get mykey
cargo run --bin kvs-client -- rm mykey
# 指定服务端地址
cargo run --bin kvs-client -- --addr 127.0.0.1:5000 get mykeycargo build # 构建
cargo test # 运行全部 23 个测试
cargo bench # 运行 kvs vs sled 基准测试
cargo clippy --all-targets # lint 检查
cargo fmt --check # 格式检查#![deny(missing_docs)]强制文档覆盖- 所有公共 API 包含
# Errors文档段 - 库代码零 clippy 警告
thiserror声明式错误类型,覆盖 I/O、序列化、网络、引擎等场景- 并发安全:TOCTOU 防护、panic 恢复、无锁读路径
MIT OR Apache-2.0