3 个版本 (破坏性更新)

使用旧的 Rust 2015

0.2.0 2016 年 1 月 19 日
0.1.0 2015 年 10 月 20 日
0.0.1 2015 年 9 月 17 日

数据库接口 中排名第 1717

Apache-2.0

5MB
8K SLoC

Rasputin DB 🌐

(目前“tyler_ranges”分支正在进行大量工作)

灵活的可线性化分布式存储

三巨头:运营清晰性、性能和可组合性

当前实现:线性化的 KV 集合/获取/替换/删除。客户端代码仅适用于理想路径,因此目前仅适合玩耍!

不推荐使用此项目的理由

  1. 大部分未实现。我们还没有支持自动分片、真实事务或其他除 KV 之外的集合类型。这些仍在规划阶段。
  2. 可能不正确。我们尚未证明核心共识算法的正确性。我们可能能够将 Raft Coq 证明适应于此目的,因为我们本质上是用非抢占性租约替换了 Raft 的可抢占领导权,以在存在部分分区的情况下提高吞吐量。
  3. 效率低下。写路径涉及大量的复制。我们正在设计一个更高效的缓冲区管理系统。
  4. 有缺陷。客户端代码是一个完整的黑客工具,偶尔才能正常工作。我们有一个模拟器用于调试状态机中的错误,但我们还没有用它来模拟常见的数据中心条件,如分区、延迟消息到达、节点重启/关闭/暂停等...
  5. 未记录。
  6. 不受欢迎。没有社区和没有生产用户(或者,至少我希望还没有人使用它!)

运行

运行测试集群
cargo build
./run.sh
tail -f _rasputin_test/*log
运行单个服务器
target/debug/rasputind \
    --peer-port=7777 \
    --cli-port=8888 \
    --seed-peers="127.0.0.1:7777" \
    --storage-dir=/var/lib/rasputin/ \
    --logfile=/var/log/rasputin.log
使用远程客户端对集群进行打击!

Cargo.toml

[dependencies]
rasputin = "0.1.0"

代码

extern crate rasputin;

fn main() {
    let peers = vec!["127.0.0.1:8888".parse().unwrap()];
    let nthreads = 1;
    let mut cli = rasputin::Client::new(peers, nthreads);

    cli.set(b"k1", b"v1").unwrap();
    assert!(cli.get(b"k1").unwrap().get_value() == b"v1");

    // CAS returns the current value, and sets the success flag accordingly
    assert!(cli.cas(b"k1", b"v1", b"v12").unwrap().get_value() == b"v12");
    assert!(cli.cas(b"k1", b"vNever", b"vNever2").unwrap().get_value() == b"v12");
    assert!(cli.cas(b"k1", b"vNever", b"vNever2").unwrap().get_success() == false);
    assert!(cli.cas(b"k1", b"v12", b"v13").unwrap().get_value() == b"v13");

    // deletes return the last value
    assert!(cli.del(b"k1").unwrap().get_value() == b"v13");
    assert!(cli.get(b"k1").unwrap().get_success() == false);
}

计划工作

自动字典顺序分片

Rasputin 将利用分片大小和请求数密度指标来促进智能拆分。

几种简单的持久化集合类型
  1. kv:由 RocksDB 支持
  2. 日志:类似 Kafka 的顺序段文件
  3. 对象:系统 VFS 上的文件
兴趣语义
  • 订阅:顺序突变流
  • 监视:最多一次突变通知
复制模式(每集合)
  1. 共识:突变在复制到法定多数之前阻塞
  2. 异步:突变快速返回,并在稍后复制
时间序列原语
  • 对数桶分组的直方图,用于高效聚合和消费极高速度的指标,类似于 loghisto

路线图

  • mio 事件循环
  • 领导者选举
  • rocksdb 持久化层
  • 日志复制
  • multi-paxos 共识
  • 简单的 KV 客户端操作
  • 可重新配置的成员资格
  • 范围分割
  • Mesos 框架
  • c/jvm/python/ruby/go 客户端库

附录:Harpoon 共识算法

因为 Rasputin 旨在尽可能成为通用的复制机制,它需要能够抵御分区。我们旨在尽可能多地重用 Raft 中适用于此的部分,并用基于租约的机制替换领导者选举机制,该机制在存在部分分区的情况下不会抢占。这显然需要广泛测试,为此正在构建一个综合模拟器以测试状态机(参见 test/cluster.rs),并且正在构建故障注入工具以在非模拟集群上诱导真实数据中心条件。

当领导者与任何其他节点之间存在部分分区时,Raft 易受快速领导者轮换的影响。部分分区的节点将触发其领导者选举计时器并收到法定多数。因为旧领导者无法与这个新领导者通信,它也会这样做。领导权波动很大,我们的吞吐量不理想。Harpoon 实质上只是经过修改的选举机制的 Raft:候选人和领导者从所有对等节点请求租约,如果他们达到法定多数,则延长领导权;如果他们在租约结束时没有达到成功扩展请求响应的法定多数,则放弃领导权。这防止了在存在部分分区的情况下发生领导权轮换,例如在开放的互联网上这是常见的。

Harpoon 尚未经过形式化验证,但最终我们将为它适配 Raft Coq 证明。

依赖关系

~10MB
~192K SLoC