9 个不稳定版本 (3 个重大更改)
0.5.0 | 2024 年 7 月 6 日 |
---|---|
0.4.1 | 2024 年 1 月 3 日 |
0.4.0 | 2023 年 12 月 27 日 |
0.3.1 | 2022 年 9 月 16 日 |
0.2.1 | 2021 年 2 月 13 日 |
#227 在 算法
42KB
727 行
sequence-generator-rust
基于 Twitter 服务器 ID(以前称为雪花)的概念构建的 64 位 IDs 序列生成器。使用 Rust 构建
目录
安装
git clone https://github.com/drconopoima/sequence-generator-rust.git
cd sequence-generator-rust
cargo build --release
二进制文件在 target/release/sequence-generator-rust
下生成
描述
您可以根据时间戳、序列号和节点/工作者 ID(基于 Twitter 雪花)生成顺序 ID
默认情况下,此包格式定义
- 最低 9 位用于存储工作者和/或主机信息(最多 512 个)
- 随后,11 位用于存储序列号(最多 2048 个)
- 最高 44 位用于存储自定义纪元,精度为每毫秒 10 个样本(10^-1)。这足以从自定义纪元存储 55 年
- 没有位是空闲的。
- 自定义纪元设置为当前十年开始(2020-01-01)
用法
以下方式生成单个序列号,通过 .env
文件设置工作者 ID(默认 0)
$ cargo run \
0: 731587959438966784
生成多个序列值(-n|--number
),提供自定义工作者 ID(--node-id
),并测量耗时(-d|--debug
)
cargo run --release -- -n 8 --node-id 505 --debug
0: 731586108621586937
1: 731586108621587449
2: 731586108621587961
3: 731586108621588473
4: 731586108621588985
5: 731586108621589497
6: 731586108621590009
7: 731586108621590521
It took 661 nanoseconds
序列的每个参数都是可定制的。
默认情况下,原始 Twitter 雪花格式定义
- 1 位未使用(符号)
- 41 位用于存储自定义纪元,精度为毫秒(10^3 微秒,从自定义纪元开始 69 年)
- 10 位用于存储工作者和数据中心信息(最多 1024 个)
- 12 位用于存储序列号(最多 4096 个)
- 使用自定义的纪元1288834974657或2010年11月04日 01:42:54。
通过传递以下命令参数,可以完美且轻松地重新创建Twitter的雪花。
$ cargo run --release -- -n 8 -d --unused-bits 1 --node-id-bits 10 --sequence-bits 12 --micros-ten-power 3 --custom-epoch '2010-11-04T01:42:54Z' --node-id 128
0: 137870923482005632
1: 137870923482006656
2: 137870923482007680
3: 137870923482008704
4: 137870923482009728
5: 137870923482010752
6: 137870923482011776
7: 137870923482012800
It took 571 nanoseconds
整数在二进制级别的特定结构包括
- 最左边的位(可自定义,默认为无)可能未被使用,并设置为0。
- 第二组位以自定义的指数形式存储时间戳(默认为44位,每100微秒采样一次,相当于参数
--micros-ten-power 2
)。您不能直接自定义时间戳的位数,但可以通过间接设置其他位组的不同值来间接实现。 - 第三组位存储序列(默认为11位)
- 最右边的位组存储主机/工作ID(默认为9位)
您还可以通过dotenv
文件进行自定义。将文件.env-example
复制到.env
cp .env-example .env
并将示例值更改为您喜欢的。
通过命令行启动参数分配的参数的优先级最高,未分配的参数可以通过使用.env
文件来获取,如果仍然有未分配的参数,则使用上面描述的默认值。
支持的唯一自定义纪元格式是RFC-3339/ISO-8601
,无论是作为CLI参数还是从dotenv文件中。
请参阅辅助位结构分析以获取生成的值的详细分析。
基准测试
请参阅辅助基准测试笔记
库
use std::time::UNIX_EPOCH;
use ::sequence_generator::*;
let custom_epoch = UNIX_EPOCH; // SystemTime object representing custom epoch time. Use checked_add(Duration) for different time
let node_id_bits = 10; // 10-bit node/worker ID
let sequence_bits = 12; // 12-bit sequence
let unused_bits = 1; // unused (sign) bits at the start of the ID. 1 or 0 generally
let micros_ten_power = 3; // Operate in milliseconds (10^3 microseconds)
let node_id = 500; // Current worker/node ID
let cooldown_ns = 1500; // initial time in nanoseconds for exponential backoff wait after sequence is exhausted
// Generate SequenceProperties
let properties = sequence_generator::SequenceProperties::new(
custom_epoch,
node_id_bits,
node_id,
sequence_bits,
micros_ten_power,
unused_bits,
cooldown_ns,
);
// Generate an ID
let id = sequence_generator::generate_id(&properties).unwrap();
// Decode ID
// Timestamp
let timestamp_micros = sequence_generator::decode_id_unix_epoch_micros(id, &properties);
// Sequence
let sequence = sequence_generator::decode_sequence_id(id, &properties);
// Node ID
let id_node = sequence_generator::decode_node_id(id, &properties);
支持
如有支持需求,请打开一个问题。
变更日志
请参阅变更日志
贡献
请使用Github Flow进行贡献。创建分支,添加提交,并打开一个拉取请求。
依赖项
~4MB
~75K SLoC