Rust分布式ID生成库svix-ksuid的使用,svix-ksuid提供高性能、可排序的全局唯一标识符生成方案

Rust分布式ID生成库svix-ksuid的使用

Svix logo

Svix-KSUID是一个纯Rust实现的KSUID库,完全兼容Segment公司的KSUID实现,并提供高性能、可排序的全局唯一ID生成方案。

什么是KSUID?

KSUID是一种K排序的UID,它存储了日期组件,因此可以基于创建时间进行近似排序。

基本用法

首先添加依赖:

[dependencies]
svix-ksuid = "^0.6.0"

基本示例代码:

use svix_ksuid::*;

let ksuid = Ksuid::new(None, None);
println!("{}", ksuid.to_string());
// 输出示例: 1srOrx2ZWZBpBUvZwXKQmoEYga2

高精度时间模式

标准KSUID只有1秒精度,库还提供了高精度模式(精度可达4ms):

use svix_ksuid::*;

let ksuid = KsuidMs::new(None, None);

可选特性

  • serde - 添加序列化/反序列化支持
[dependencies]
svix-ksuid = { version = "^0.6.0", features = ["serde"] }

完整示例代码

use svix_ksuid::*;
use chrono::Utc;

fn main() {
    // 1. 基本使用
    let ksuid = Ksuid::new(None, None);
    println!("基本KSUID: {}", ksuid.to_string());
    
    // 2. 高精度模式
    let ksuid_ms = KsuidMs::new(None, None);
    println!("高精度KSUID: {}", ksuid_ms.to_string());
    
    // 3. 转换KSUID
    println!("Base62: {}", ksuid.to_string());
    println!("Bytes: {:?}", ksuid.bytes());
    println!("Timestamp: {:?}", ksuid.timestamp());
    println!("Timestamp seconds: {}", ksuid.timestamp_seconds());
    println!("Payload: {:?}", ksuid.payload());
    
    // 4. 创建指定参数的KSUID
    let bytes = [12u8; Ksuid::PAYLOAD_BYTES];
    let ksuid_custom = Ksuid::new(Some(Utc::now()), Some(&bytes));
    println!("自定义KSUID: {}", ksuid_custom.to_string());
    
    // 5. 从Base62字符串创建
    let base62 = "1srOrx2ZWZBpBUvZwXKQmoEYga2";
    let ksuid_from_str = Ksuid::from_str(base62).unwrap();
    println!("从字符串解析: {:?}", ksuid_from_str);
    
    // 6. 比较KSUID
    let ksuid1 = Ksuid::from_seconds(Some(1_555_555_555), None);
    let ksuid2 = Ksuid::from_seconds(Some(1_777_777_777), None);
    assert!(ksuid1 < ksuid2);
}

特性说明

  • 生成ID包含时间戳信息,可按时间排序
  • 提供标准(1秒精度)和高精度(4ms精度)两种模式
  • 支持多种格式转换(Base62/字节数组等)
  • 线程安全,适合分布式环境使用

该库遵循MIT许可证,所有权利归Svix webhooks服务所有。


1 回复

Rust分布式ID生成库svix-ksuid使用指南

简介

svix-ksuid是一个Rust实现的KSUID(可排序唯一标识符)生成库,提供高性能、可排序的全局唯一ID生成方案。KSUID结合了时间戳和随机数据,具有以下特点:

  • 按时间排序:ID包含时间戳信息,可以按生成时间排序
  • 分布式安全:不依赖中心节点,可在分布式系统中安全使用
  • 高可读性:使用Base62编码,比UUID更短更友好

安装

在Cargo.toml中添加依赖:

[dependencies]
svix-ksuid = "0.8.0"

基本使用

生成KSUID

use svix_ksuid::*;

fn main() {
    // 生成一个新的KSUID
    let ksuid = Ksuid::new(None, None);
    println!("KSUID: {}", ksuid.to_string());
    
    // 输出示例: 1tOZ6ogSpC2Z7wQdF2V3jR4Xb5e
}

从字符串解析KSUID

let ksuid_str = "1tOZ6ogSpC2Z7wQdF2V3jR4Xb5e";
let ksuid = Ksuid::from_str(ksuid_str).unwrap();
println!("Parsed KSUID: {:?}", ksuid);

获取KSUID的组成部分

let ksuid = Ksuid::new(None, None);

// 获取时间戳(Unix秒)
println!("Timestamp: {}", ksuid.timestamp());

// 获取有效负载(随机部分)
println!("Payload: {:?}", ksuid.payload());

// 获取生成时间
println!("Generated at: {:?}", ksuid.datetime());

高级用法

自定义时间戳和有效负载

use std::time::{SystemTime, UNIX_EPOCH};

// 自定义时间戳(Unix秒)
let timestamp = SystemTime::now()
    .duration_since(UNIX_EPOCH)
    .unwrap()
    .as_secs();

// 自定义有效负载(16字节)
let payload = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];

let ksuid = Ksuid::new(Some(timestamp), Some(&payload));
println!("Custom KSUID: {}", ksuid);

批量生成KSUID

use svix_ksuid::KsuidLike;

let start_time = 1_600_000_000; // 自定义起始时间戳

// 批量生成10个KSUID
let ksuids = (0..10)
    .map(|_| Ksuid::new(Some(start_time), None))
    .collect::<Vec<_>>();

for ksuid in ksuids {
    println!("{}", ksuid);
}

比较和排序

let ksuid1 = Ksuid::new(None, None);
std::thread::sleep(std::time::Duration::from_secs(1));
let ksuid2 = Ksuid::new(None, None);

assert!(ksuid1 < ksuid2); // 按时间排序

性能考虑

svix-ksuid经过优化,性能很高:

  • 在大多数现代CPU上每秒可生成数百万个ID
  • 不依赖系统调用或阻塞操作
  • 线程安全,可在多线程环境中使用

适用场景

  1. 分布式系统需要全局唯一ID
  2. 需要按时间排序的ID场景
  3. 数据库主键生成
  4. 日志追踪和事件溯源

与其他ID方案的比较

  • 相比UUID:更短、可排序、更高性能
  • 相比Snowflake:不依赖中心节点、更简单
  • 相比MongoDB ObjectID:更通用、不绑定特定数据库

完整示例代码

use svix_ksuid::*;
use std::time::{SystemTime, UNIX_EPOCH};
use std::thread;

fn main() {
    // 1. 基本使用示例
    println!("=== 基本使用示例 ===");
    
    // 生成KSUID
    let ksuid = Ksuid::new(None, None);
    println!("生成的KSUID: {}", ksuid);
    
    // 从字符串解析
    let ksuid_str = ksuid.to_string();
    let parsed_ksuid = Ksuid::from_str(&ksuid_str).unwrap();
    println!("解析后的KSUID: {:?}", parsed_ksuid);
    
    // 获取组成部分
    println!("时间戳: {}", ksuid.timestamp());
    println!("有效负载: {:?}", ksuid.payload());
    println!("生成时间: {:?}", ksuid.datetime());
    
    // 2. 高级用法示例
    println!("\n=== 高级用法示例 ===");
    
    // 自定义时间戳和有效负载
    let timestamp = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .unwrap()
        .as_secs();
    let payload = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
    let custom_ksuid = Ksuid::new(Some(timestamp), Some(&payload));
    println!("自定义KSUID: {}", custom_ksuid);
    
    // 批量生成
    println!("\n批量生成KSUID:");
    let batch_ksuids = (0..5)
        .map(|_| Ksuid::new(None, None))
        .collect::<Vec<_>>();
    for k in batch_ksuids {
        println!("{}", k);
    }
    
    // 比较和排序
    let ksuid_early = Ksuid::new(None, None);
    thread::sleep(std::time::Duration::from_secs(1));
    let ksuid_late = Ksuid::new(None, None);
    
    println!("\n比较结果:");
    println!("ksuid_early: {}", ksuid_early);
    println!("ksuid_late: {}", ksuid_late);
    println!("ksuid_early < ksuid_late: {}", ksuid_early < ksuid_late);
}

这个完整示例演示了svix-ksuid库的所有主要功能,包括基本使用和高级用法。示例中包含了生成KSUID、解析字符串、获取ID组成部分、自定义时间戳和有效负载、批量生成以及比较排序等功能。

回到顶部