#id-generator #snowflake-id #id #snowflake #generator #distributed-systems #generate

sinteflake

受Snowflake启发的64位ID生成器,但生成非常独特的数字

1个不稳定版本

0.1.0 2024年8月6日

#469 in 算法

Download history 71/week @ 2024-07-31 46/week @ 2024-08-07

每月117次下载

Apache-2.0

41KB
664

SINTEFlake

SINTEFlake是一个64位ID生成器,受Twitter的Snowflake和Sony的Sonyflake的启发。

它生成的标识符以哈希或伪随机数开头,而不是时间戳。标识符不是大致按时间顺序排列,而是非常独特的数字。

功能

  • 生成具有唯一值的64位ID
  • 允许分布式系统自定义实例ID
  • 提供基于哈希的ID生成
  • 支持同步和异步环境

结构

SINTEFlake ID由以下部分组成

  • 14位用于哈希或随机数。
  • 31位用于8秒分辨率的时钟。
  • 10位用于实例标识符。
  • 8位用于序列号。

这总共是63位,以在使用有符号64位整数时只保留正数。

安装

将此添加到您的 Cargo.toml

[dependencies]
sinteflake = "0.1"

用法

use sinteflake::{next_id, next_id_with_hash, set_instance_id, update_time};

set_instance_id(42)?;

let id_a = next_id()?;
let id_b = next_id()?;

let id_c = next_id_with_hash(&[1, 2, 3])?;
let id_d = next_id_with_hash(&[1, 2, 3])?;

update_time()?;

异步用法

[dependencies]
sinteflake = { version = "0.1", features = ["async"] }
tokio = { version = "1", features = ["full"] }
use sinteflake::{next_id_async, next_id_with_hash_async, set_instance_id_async, update_time_async};

set_instance_id_async(42).await?;

let id = next_id_async().await?;
let id = next_id_with_hash_async(&[1, 2, 3]).await?;

update_time_async().await?;

请注意,默认情况下未启用async功能,并且set_instance_id_async不会设置非异步版本的实例ID。

自定义设置

您可以使用自己的设置创建自定义SINTEFlake实例

use sinteflake::sinteflake::SINTEFlake;
use time::OffsetDateTime;

let mut instance = SINTEFlake::custom(
    42,                                                      // instance_id
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], // hash key
    123,                                                     // counter hash key
    OffsetDateTime::from_unix_timestamp(1719792000)?,        // epoch
)?;

let id_a = instance.next_id()?;
// ...

非时间顺序

与Snowflake(和Sonyflake)不同,SINTEFlake并不打算大致按时间顺序排列。SINTEFlake生成的ID序列将具有非常不同的值。这对于在垂直数据库中处理区域映射等操作非常有用。

时间戳的精度仅为8秒。此外,时间戳位数的排列使得数字不稳定。因此,无法使用标识符进行排序。它将在大约544年后溢出,这应该足够长了。

这种设计选择与Snowflake相比,在内存使用和复杂性方面略有增加,因为需要跟踪更多数字以处理冲突。不是大致按时间顺序排列也是许多情况下的缺点。

这不是CryptoSecure

仅用64位无法实现密码学安全。SINTEFLake标识符本身并不安全,因为它们不够长且容易遭受暴力破解。

参考,使用的哈希算法是SIPHash 2-4。时间戳排列表使用π和e的数字,应该是袖子里没有东西足够的。

考虑使用UUIDs

UUIDs非常棒,但有点大。有时,你宁愿用64位而不是128位。这可以用于进行小的性能改进,或者与不支持128位数字的原生系统一起工作。64位数字通常比字符串或字节数组计算得更快。

然而,UUIDs几乎是更好的选择,应该优先考虑。

测试

cargo test
cargo llvm-cov # Coverage report
cargo bench # Benchmark
cargo bench --bench=bench -- --quick # Quick benchmark

许可证

本项目采用Apache许可证,版本2.0。有关详细信息,请参阅LICENSE文件。

贡献

欢迎贡献!请随时提交拉取请求。

依赖关系

~2–8.5MB
~76K SLoC