# 小型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**: 0 - **Forks**: 0 - **Created**: 2025-09-06 - **Last Updated**: 2025-09-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Mini-Redis项目 这是一个仿造redis实现的一个kv存储项目,实现了RESP协议解析、事件驱动⽹络编程、跳表数据结构实现、持 久化和主从复制等技术。远程仓库中有详细的开发日志和测试数据 **技术栈:**C++、CMake、epoll事件驱动、RESP协议、AOF + RDB持久化机制 1. ⽀持标准RESP协议,兼容redis-cli⼯具 2. 单机QPS达4万+,远程仓库的 README 有测试数据 3. 采用异步AOF、批量非阻塞I/O处理、epoll边沿触发实现了高性能并发功能 4. 采用了AOF+RDB机制,实现了kv存储的持久化功能 5. 实现了跳表数据结构,作为kv储存的zset的底层数据结构 6. 采用unordered_map提升了存储性能,使用多线程提高了并发 7. 通过 TCP 网络通信、多线程、PSYNC协议解析等技术,实现了主从复制的核心逻辑 8. 使用writev优化了写事件性能,采用二进制文件读写的方式提高了aof文件的读写效率和安全性 # 一、项目架构 ## 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 # 列出所有键 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)