3 个版本 (破坏性)

使用旧Rust 2015

0.4.0 2017年2月24日
0.2.0 2017年2月19日
0.1.0 2017年2月18日

#944 in 并发


用于 monotone-cli

Apache-2.0

35KB
931

monotone

Build Status

分布式系统中的配置管理计数器和队列

Monotone 是一个维护原子计数器和队列的库和 CLI。实现考虑了配置管理。注意,计数器不是用于事件跟踪的性能计数器。

包含两种实现

  1. 一个单进程实现,通过 Arc<Mutex<...>> 同步
  2. 一个使用乐观锁条件更新的 DynamoDb 实现

文档

https://docs.rs/monotone

构建 / 安装

源代码仓库包含两个项目。库名为 monotone,而 CLI 位于名为 cli 的文件夹中,尽管它构建了一个名为 monotone 的可执行文件。

您可以通过将其添加到 Cargo.toml 中的依赖项来链接到库,就像平常一样。选择 aws 功能以引入 rusoto 并使用 DynamoDb 后端。

默认情况下只是内存后端。

[dependencies]
monotone = { version = "0.4", features = ["aws"] }

笔记本电脑 / 开发环境中的 CLI

安装 rust。稳定的 rust 就可以,但至少应该是 1.15。

考虑使用 rustup: https://www.rustup.rs

然后运行 cargo install monotonehttps://crates.io 安装版本,或 cargo install --path=. 直接从签出的源安装。

CI / CD 中的 CLI

要么在你的 jenkins 上安装 rust 工具链,要么使用像这样的 docker 容器:https://hub.docker.com/r/jimmycuadra/rust/

然后像在您的开发环境中一样构建,并将构建的工件复制到安全的地方。

测试

monotone/tests”文件夹包含集成测试。"terraform”文件夹包含运行集成测试的基础设施定义。请参阅该目录下的readme文件。

命令行命令

每个计数器或队列都在DynamoDb表中的单独行中存储。"-i”参数选择哪一行。命令行会阻止你在队列上运行计数器命令,反之亦然。

计数器

计数器是一个简单的原子计数器。运行方式如下

monotone -i mycounter counter get

将返回

{
  "id": "mycounter",
  "value": 0,
  "region": "eu-west-1",
  "table": "Counters"
}

如下方式增加计数器

monotone -i mycounter counter next

将返回

{
  "id": "mycounter",
  "value": 1,
  "region": "eu-west-1",
  "table": "Counters"
}

队列

队列是字符串进程ID的列表。队列中的每个条目在加入列表时都会赋予单调计数器的值。列表按计数器的升序排序。

队列包含一个围栏令牌,该令牌由所有操作返回。这将随着对存储的每次写入单调递增。请使用此令牌在系统中进行条件更新,以防止对队列的过时视图采取行动。

如下方式将进程ID添加到队列中

monotone -i myqueue queue -p foo join

输出将类似于以下内容

{
  "id": "myqueue",
  "region": "eu-west-1",
  "table": "Counters",
  "fencing_token": 1,
  "ticket": {
    "process_id": "foo",
    "counter": 1,
    "position": 0
  }
}

您还可以删除节点(为了整洁)如下

monotone -i myqueue queue -p foo leave

这将打印输出

{
  "id": "myqueue",
  "region": "eu-west-1",
  "table": "Counters",
  "fencing_token": 2
}

要列出节点,请使用

monotone -i myqueue queue list

输出将类似于以下内容

{
  "id": "myqueue",
  "region": "eu-west-1",
  "table": "Counters",
  "fencing_token": 2,
  "tickets": [
    {
      "process_id": "foo",
      "counter": 1,
      "position": 0
    }
  ]
}

示例用例

将服务器ID分配给Zookeeper集群中的节点

Zookeeper是一个存储类似于在该crate中实现的原子计数器的理想之地。但如果你还没有Zookeeper集群,正在尝试构建一个集群呢?你必须建立在你已有的东西上,比如DynamoDb。

在第一次启动时,像这样运行命令行的队列命令(务必确保你的主机名是唯一的,例如EC2实例ID!)

monotone -i myzkcluster queue -p $(hostname -f) join | jq .ticket.counter

将结果值写入"/etc/zookeeper/conf/myid",适当地。

请注意,Zookeeper文档表示服务器ID必须在0到255之间。Monotone使用u64整数的完整范围。

简单的领导者选举或锁

队列中的节点列表足以指派一个特殊的进程或领导者。

只需使用队列中的第一个进程。

有几个限制

  1. 没有检查存活性的机制来从队列中删除失败的进程
  2. 您必须使用围栏令牌来确保在充当领导者/持有锁时队列没有更改。

依赖关系

~10-20MB
~349K SLoC