# mini-redis **Repository Path**: MuMuNan/mini-redis ## Basic Information - **Project Name**: mini-redis - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-18 - **Last Updated**: 2026-06-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # mini-redis mini-redis 是从 Redis 7.x 真实源码中蒸馏 SET/GET 主代码路径的最小学习实现。 > 不是复刻完整 Redis;不是设计一个通用 KV 数据库。 > 是把 `client → event loop → RESP → command lookup → command exec → db → reply` 这一条主路径,用 Go 标准库以最小代码量重新走一遍。 阅读顺序:[`CLAUDE.md`](CLAUDE.md) → [`docs/commit-policy.md`](docs/commit-policy.md) → [`docs/test-policy.md`](docs/test-policy.md) → [`docs/redis-reading-map.md`](docs/redis-reading-map.md) → [`docs/plan.md`](docs/plan.md)。 ## 已支持的命令 P0–P4(第一批): * `PING [message]` * `SET key value`(不支持 `EX/PX/NX/XX/KEEPTTL/GET`) * `GET key` * `DEL key`(单 key) * `EXISTS key`(单 key) P5(第二批): * `EXPIRE key seconds` * `PEXPIRE key milliseconds` * `TTL key` * `PTTL key` * `PERSIST key` P6(第三批)持久化: * `mini-redis-server -aof ` — AOF:每条写命令 `fsync` 后追加,重启时按 RESP 重放 * `mini-redis-server -rdb ` — RDB:启动加载快照,优雅关闭时 dump 全量 KV * AOF 与 RDB 可单独或同时启用;同时启用时 RDB 先 load、AOF 后 replay P7(第四批)Pub/Sub: * `SUBSCRIBE channel [channel...]` * `UNSUBSCRIBE [channel...]` * `PUBLISH channel message` → `:N`(N = 收到消息的订阅者数) Pub/Sub 模式下,订阅者会在原连接上同时收到命令回复与 `*3\r\n$7\r\nmessage\r\n$\r\n\r\n$\r\n\r\n` 推送。 ## 构建 ```bash go build ./... ``` 产物: ```text mini-redis-server # cmd/mini-redis-server mini-redis-cli # cmd/mini-redis-cli ``` ## 运行 启动服务(默认 `127.0.0.1:6380`,故意避开真实 redis 的 6379): ```bash go run ./cmd/mini-redis-server # 或 ./mini-redis-server -addr 127.0.0.1 -port 6380 ``` 另起一个 shell,用自带 cli: ```bash go run ./cmd/mini-redis-cli SET hello world # OK go run ./cmd/mini-redis-cli GET hello # "world" go run ./cmd/mini-redis-cli EXISTS hello # 1 go run ./cmd/mini-redis-cli DEL hello # 1 go run ./cmd/mini-redis-cli GET hello # (nil) ``` 也可以直接用 `redis-cli`(协议级兼容): ```bash redis-cli -p 6380 PING # PONG redis-cli -p 6380 SET hello world # OK redis-cli -p 6380 GET hello # "world" ``` 或者跑一遍演示脚本: ```bash bash scripts/demo-set-get.sh ``` ## 测试 ```bash go test ./... go test -race ./... ``` 测试分层(详见 [`docs/test-policy.md`](docs/test-policy.md)): | 层 | 位置 | 内容 | |---|---|---| | L1 | `internal/resp` `internal/db` | RESP 编解码、内存 KV | | L2 | `internal/command` | 命令注册 + 分发(PING/SET/GET/DEL/EXISTS)| | L1+`net.Pipe` | `internal/server` | Server 装配、Session round-trip | | L3 | `internal/server` `test/integration` | 真实 TCP、并发、优雅关闭 | | L4 | `test/e2e` | 进程级 cli ↔ server | ## 项目结构 ```text mini-redis/ cmd/ mini-redis-server/ # 服务端 entry point(蒸馏 src/server.c main) mini-redis-cli/ # 单命令 cli(蒸馏 src/redis-cli.c 一小部分) internal/ resp/ # RESP2 parser + writer(src/networking.c) db/ # 内存 string KV(src/db.c + src/dict.c + src/object.c) command/ # 命令表 + 分发(src/server.c command table、src/t_string.c) server/ # Config / Server / Session / TCP loop(src/server.c initServer、src/networking.c accept/read/write) test/ integration/ # L3 真实 TCP e2e/ # L4 进程级 scripts/ demo-set-get.sh # README 演示 docs/ redis-reading-map.md # Redis 源码地图 plan.md # 实施计划(每个 Step:做什么 / 测什么 / commit / 验收) commit-policy.md test-policy.md ``` ## 不实现的内容(含原因) | 暂不实现 | 原因 | |---|---| | RDB / AOF | 第三批 P6;先把内存主路径走通 | | Replication / Cluster / Sentinel | 分布式/高可用,正交于单机 SET/GET | | Lua / Modules | 命令扩展,不在主路径 | | list / set / hash / zset / stream | 第一批只蒸馏 string | | ACL / Eviction / 多 DB | 不影响最小读写闭环 | | Inline 协议 / RESP3 | 第一批仅 RESP2 multibulk | | 多线程 IO / pipeline 优化 | goroutine-per-conn 已足够走通主路径 | 如何扩展、按什么顺序,详见 [`docs/plan.md`](docs/plan.md) §3 / §8。