#key-value-database #key-value #database-server #embedded-database #server #client

bin+lib yedb

坚固的免崩溃嵌入式和客户端/服务器键值数据库

47个版本

0.4.15 2024年3月3日
0.4.14 2023年12月29日
0.4.13 2023年5月31日
0.4.12 2023年3月25日
0.0.3 2021年2月24日

#146数据库接口

Download history 129/week @ 2024-04-28 1/week @ 2024-05-26 10/week @ 2024-06-30 30/week @ 2024-07-07 11/week @ 2024-07-14 324/week @ 2024-07-28

每月375次下载
用于 2 crate

Apache-2.0

195KB
4.5K SLoC

yedb - 坚固的免崩溃嵌入式和客户端/服务器键值数据库(Rust实现)

Cargo crate

crates.io/crates/yedb

功能

  • client-sync 同步客户端
  • client-async 异步客户端
  • cli yedb-cli
  • server yedb-server

为什么选择YEDB?

  • 它快吗?

  • Rust版本相当快,但如果是自动刷新启用,写入仍然较慢。

  • 它智能吗?

  • 那么YEDB是用来做什么的?

  • YEDB超可靠、线程安全且非常易于使用。

  • 我不喜欢Rust

  • 有其他实现

Power loss data survive demo

https://www.youtube.com/watch?v=i3hSWjrNqLo

YEDB是一个绝对可靠的坚固键值数据库,可以在任何电源损失的情况下生存,除非操作系统文件系统损坏。键数据以非常可靠的方式保存,并立即刷新到磁盘(这可以禁用以加快引擎但不建议这么做——为什么YEDB会被使用)。

Rust版本特性

  • Rust版本建立在Serde框架之上。

  • 所有键值都是serde_json::Value对象。

  • 支持的存储序列化格式:JSON(默认)、YAML、MessagePack和CBOR。

  • 由于当前serde_json::Value不支持字节类型,Rust版本无法处理字节键值。

  • 包含:嵌入式库、异步服务器和命令行客户端(仅支持TCP/Unix套接字)。

  • 命令行客户端非常基本。如果您需要更多功能,请使用yedb Python CLI

超过YEDB规范的功能

  • "delete"命令不会删除键,而是将它们移动到.trash文件夹

  • 在调用"purge"方法时清理.trash文件夹。

  • "auto_bak"属性告诉服务器在键数据修改时自动创建键版本的备份

  • "bak"键是隐藏的

客户端/服务器

可在发布页面找到二进制文件。

运行服务器

./yedb-server /tmp/db1

使用客户端

# get server info
./yedb-cli info
# set key value
./yedb-cli set x 5 -p number
# list all keys
./yedb-cli ls /
# edit key with $EDITOR
./yedb-cli edit x
# get key as JSON
./yedb-cli get x
# get help for all commands
./yedb-cli -h

代码示例

可以使用任何类型的Lock/Mutex安全地在线程之间共享数据库/客户端对象。

嵌入式示例

use yedb::Database;
use serde_json::Value;

let mut db = Database::new();
db.set_db_path("/tmp/db1").unwrap();
db.open().unwrap();
let key_name = "test/key1";
db.key_set(&key_name, Value::from(123_u8)).unwrap();
println!("{:?}", db.key_get(&key_name));
db.key_delete(&key_name).unwrap();
db.close().unwrap();

TCP/Unix套接字客户端示例

use yedb::YedbClient;
use serde_json::Value;

let mut client = YedbClient::new("tcp://127.0.0.1:8870");
let key_name = "test/key1";
client.key_set(&key_name, Value::from(123_u8)).unwrap();
println!("{:?}", client.key_get(&key_name));
client.key_delete(&key_name).unwrap();

异步TCP/Unix套接字客户端示例

use serde_json::Value;
use yedb::{YedbClientAsync, YedbClientAsyncExt};

async fn test() {
    let mut client = YedbClientAsync::new("tcp://127.0.0.1:8870");
    let key_name = "test/key1";
    client.key_set(&key_name, Value::from(123_u8)).await.unwrap();
    println!("{:?}", client.key_get(&key_name).await);
    client.key_delete(&key_name).await.unwrap();
}

异步TCP/Unix套接字客户端池示例

use serde_json::Value;
use std::sync::Arc;
use std::time::Duration;
use yedb::{YedbClientPoolAsync, YedbClientAsyncExt};

async fn test() {
    let pool = Arc::new(
        YedbClientPoolAsync::create()
            .size(10)
            .path("tcp://127.0.0.1:8870")
            .retries(3)
            .timeout(Duration::from_secs(2))
            .build()
    );
    let mut futs = Vec::new();
    for i in 0..10 {
        let task_pool = pool.clone();
        let fut = tokio::spawn(async move {
            let mut client = task_pool.get().await;
            let key = format!("test/key{}", i);
            client.key_set(&key, Value::from(i)).await.unwrap();
            println!("{}", client.key_get(&key).await.unwrap());
            client.key_delete(&key).await.unwrap();
        });
        futs.push(fut);
    }
    for fut in futs {
        fut.await.unwrap();
    }
}

规范

yedb.bma.ai

一些基准数据

  • CPU: 英特尔酷睿i7-8550U (4核心)
  • 驱动器: 三星 MZVLB512HAJQ-000L7 (NVMe)
  • auto_flush: false
  • 连接: Unix套接字
  • 服务器工作者: 2
  • 客户端线程: 4
set/number: 8164 ops/sec
set/string: 7313 ops/sec
set/array: 7152 ops/sec
set/object: 5272 ops/sec

get/number: 49709 ops/sec
get/string: 33338 ops/sec
get/array: 31426 ops/sec
get/object: 11654 ops/sec

get(cached)/number: 122697 ops/sec
get(cached)/string: 61206 ops/sec
get(cached)/array: 59309 ops/sec
get(cached)/object: 34583 ops/sec

increment: 7079 ops/sec

依赖

~15–35MB
~569K SLoC