# 小型redis **Repository Path**: chen_dl/mini-redis ## Basic Information - **Project Name**: 小型redis - **Description**: 在linux系统上实现的仿redis的mini-redis - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 1 - **Created**: 2025-09-06 - **Last Updated**: 2026-03-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Mini-Redis项目 技术栈:C++17、CMake、epoll 事件驱动、RESP 协议、AOF+RDB 持久化机制、跳表、TCP 网络编程 仓库链接:https://gitee.com/chen_dl/mini-redis 项目描述:基于 C++ 开发 mini-redis 轻量级 KV 存储系统,兼容 RESP 协议,通过 epoll 边沿触发 + 批量非阻塞 I/O 实现 4 万 + 单机 QPS;实现跳表、AOF+RDB 持久化,重构 Redis 主从复制逻辑(子线程替代 fork),完成 PSYNC 协议解析与 TCP 通信。 1. 协议与网络层:兼容标准 RESP 协议,适配 redis-cli 工具;基于 epoll 边沿触发 + 批量非阻塞 I/O + writev 优化实现高性能并发,单机 QPS 达 4 万 + 2. 数据存储层:实现跳表数据结构,作为 zset 类型底层存储;基于 AOF(异步写入)+RDB 双机制完成 KV 数据持久化,通过二进制文件读写提升 AOF 文件读写效率与安全性 3. 集群能力层:重构 Redis 主从复制逻辑,以子线程替代 fork 子进程方案,基于 TCP 通信 + PSYNC 协议解析实现主从复制核心功能 # 一、项目架构 ## 1.1 项目架构图 ![image-20250927114518381](开发日志/image/1.png) ## 1.2 请求处理流程 1. ⽹络接收: epoll监听客⼾端连接和数据 2. 协议解析: 解析RESP格式的命令 3. 命令执⾏: 在KV存储中执⾏操作 4. 持久化: AOF记录命令,RDB定期快照 5. 主从复制: 同步命令到从节点 6. 响应返回: 将结果序列化为RESP格式返回 ## 1.3 模块划分 | 模块 | 文件 | 功能 | | ------ | ------------------------------------------------------------ | -------------------------- | | ⽹络层 | Server.h、Server.cpp | epoll事件循环,TCP连接管理 | | 协议层 | RespParser.h、RespParser.cpp | RESP协议解析和序列化 | | 存储层 | Skiplist.h、Skiplist.cpp、KeyValueStore.h、KeyValueStore.cpp | 数据结构实现,过期管理 | | 持久化 | Rdb.h、Rdb.cpp、AofLogger.h、AofLogger.cpp | AOF/RDB持久化 | | 复制 | ReplicaClient.h、ReplicaClient.cpp | 主从复制 | | 配置 | config.h、log.h、config_loader.h、config_loader.cpp | 配置解析与日志输出 | # 二、环境准备与项⽬搭建 ## 2.1 环境要求 ```shell # Ubuntu/Debian sudo apt install build-essential cmake pkg-config # CentOS/RHEL sudo yum install gcc-c++ cmake make # 检查版本 g++ --version # 需要支持C++17 cmake --version # 建议3.15+ ``` ## 2.2 项⽬结构 ```shell mini_redis ├── bin │ └── mini_redis ├── build ├── CMakeLists.txt ├── conf │ ├── always.conf │ ├── aof.conf │ ├── everysec.conf │ ├── none.conf │ └── rdb.conf ├── data │ └── appendonly.aof ├── include │ └── mini_redis │ ├── AofLogger.h │ ├── config.h │ ├── config_loader.h │ ├── KeyValueStore.h │ ├── log.h │ ├── Rdb.h │ ├── ReplicaClient.h │ ├── RespParser.h │ ├── Server.h │ ├── Skiplist.h │ └── state.h └── src ├── AofLogger.cpp ├── config_loader.cpp ├── KeyValueStore.cpp ├── main.cpp ├── Rdb.cpp ├── ReplicaClient.cpp ├── RespParser.cpp ├── Server.cpp └── Skiplist.cpp ``` ## 2.3 构建项目 ```shell cd mini-redis cmake -S . -B build cmake --build build -j ``` ## 2.4 单机启动模式 ### **1.** 无持久化模式(none.conf) ```shell # 启动服务器 # 服务器将在端口 6388 启动,无 AOF 和 RDB ./bin/mini_redis --config ./conf/none.conf ``` ### 2. 每秒同步模式(everysec.conf) ```shell # 启动服务器 # 服务器将在端口 6388 启动,AOF 每秒同步一次 ./bin/mini_redi --config ./conf/everysec.conf ``` ### **3.** 立即同步模式 (always.conf) ```shell # 启动服务器 # 服务器将在端口 6388 启动,每个写操作立即同步到磁盘 ./bin/mini_redi --config ./conf/always.conf ``` ## 2.5 主从复制模式 ```shell # 启动主节点 ./bin/mini_redis --config ./conf/master.conf ``` ```shell # 启动从节点 ./bin/mini_redis --config ./conf/replica.conf ``` # 三、测试 ## 3.1 使⽤ redis-cli 进⾏测试 ### 连接测试 ```shell # 连接到单机模式 redis-cli -p 6388 # 连接到主节点 redis-cli -p 6379 # 连接到从节点 redis-cli -p 6380 ``` ### 基本命令测试 ```shell # 测试连接 redis-cli -p 6388 PING # 获取服务器信息 redis-cli -p 6388 INFO # 回显测试 redis-cli -p 6388 ECHO "Hello Mini-Redis" ``` ### String操作 ```shell # 设置键值 redis-cli -p 6388 SET mykey "Hello World" # 获取值 redis-cli -p 6388 GET mykey # 删除键 redis-cli -p 6388 DEL mykey # 设置过期时间(秒) redis-cli -p 6388 SET tempkey "temporary" redis-cli -p 6388 EXPIRE tempkey 60 # 查看剩余过期时间 redis-cli -p 6388 TTL tempkey # 检查键是否存在 redis-cli -p 6388 EXISTS mykey ``` ![image-20250927123547953](开发日志/image/2.png) ### **Hash** 操作 ```shell # 设置 Hash 字段 redis-cli -p 6388 HSET user:1 name "chen" redis-cli -p 6388 HSET user:1 age "22" redis-cli -p 6388 HSET user:1 city "湖南" # 获取 Hash 字段 redis-cli -p 6388 HGET user:1 name # 获取所有字段和值 redis-cli -p 6388 HGETALL user:1 # 检查字段是否存在 redis-cli -p 6388 HEXISTS user:1 email # 删除字段 redis-cli -p 6388 HDEL user:1 age # 获取字段数量 redis-cli -p 6388 HLEN user:1 ``` ![image-20250927124237148](开发日志/image/3.png) ### ZSet操作 ```shell # 添加成员和分数 redis-cli -p 6388 ZADD leaderboard 100 "player1" redis-cli -p 6388 ZADD leaderboard 85 "player2" redis-cli -p 6388 ZADD leaderboard 92 "player3" # 按分数范围查询(默认升序) redis-cli -p 6388 ZRANGE leaderboard 0 -1 # 获取成员分数 redis-cli -p 6388 ZSCORE leaderboard "player2" # 删除成员 redis-cli -p 6388 ZREM leaderboard "player2" ``` ![image-20250927124643013](开发日志/image/4.png) ### 测试主从复制 ```shell # 启动主节点 ./bin/mini_redis --config ./conf/master.conf # 启动从节点 ./bin/mini_redis --config ./conf/replica.conf # 连接到主节点 redis-cli -p 6379 # 连接到从节点 redis-cli -p 6380 ``` ![image-20260310214852225](开发日志/image/10.png) ### 其他操作 ```shell # 列出所有键 redis-cli -p 6388 KEYS "*" # 触发 RDB 快照保存 redis-cli -p 6388 BGSAVE # 清空所有数据 redis-cli -p 6388 FLUSHALL ``` ![image-20250927124911801](开发日志/image/5.png) ## 3.2 性能测试 ### mini-redis测试 ```shell # 测试 SET 操作 redis-benchmark -h 127.0.0.1 -p 6388 -t set -n 10000 -d 100 ``` ![image-20250927125930442](开发日志/image/6.png) ```shell # 测试 GET 操作 redis-benchmark -h 127.0.0.1 -p 6388 -t get -n 10000 ``` ![image-20250927130044201](开发日志/image/7.png) ### 官方redis测试 ```shell # 测试 SET 操作 redis-benchmark -h 127.0.0.1 -p 你自己的redis端口 -a 你自己的redis密码 -t set -n 10000 -d 100 ``` ![image-20250927130438760](开发日志/image/8.png) ```shell # 测试 GET 操作 redis-benchmark -h 127.0.0.1 -p 你自己的redis端口 -a 你自己的redis密码 -t get -n 10000 ``` ![image-20250927130808002](开发日志/image/9.png)