Skip to content

nicedvx/mini-bitcask

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mini-bitcask

一个轻量级的 Bitcask 键值存储引擎,使用 Rust 实现。

功能特性

  • 核心操作: putgetdelete,O(1) 磁盘寻址
  • 原子批量写入: WriteBatch 支持事务操作,保证 ACID 特性
  • 迭代器支持: 前缀过滤、反向迭代、fold 操作
  • 数据压缩: Merge 操作回收已删除/更新键的磁盘空间
  • 多种索引类型:
    • BTree(默认,内存索引)
    • SkipList(内存索引,并发友好)
    • B+Tree(持久化索引,基于 jammdb)
  • 灵活的 I/O 方式:
    • 标准文件 I/O
    • 内存映射 I/O(mmap),加速启动
  • 数据完整性: CRC32 校验确保日志记录完整
  • 并发安全: 细粒度锁实现线程安全
  • 进程安全: 文件锁防止多实例同时访问

架构

┌─────────────────────────────────────────────────────────┐
│                        Engine                           │
├─────────────────────────────────────────────────────────┤
│  ┌─────────────┐   ┌─────────────┐   ┌─────────────┐   │
│  │    Index    │   │ Active File │   │ Older Files │   │
│  │  (BTree/    │   │   (写入)    │   │   (只读)    │   │
│  │  SkipList/  │   │             │   │             │   │
│  │  B+Tree)    │   │             │   │             │   │
│  └──────┬──────┘   └──────┬──────┘   └──────┬──────┘   │
│         │                 │                  │          │
│         └────────────────>│<─────────────────┘          │
│                      Log Records                        │
│               (key, value, type, crc)                   │
└─────────────────────────────────────────────────────────┘

快速开始

安装

Cargo.toml 中添加依赖:

[dependencies]
bitcask = { path = "path/to/mini-bitcask" }

基本使用

use bitcask::{db::Engine, options::Options};
use bytes::Bytes;

fn main() {
    // 使用默认配置打开存储引擎
    let opts = Options::default();
    let engine = Engine::open(opts).expect("failed to open engine");

    // 写入数据
    engine.put(Bytes::from("name"), Bytes::from("bitcask")).unwrap();

    // 读取数据
    let value = engine.get(Bytes::from("name")).unwrap();
    println!("value: {:?}", String::from_utf8(value.to_vec()));

    // 删除数据
    engine.delete(Bytes::from("name")).unwrap();
}

批量操作

use bitcask::{db::Engine, options::{Options, WriteBatchOptions}};
use bytes::Bytes;

fn main() {
    let engine = Engine::open(Options::default()).unwrap();

    // 创建批量写入
    let wb = engine.new_write_batch(WriteBatchOptions::default()).unwrap();

    // 批量写入操作
    wb.put(Bytes::from("key1"), Bytes::from("value1")).unwrap();
    wb.put(Bytes::from("key2"), Bytes::from("value2")).unwrap();
    wb.delete(Bytes::from("old_key")).unwrap();

    // 原子提交
    wb.commit().unwrap();
}

迭代器

use bitcask::{db::Engine, options::{Options, IteratorOptions}};

fn main() {
    let engine = Engine::open(Options::default()).unwrap();

    // 使用前缀过滤迭代
    let iter_opts = IteratorOptions {
        prefix: b"user:".to_vec(),
        reverse: false,
    };

    let iter = engine.iter(iter_opts);
    while let Some((key, value)) = iter.next() {
        println!("{:?} -> {:?}", key, value);
    }

    // fold 操作
    engine.fold(|key, value| {
        println!("{:?}: {:?}", key, value);
        true // 继续迭代
    }).unwrap();
}

配置选项

use bitcask::options::{Options, IndexType, IOType};
use std::path::PathBuf;

let opts = Options {
    dir_path: PathBuf::from("/data/bitcask"),     // 数据库目录
    data_file_size: 256 * 1024 * 1024,            // 单个数据文件大小,256MB
    sync_writes: false,                            // 每次写入是否持久化
    bytes_per_sync: 0,                             // 累计写入多少字节后持久化(0 表示禁用)
    index_type: IndexType::BTree,                  // 索引类型
    mmap_at_startup: true,                         // 启动时使用 mmap 加速加载
    data_file_merge_ratio: 0.5,                    // 可回收空间达到 50% 时触发 merge
};

索引类型对比

类型 存储位置 适用场景
BTree 内存 通用场景,性能均衡
SkipList 内存 高并发写入场景
BPlusTree 磁盘 数据量大、内存有限场景

子项目

bitcask-http

基于 Actix-web 的 HTTP API 服务。

cd bitcask-http
cargo run

API 接口:

  • POST /bitcask/put - 存储键值对(JSON 请求体)
  • GET /bitcask/get/{key} - 根据 key 获取 value
  • DELETE /bitcask/delete/{key} - 删除 key
  • GET /bitcask/listkeys - 列出所有 key
  • GET /bitcask/stat - 获取数据库统计信息

bitcask-redis

兼容 Redis 协议的服务,支持常用数据结构。

cd bitcask-redis
cargo run

支持的命令:

  • String: SETGET
  • Hash: HSET
  • Set: SADD
  • List: LPUSH
  • Sorted Set: ZADD

使用任意 Redis 客户端连接:

redis-cli -p 6380
> SET name bitcask
OK
> GET name
"bitcask"

性能测试

运行基准测试:

cargo bench

项目结构

mini-bitcask/
├── src/
│   ├── lib.rs           # 库入口
│   ├── db.rs            # 核心 Engine 实现
│   ├── options.rs       # 配置选项
│   ├── batch.rs         # WriteBatch 原子批量写入
│   ├── iterator.rs      # 迭代器实现
│   ├── merge.rs         # 数据压缩
│   ├── errors.rs        # 错误类型
│   ├── data/            # 数据文件处理
│   │   ├── data_file.rs # 数据文件操作
│   │   └── log_record.rs# 日志记录编解码
│   ├── fio/             # 文件 I/O 抽象
│   │   ├── file_io.rs   # 标准文件 I/O
│   │   └── mmap.rs      # 内存映射 I/O
│   └── index/           # 索引实现
│       ├── btree.rs     # BTree 索引
│       ├── skiplist.rs  # SkipList 索引
│       └── bptree.rs    # B+Tree 索引
├── bitcask-http/        # HTTP API 服务
├── bitcask-redis/       # Redis 兼容服务
├── examples/            # 使用示例
└── benches/             # 性能测试

参考资料

致谢

感谢 RoseDB Labs 组织的开源项目和技术分享,本项目的实现参考了其设计思路。

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages