Skip to content

muma0413/Build-Redis-from-Scratch-with-AI

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

37 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Mini-Redis Logo

Mini-Redis (AI Edition)

🤖 Gemini 3.0 Pro 从零构建 Redis:人机结对编程实录 🚀

Java 17 × Netty × 核心原理复刻

不仅仅是 KV 存储,更是对 Redis 灵魂的致敬。

License Java 17 Powered by Gemini

项目简介硬核技术栈持久化机制性能测试开发实录快速开始路线图



📖 项目简介

Mini-Redis 不仅仅是一个 KV 存储引擎,它是 AI 辅助编程 (AI-Native Development) 极限能力的试金石。

本项目由 Gemini 3.0 Pro 全程深度参与构建。从一行代码都没有的空白仓库,到拥有 MP-AOF、QuickList、SkipList 的工业级存储引擎,每一行代码都凝聚了 人类程序员思维AI 极致执行力 的碰撞。

为什么它不是“又一个玩具”? 不同于市面上仅封装 HashMap 的简单实现,我们追求技术深度的 1:1 复刻。我们不仅实现了基础功能,更挑战了 Redis 7.0+ 的前沿特性(如 Multi-Part AOF 增量重写、SINTERCARD、LPOP Count 等)。

基于 Java 17Netty 的高性能 Reactor 模型,证明了在现代 JVM 上复刻工业级 C 语言中间件的可行性与惊人性能。


🛠️ 硬核技术栈 & 核心特性

1. 🏗️ 高性能通信架构

  • Reactor 模型: 基于 Netty 4.1 实现非阻塞 I/O,单机吞吐量对标原生 Redis。
  • 无锁化设计 (Lock-Free): 采用 "IO 多线程 + 业务单线程" 架构,彻底消除 synchronized 锁竞争,写性能提升 5 倍以上。
  • RESP 协议栈: 纯手写 RESP 解析器与编码器,支持递归解析数组与 BulkString。
  • Context 上下文: 引入 RedisContext 传递连接状态,为未来 ACL、事务和多数据库支持预留了优雅的扩展点。

2. 📡 分布式与高可用 (Replication) 【NEW】

实现了对标 Redis 2.8+ 的 PSYNC 主从复制协议,具备生产级的高可用能力:

  • 全量复制 (Full Resync): 利用 BGSAVE 生成 RDB 快照,通过 Netty ChunkedFile 实现零拷贝流式传输,无内存溢出风险。
  • 增量复制 (Partial Resync): 基于 Replication Backlog (环形缓冲区) 实现断点续传,完美应对网络抖动,避免昂贵的全量重传。
  • 级联复制 (Cascading): 支持 Master -> Slave A -> Slave B 链式拓扑,减轻 Master 负载。
  • 心跳保活: 完整的 PING / REPLCONF ACK 机制,自动检测连接失效并触发重连。

3. 🧠 数据结构:极致优化与双引擎

我们实现了 Redis 最引以为傲的**“自适应存储策略”**,根据数据量大小动态切换底层结构:

🔹 String (字符串)

  • 二进制安全: 底层基于 byte[],完美支持图片、视频等二进制数据。
  • 原子计数器: 完整实现 INCR, DECRBY, INCRBY,保证并发安全。
  • 位图操作 (Bitmap): 支持 SETBIT, BITCOUNT, BITOP 等位操作指令,轻松应对亿级用户签到场景。
  • 高阶特性: 支持 Redis 6.2 GETEX (Get and Expire) 及 SETNX 分布式锁原语。

🔹 List (列表)

  • QuickList 架构: 抛弃传统的 LinkedList,实现 QuickList (双向链表 + ZipList) 混合结构,平衡内存与性能。
  • 阻塞队列 (Blocking Queue): 深度复刻 BLPOP, BRPOP, BRPOPLPUSH
    • 实现 Global Blocking Registry,支持精确唤醒与超时处理。
    • 完美解决并发下的虚假唤醒 (Spurious Wakeup) 问题。
  • 批量操作: 支持 LPOP/RPOP 的 count 参数 (Redis 6.2+)。

🔹 Hash (哈希)

  • 双引擎切换 (Dual-Engine):
    • ZipList: 小数据量下使用紧凑数组,极大节省内存。
    • HashTable: 大数据量下自动升级,保证 O(1) 查询。
  • 高频指令: 支持 HINCRBY 原子递增及 HSCAN 游标遍历(基于 Snapshot 模拟)。

🔹 Set (集合)

  • IntSet 优化: 当集合元素均为整数时,采用二分查找的有序数组存储,内存占用降低 10x。
  • 集合运算: 实现 SUNION, SINTER, SDIFF 及其 Store 变体。
  • Redis 7.0 特性: 首发支持 SINTERCARD,利用基数估算与 Limit 截断,极大提升大集合交集计算性能。

🔹 Sorted Set (有序集合)

  • SkipList (跳表) 引擎: 纯手写 Java 版跳表,包含核心的 Span (跨度) 维护。
    • 支持 O(logN) 的 ZRANK (排名查询)。
    • 支持 O(logN) 的 ZRANGE (范围查询)。
  • 复杂查询: 实现了 ZREVRANGE (倒序), ZRANGEBYSCORE (分数范围), ZCOUNT (利用 Rank 相减优化)。
  • 防御性编程: 针对大 Key 扫描 (ZRANGE 0 -1) 植入了日志预警机制。

4. 🛡️ 稳定性与健壮性

  • 双模持久化:
    • AOF: 支持 Redis 7.0 MP-AOF (Multi-Part) 架构,实现增量重写 (Incremental Rewrite),无阻塞。
    • RDB: 支持自动快照 (save 900 1),生成紧凑二进制文件。
  • 过期策略: 惰性删除 (Lazy) + 定期扫描 (Active) 双管齐下,杜绝内存泄漏。
  • 类型安全: 全局采用 RedisData<T> 泛型封装,杜绝 ClassCastException

🤖 开发实录 (The AI Journey)

我们将整个开发过程的对话记录整理成了 PDF,这是一份珍贵的现代软件工程实录

阶段 核心内容 记录下载
Phase 1 通信骨架: Netty, RESP, Dispatcher [Coming Soon]
Phase 2 内存引擎: String 原子性, Hash 策略模式 [Coming Soon]
Phase 3 高阶结构: 手写 SkipList, QuickList, 阻塞队列 [Coming Soon]

🚀 快速开始

环境要求

  • JDK 17+
  • Maven 3.8+

构建与运行

git clone https://github.com/muma0413/Build-Redis-from-Scratch-with-AI.git
cd mini-redis
mvn clean package
java -jar target/mini-redis-1.0-SNAPSHOT.jar

连接测试

你可以使用官方 redis-cli 或任何可视化客户端(如 ARDM)连接:

redis-cli -p 6379
127.0.0.1:6379> PING
PONG
127.0.0.1:6379> SET user:1 "Gemini"
OK
127.0.0.1:6379> ZADD rank 100 "Player1"
(integer) 1
127.0.0.1:6379> ZRANK rank "Player1"
(integer) 0

🛣️ 路线图 (Roadmap)

我们正在按照严格的工程标准迭代本项目,目前已完成核心内存数据库的所有功能。

  • Phase 1: 骨架与协议

    • Netty 非阻塞 Reactor 模型搭建
    • RESP 协议纯手写解析器与编码器
    • Command Dispatcher 命令分发系统
  • Phase 2: 内存数据结构 (Memory Engine)

    • String: 基础读写、原子计数 (INCRBY)、位操作 (SETBIT/BITCOUNT)、GETEX
    • Hash: ZipList/HashTable 动态切换策略、HSCAN、集合运算
    • List: QuickList (双向链表+ZipList) 架构、BLPOP/BRPOP 阻塞队列实现
    • Set: IntSet/HashTable 动态切换、SINTERCARD (Redis 7.0)、集合运算 (SUNION/SDIFF)
    • ZSet: SkipList (跳表) 核心引擎、Span 排名计算、ZRANGEBYSCOREZREVRANGE
  • Phase 3: 架构重构与优化

    • 引入 RedisContext 上下文传递
    • 泛型 RedisData<T> 类型安全改造
    • 无锁化重构: IO多线程+业务单线程,QPS 提升 500%
  • Phase 4: 持久化 (Persistence)

    • MP-AOF: Redis 7.0 多分片 AOF,支持增量重写 (Incremental Rewrite)
    • RDB: 二进制快照保存与加载,支持自动触发策略 (save 900 1)
  • Phase 5: 分布式与高可用 (Replication)

    • PSYNC 协议: 智能全量/增量同步判定
    • Replication Backlog: 环形缓冲区实现断点续传
    • 级联复制: 支持 Master -> Slave -> Slave 链式传播
    • 心跳保活: PING / REPLCONF ACK 机制
  • Phase 6: 运维与扩展 (Ops & Future)

    • Dockerization: 提供标准 Dockerfile 及 Docker Compose 编排,一键启动集群。
    • Observability: 实现 INFO (增强版), MONITOR, SLOWLOG 等监控指令。
    • Cluster: 探索基于 Gossip 协议的分片集群。
    • LSM-Tree: 探索基于磁盘的存储引擎 (RocksDB 风格)。

📊 性能基准测试 (Benchmark Report)

我们在单机环境下对 Mini-Redis 进行了全方位的压力测试,以验证 "Netty I/O 多线程 + 业务单线程无锁" 架构的极限吞吐量。

测试环境

  • 硬件: 开发笔记本 (Environment Dependent)
  • JVM: JDK 17 (G1GC, Default Tuning)
  • 工具: 自研 Netty 压测客户端 (基于 Pipeline 流水线模式)
  • 策略: 50 并发连接,每连接 10,000 请求 (共 50w/轮),3 轮预热 + 5 轮均值统计。

核心指标 (QPS)

模块 写指令 (Write) QPS 读指令 (Read) QPS 备注
String SET 254,277 GET 396,291 纯内存操作,基准水位
INCR 250,030 MGET 188,774 批量读协议开销较大
Hash HSET 250,906 HGET 344,534 HashTable O(1) 查找
HINCRBY 261,319 HSCAN 173,682 遍历拷贝开销
List LPUSH 260,345 LINDEX 318,721 QuickList 局部性优势
LPOP 258,299 LRANGE 89,841 协议序列化瓶颈 (10 elements)
Set SADD 269,550 SISMEMBER 291,287 IntSet/HashTable 混合引擎
SPOP 266,670 SINTER 276,661 集合运算高效算法
ZSet ZADD 266,844 ZSCORE 332,778 Dict O(1) 查找
ZRANGE 210,744 SkipList O(logN) 遍历

📈 性能深度剖析

  1. 写性能 (Write Throughput):

    • 所有写操作稳定在 25万 ~ 27万 QPS
    • 架构胜利: 得益于无锁化架构,消除了 synchronized 的上下文切换,写操作达到了 Netty IO 处理能力的物理上限。
    • 数据结构优化: 即使是复杂的 ZADD (SkipList) 和 LPUSH (QuickList),性能并未显著低于简单的 SET,证明了底层数据结构实现的极低 Overhead。
  2. 读性能 (Read Throughput):

    • 单点查询 (GET, HGET, ZSCORE) 突破 30万 ~ 40万 QPS
    • 内存寻址: 读操作不需要分配新对象(写操作需要创建 Entry),GC 压力更小,且 CPU 缓存命中率更高。
  3. 协议开销 (Protocol Overhead):

    • LRANGEMGET 的 QPS 相对较低 (9万 ~ 18万)。这是因为 Redis RESP 协议在返回数组时需要大量的字节拼接和内存拷贝,网络带宽和序列化成为了主要瓶颈,而非数据结构本身。

(注:以上数据为本地 Loopback 压测结果,实际网络环境下受带宽延迟影响会有所不同)

📚 源码深度解析

想知道 Mini-Redis 内部是如何工作的?我们准备了深度的架构剖析文档:

  • 总体架构设计: Netty 线程模型与命令分发流程。
  • 数据结构解密:
    • 为什么 ZSet 要用 SkipList?Span 是如何计算排名的?
    • QuickList 是如何通过“链表+数组”平衡内存与性能的?
    • Set 的 IntSet 优化策略。
  • 并发与阻塞机制: 深度解析 BLPOP 是如何利用 Netty 实现非阻塞挂起与异步唤醒的。

📡 主从复制 (Replication)

Mini-Redis 实现了一套完整的、对标 Redis 2.8+ 协议的主从复制机制,支持全量同步、增量同步、级联复制及自动故障恢复。

1. 原理介绍 (Architecture)

Redis 的复制机制是基于 异步复制 (Asynchronous Replication) 的。其核心流程如下:

  1. 握手 (Handshake): Slave 连接 Master,发送 PING, REPLCONF 等指令建立信任。
  2. 同步 (Synchronization):
    • 全量复制 (Full Resync): Master 执行 BGSAVE 生成 RDB 快照发送给 Slave。Slave 清空内存并加载 RDB。
    • 增量复制 (Partial Resync): 如果 Slave 只是短暂断线,Master 通过 Replication Backlog 补发断线期间的增量命令,避免昂贵的全量 RDB 传输。
  3. 传播 (Propagation): Master 将后续所有的写命令 (Write Commands) 异步转发给所有在线的 Slave,保持数据最终一致性。

2. 核心功能 (Features)

Mini-Redis 目前支持:

  • SLAVEOF 命令: 动态切换主从角色,支持 SLAVEOF NO ONE 提升为 Master。
  • PSYNC 协议: 支持 Redis 2.8+ 的 PSYNC,智能判断全量或增量同步。
  • RDB 流式传输: 利用 Netty ChunkedFile 实现 RDB 文件的零拷贝流式发送,无内存溢出风险。
  • Replication Backlog: 维护环形缓冲区,支持断点续传。
  • 级联复制 (Cascading): 支持 Master -> Slave A -> Slave B 的链式拓扑。
  • 心跳保活: Master 定时发送 PING,Slave 定时发送 REPLCONF ACK
  • 故障自动重连: Slave 断线后自动重连并尝试增量同步。

3. 实现原理与流程 (Implementation)

3.1 核心组件

  • ReplicationManager: 上帝类。负责维护复制状态机 (State Machine)、管理 Slave 连接、处理 PSYNC 逻辑。
  • ReplicationBacklog: 固定大小的 RingBuffer,存储最近的写命令字节流。
  • RedisSlaveHandler: Slave 端的 Netty Handler,处理握手响应和 RDB 数据流。

3.2 流程图解

A. 全量同步流程

[Slave]                     [Master]
   |      SLAVEOF host port     |
   | -------------------------> |
   |      PSYNC ? -1            |
   | -------------------------> | (Check Backlog: Miss)
   |      +FULLRESYNC id off    | (Trigger BGSAVE)
   | <------------------------- |
   |                            | (Buffer new commands to Pending List)
   |      $ <len>\r\n<RDB>      | (Send RDB via Zero-Copy)
   | <========================= |
   | (Flush DB & Load RDB)      |
   |                            | (Promote Slave to Online)
   |      (Command Stream)      | (Send Buffered Commands)
   | <------------------------- |

4. 使用说明 (Usage)

方式一:配置文件启动

在 redis.properties 中配置:

# =========================================================
# Mini-Redis 核心配置文件 (redis.properties)
# =========================================================

# --- 网络与连接 (Network) ---
# 服务器监听端口 (默认: 6379)
server.port=6379

# Netty Worker 线程数 (0 = 自动设置为 CPU 核心数 * 2)
# 调大此值可提升高并发下的 IO 吞吐量
server.worker_threads=0

# 最大客户端连接数限制
server.max_clients=10000

# --- 存储引擎策略 (Storage Backend) ---
# 集合(Set) 和 哈希(Hash) 的底层实现策略
# JDK_HASHMAP: 吞吐量极高,但扩容时可能会有瞬间卡顿 (STW)
# REDIS_DICT:  自研实现,支持渐进式 Rehash,延迟极低且平滑 (推荐生产环境)
backend.set_dict=REDIS_DICT

# --- 持久化: AOF (Append Only File) ---
# 是否开启 AOF 持久化 (yes/no)
# 建议开启以保证数据安全性,重启时优先加载 AOF
appendonly=yes

# AOF 刷盘策略
# always:   每条写命令都刷盘 (最安全,性能最低)
# everysec: 每秒刷盘一次 (推荐,折中方案,最多丢1秒数据)
# no:       操作系统决定 (最快,不安全)
appendfsync=everysec

# AOF 文件存储目录 (相对于工作目录)
appenddirname=appendonlydir

# AOF 主文件名
appendfilename=appendonly.aof

# 是否使用 RDB 混合格式头 (暂未启用,预留配置)
aof-use-rdb-preamble=no

# AOF 自动重写触发条件
# 当 AOF 文件大小增长率超过此百分比时触发重写
auto-aof-rewrite-percentage=100
# 允许触发重写的最小文件体积 (避免小文件频繁重写)
auto-aof-rewrite-min-size=64mb

# --- 持久化: RDB (Snapshot) ---
# 快照自动保存策略 (格式: <seconds> <changes>)
# 900秒内有1次修改,或300秒内10次,或60秒内10000次
save=900 1 300 10 60 10000

# RDB 文件名
dbfilename=dump.rdb

# --- 主从复制 (Replication) ---
# 如果配置了以下项,当前实例启动后将自动连接 Master 成为 Slave
# slaveof=127.0.0.1 6379

# 断线重连间隔 (毫秒)
repl-retry-interval=1000

# --- 工作目录 (Working Directory) ---
# RDB 文件和 AOF 目录将存放于此
# 默认为当前启动目录 (.)
dir=.

方式二:运行时动态挂载

启动两个实例后,在 Slave 端执行:

redis-cli -p 6380
> SLAVEOF 127.0.0.1 6379
OK

验证同步

1.Master: SET k1 v1

2.Slave: GET k1 -> "v1"

3.断线测试: 杀掉 Slave 再重启(或使用 DEBUG REPL_BREAK),观察日志是否触发 Partial resync。

🐳 Docker 部署

不想配置 Java 环境?使用 Docker 一键启动!

1. 构建镜像

docker build -t mini-redis .

🤝 贡献 (Contribution)

本项目是一个探索 "AI Pair Programming" (AI 结对编程) 边界的实验性项目。我们欢迎任何形式的贡献!

如何参与?

  1. Fork 本仓库:将代码克隆到你的本地。
  2. 选择任务:从上面的 路线图 中选择未完成的特性(如持久化模块)。
  3. 提交 PR
    • 请确保你的代码风格与现有项目保持一致。
    • 必须包含单元测试:所有新功能都需经过 JUnit 测试验证。
  4. Issue 讨论:如果你发现了 Bug 或有更好的架构建议(比如 SkipList 的随机算法优化),欢迎提 Issue 讨论。

特别感谢:本项目的所有代码与架构决策均由水平非常一般的程序员与 AI 高级助手 (Gemini 3 PRO) 共同完成。

About

Mini-Redis (Java 17): A professional recreation of Redis internals (ZipList/SkipList/Dict) built via deep AI collaboration. Includes full source code + design conversation logs.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages