# hyperdb **Repository Path**: alex-ashuo/hyperdb ## Basic Information - **Project Name**: hyperdb - **Description**: No description available - **Primary Language**: C++ - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2026-04-08 - **Last Updated**: 2026-04-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # HyperDB > 一个高性能的企业级键值存储引擎 [![C++20](https://img.shields.io/badge/C%2B%2B-20-blue.svg)](https://en.cppreference.com/w/cpp/20) [![CMake](https://img.shields.io/badge/CMake-3.30+-green.svg)](https://cmake.org/) ## 项目简介 **HyperDB** 是一个基于 LSM 树(Log-Structured Merge Tree)设计的高性能键值存储引擎,采用 **C++20** 开发。它提供了类似 Redis 的接口,支持 Redis CLI 客户端连接,同时具备 MVCC 事务、WriteAheadLog 持久化、布隆过滤器等企业级特性。 ### 核心特性 | 特性 | 描述 | |------|------| | **LSM 树存储** | 优化写入性能的层次化存储结构 | | **MVCC 事务** | 多版本并发控制,支持四种隔离级别 | | **WAL 持久化** | 预写日志确保数据不丢失 | | **Redis 兼容** | 支持标准 Redis CLI 客户端连接 | | **布隆过滤器** | 快速判断键是否存在,减少磁盘访问 | | **层级压缩** | 自动合并 SST 文件,优化存储空间 | --- ## 快速开始 ### 5 分钟快速上手 #### 1. 克隆并构建项目 ```bash # 克隆项目 git clone https://gitee.com/tyking123/hyperdb cd HyperDB # 创建构建目录 mkdir build && cd build # 配置项目 cmake .. # 编译 cmake --build . --config Release # 运行测试 ctest -C Release --output-on-failure ``` #### 2. 启动 HyperDB 服务器 ```bash # 构建成功后,启动服务器(默认端口 6380) ./server/HyperDBServer ``` #### 3. 使用 Redis CLI 连接 ```bash # 在另一个终端,使用 redis-cli 连接 redis-cli -p 6380 # 体验基本操作 > SET name HyperDB OK > GET name "HyperDB" > INCR counter (integer) 1 > DEL name (integer) 1 ``` #### 4. C++ SDK 使用示例 ```cpp #include "hyper_core/hyper_engine.h" int main() { // 创建数据库实例 hyperdb::HyperDB db("./data"); // 基本操作 db.Put("key1", "value1"); auto val = db.Get("key1"); // 返回 std::optional // 事务操作 auto trx = db.BeginTransaction(hyperdb::IsolationLevel::Repeatable_Read); trx->Put("user:1", "Alice"); trx->Commit(); return 0; } ``` --- ## 目录结构 ``` HyperDB/ ├── engine/ # 核心存储引擎 │ ├── include/ # 头文件目录 │ │ ├── hyper_core/ # HyperDB 高层 API │ │ ├── engine/ # LSM 引擎核心 │ │ ├── mem_table/ # 内存表(跳表实现) │ │ ├── sst/ # SST 文件管理 │ │ ├── wal/ # 预写日志 │ │ ├── redis_wrapper/ # Redis 兼容层 │ │ └── ... │ └── src/ # 实现文件 ├── server/ # 网络服务器 │ ├── include/ # 服务器头文件 │ └── src/ # 服务器实现(基于 muduo) ├── main/ # 主程序示例 ├── test/ # 测试代码 ├── third_party/ # 第三方依赖(fmt, spdlog) ├── cmake/ # CMake 模块 └── CMakeLists.txt # 顶层构建配置 ``` --- ## 核心概念 ### LSM 树(Log-Structured Merge Tree) LSM 树是一种针对写入优化的数据结构,工作原理如下: ``` 写入流程: ┌─────────┐ ┌────────────┐ ┌─────────┐ │ Write │ ──▶ │ MemTable │ ──▶ │ SST │ │ Request│ │ │ │ │ └─────────┘ └────────────┘ └─────────┘ │ │ ▼ ▼ ┌────────┐ ┌─────────┐ │ WAL │ │ bloom │ │ │ │ filter │ └────────┘ └─────────┘ ``` **层级结构**:L0 → L1 → L2 → ... → Ln - 每层容量是上一层的 4 倍(可配置) - 当 MemTable 满时,刷新到 L0 - 当 L0 文件过多时,触发压缩到 L1 ### MVCC(多版本并发控制) HyperDB 支持四种事务隔离级别: | 隔离级别 | 说明 | 使用场景 | |----------|------|----------| | `Read_Uncommitted` | 读取未提交的最新数据 | 最高性能,可能脏读 | | `Read_Committed` | 读取已提交的数据 | 避免脏读 | | `Repeatable_Read` | 事务内多次读取结果一致 | 默认级别,避免不可重复读 | | `Serializable` | 串行执行 | 最高隔离,完全一致 | ```cpp // Repeatable Read 示例:事务内读取一致 auto trx1 = db.BeginTransaction(IsolationLevel::Repeatable_Read); auto trx2 = db.BeginTransaction(IsolationLevel::Repeatable_Read); db.Put("balance", "100"); trx2->Put("balance", "200"); trx2->Commit(); // trx1 仍读取到 100(Repeatable Read) auto val = trx1->Get("balance"); // "100" ``` ### WAL(Write-Ahead Log) 预写日志确保数据持久性: - 每次写入先记录日志 - 崩溃后可根据 WAL 恢复数据 - 支持崩溃恢复测试(参见 `test/test_mvcc_wal.cpp`) --- ## API 参考 ### HyperDB 核心 API #### 数据库操作 ```cpp #include "hyper_core/hyper_engine.h" // 创建数据库(自动创建目录) hyperdb::HyperDB db("./data_dir"); // 单键操作 std::optional Get(const std::string& key); void Put(const std::string& key, const std::string& value); void Remove(const std::string& key); // 批量操作(更高效) void PutBatch(const std::vector>& kvs); void RemoveBatch(const std::vector& keys); // 刷新内存表到磁盘 void FlushAll(); ``` #### 事务操作 ```cpp // 开始事务 auto trx = db.BeginTransaction(IsolationLevel::Repeatable_Read); // 事务内操作 trx->Put("key", "value"); trx->Get("key"); trx->Remove("key"); // 提交或回滚 trx->Commit(); // 或 trx->Rollback(); ``` #### 查询操作 ```cpp // 前缀查询 auto result = db.PrefixQuery("user:"); if (result) { auto [begin, end] = *result; for (auto it = begin; it != end; ++it) { auto [key, value] = *it; std::cout << key << ": " << value << std::endl; } } // 范围查询 auto range = db.RangeQuery("a", "c"); // 清空数据库 db.Clear(); ``` ### Redis 兼容 API ```cpp #include "redis_wrapper/redis_wrapper.h" hyperdb::RedisWrapper redis("./data"); // String 操作 redis.Set({"SET", "key", "value"}); // 返回 "+OK\r\n" redis.Get({"GET", "key"}); // 返回 "$5\r\nvalue\r\n" redis.Incr({"INCR", "counter"}); // 返回 ":1\r\n" redis.Decr({"DECR", "counter"}); // 返回 ":0\r\n" // Hash 操作 redis.Hset({"HSET", "hash", "field", "value"}); redis.Hget({"HGET", "hash", "field"}); redis.Hdel({"HDEL", "hash", "field"}); redis.Hkeys({"HKEYS", "hash"}); // List 操作 redis.Lpush({"LPUSH", "list", "item"}); redis.Rpush({"RPUSH", "list", "item"}); redis.Lpop({"LPOP", "list"}); redis.Rpop({"RPOP", "list"}); redis.Lrange({"LRANGE", "list", "0", "-1"}); // Set 操作 redis.Sadd({"SADD", "set", "member"}); redis.Srem({"SREM", "set", "member"}); redis.Smembers({"SMEMBERS", "set"}); // Sorted Set 操作 redis.Zadd({"ZADD", "zset", "1.0", "member"}); redis.Zscore({"ZSCORE", "zset", "member"}); redis.Zrange({"ZRANGE", "zset", "0", "-1"}); // 键管理 redis.Expire({"EXPIRE", "key", "3600"}); redis.Ttl({"TTL", "key"}); redis.Del({"DEL", "key1", "key2"}); ``` --- ## Redis CLI 使用指南 ### 启动服务器 ```bash # 默认端口 6380 ./server/HyperDBServer # 如需修改端口,编辑 server/src/main.cpp 中的端口号 # net::InetAddress listen_address(6380); // 修改为其他端口 ``` ### 连接方式 ```bash # 使用 redis-cli 连接 redis-cli -p 6380 # 如果 redis-cli 不在 PATH 中 /path/to/redis-cli -p 6380 # 测试连接 redis-cli -p 6380 PING # 返回: PONG ``` ### 支持的 Redis 命令 #### String 类型 ```bash > SET mykey "Hello" OK > GET mykey "Hello" > INCR counter (integer) 1 > INCR counter (integer) 2 > DECR counter (integer) 1 > DEL mykey (integer) 1 > EXISTS mykey (integer) 0 ``` #### Hash 类型 ```bash > HSET user:1 name "Alice" age "25" (integer) 2 > HGET user:1 name "Alice" > HGET user:1 age "25" > HDEL user:1 age (integer) 1 > HKEYS user:1 1) "name" ``` #### List 类型 ```bash > RPUSH fruits apple banana cherry (integer) 3 > LRANGE fruits 0 -1 1) "apple" 2) "banana" 3) "cherry" > LPOP fruits "apple" > RPOP fruits "cherry" > LLEN fruits (integer) 1 ``` #### Set 类型 ```bash > SADD colors red green blue (integer) 3 > SMEMBERS colors 1) "red" 2) "green" 3) "blue" > SISMEMBER colors red (integer) 1 > SREM colors green (integer) 1 > SCARD colors (integer) 2 ``` #### Sorted Set 类型 ```bash > ZADD leaderboard 100 "Alice" 200 "Bob" 150 "Charlie" (integer) 3 > ZSCORE leaderboard "Alice" "100" > ZRANGE leaderboard 0 -1 1) "Alice" 2) "Charlie" 3) "Bob" > ZRANK leaderboard "Bob" (integer) 2 > ZINCRBY leaderboard 50 "Alice" "150" ``` #### 过期时间管理 ```bash > SET tempkey "temporary" OK > EXPIRE tempkey 10 (integer) 1 > TTL tempkey (integer) 9 # 剩余 9 秒 ``` --- ## 构建指南 ### 环境要求 - **操作系统**: Linux / macOS / Windows - **编译器**: GCC 11+ / Clang 12+ / MSVC 2019+ - **CMake**: 3.30+ - **C++ 标准**: C++20 ### 第三方依赖 | 依赖 | 版本 | 说明 | |------|------|------| | muduo | latest | 网络库(server 部分) | | fmt | - | 字符串格式化(已包含) | | spdlog | - | 日志库(已包含) | ### 完整构建步骤 #### Linux / macOS ```bash # 安装 muduo(以 Ubuntu 为例) sudo apt-get install libmuduo-dev # 或者从源码编译 muduo git clone https://github.com/chenshuo/muduo.git cd muduo && ./build.sh && sudo ./build.sh install # 构建 HyperDB cd HyperDB mkdir build && cd build cmake .. make -j$(nproc) # 运行测试 make test # 或 ctest --output-on-failure ``` #### Windows ```powershell # 使用 Visual Studio Developer Command Prompt cd HyperDB mkdir build && cd build cmake .. -G "Visual Studio 17 2022" cmake --build . --config Release # 运行测试 ctest -C Release --output-on-failure ``` ### 运行主程序示例 ```bash cd build ./main/main # 输出示例: # [2026-04-01 18:00:00.000] [info] Starting Comprehensive Test... # [2026-04-01 18:00:00.001] [info] [1] Testing Basic CRUD... # [2026-04-01 18:00:00.002] [info] - Get user:1 Success: Alice # ... ``` ### 运行特定测试 ```bash # 运行 Redis 命令测试 ./test/test_redis_server # 运行 MVCC 和 WAL 测试 ./test/test_mvcc_wal # 运行引擎测试 ./test/test_engine ``` --- ## 配置参数 HyperDB 的核心配置参数位于 `engine/include/engine/engine.h`: ```cpp // 内存限制 constexpr space::MegaBytes LSM_TOTAL_MEM_SIZE_LIMIT(64); // 总内存上限 64MB constexpr space::MegaBytes LSM_PER_MEM_SIZE_LIMIT(4); // 单个 MemTable 4MB // 块缓存配置 constexpr space::KiloBytes LSM_BLOCK_MEM_SIZE_LIMIT(32); // 块大小 32KB inline constexpr size_t LSM_BLOCK_CACHE_CAPACITY = 1024; // 缓存容量 inline constexpr size_t LSM_BLOCK_CACHE_K = 8; // LRU-K 参数 // 层级压缩配置 inline constexpr int LSM_SST_LEVEL_RATIO = 4; // 层级容量增长比率 ``` 如需修改配置,直接编辑上述头文件后重新编译。 --- ## 常见问题 ### Q: 编译失败,提示找不到 muduo? **A:** 请确保已安装 muduo 网络库。在 Linux 上执行: ```bash sudo apt-get install libmuduo-dev # 或从源码安装 ``` ### Q: 如何调整内存使用? **A:** 修改 `engine/include/engine/engine.h` 中的 `LSM_TOTAL_MEM_SIZE_LIMIT` 和 `LSM_PER_MEM_SIZE_LIMIT` 参数。 ### Q: 如何查看日志? **A:** HyperDB 使用 spdlog 输出日志。日志级别可通过 `Logger::setLogLevel()` 设置: ```cpp Logger::setLogLevel(muduo::Logger::INFO); // 生产环境用 WARNING Logger::setLogLevel(muduo::Logger::DEBUG); // 调试用 ``` ### Q: Redis CLI 连接被拒绝? **A:** 检查: 1. HyperDBServer 是否正在运行 2. 端口是否被占用:`netstat -an | grep 6380` 3. 防火墙是否允许该端口 ### Q: 数据持久化在哪里? **A:** 数据存储在创建 HyperDB 时指定的目录下: ``` ./data_dir/ ├── wal/ # Write-Ahead Log ├── sst_*.0 # L0 层 SST 文件 ├── sst_*.1 # L1 层 SST 文件 └── ... ``` ### Q: 如何备份数据? **A:** 直接备份数据目录即可: ```bash cp -r ./data_dir ./data_dir_backup ``` --- ## 许可证 本项目基于 [MIT License](LICENSE) 开源。 --- ## 贡献指南 欢迎提交 Issue 和 Pull Request! 1. Fork 本仓库 2. 创建特性分支:`git checkout -b feature/xxx` 3. 提交更改:`git commit -m 'Add xxx feature'` 4. 推送分支:`git push origin feature/xxx` 5. 创建 Pull Request