Project Icon

ksuid

Go语言高效全局唯一标识符生成库KSUID

ksuid是一个Go语言库,用于生成和解析可排序的唯一标识符KSUID。该库提供自然排序、无冲突和无依赖的标识符,具有高度可移植性。经过生产环境验证和性能优化,ksuid提供丰富的接口和命令行工具,适用于多种场景的唯一标识需求。

ksuid Go 报告卡 GoDoc Circle CI

ksuid 是一个高效、全面、经过实战检验的 Go 库,用于生成和解析一种特定类型的全局唯一标识符,称为 KSUID。这个库作为其参考实现。

安装

go get -u github.com/segmentio/ksuid

什么是 KSUID?

KSUID 代表可排序的唯一标识符(K-Sortable Unique IDentifier)。它是一种类似于 RFC 4122 UUID 的全局唯一标识符,从底层设计上就能够按生成时间戳"自然"排序,无需任何特殊的类型感知逻辑。

简而言之,通过 UNIX sort 命令对一组 KSUID 进行排序,将得到按生成时间排序的列表。

为什么使用 KSUID?

生成唯一标识符的方法有很多,为什么选择 KSUID?

  1. 自然按生成时间排序
  2. 无冲突、无需协调、无依赖
  3. 高度可移植的表示形式

即使这些特性中只有一个对你很重要,KSUID 也是一个很好的选择!:) 许多项目选择使用 KSUID 仅仅 是因为其文本表示形式便于复制粘贴。

关于这个主题的后续阅读:UUID 的简史

1. 自然按生成时间排序

与更常见的 UUIDv4 不同,KSUID 包含一个时间戳组件,允许它们按生成时间松散排序。这不是一个强保证(不变量),因为它依赖于挂钟时间,但在实践中仍然非常有用。二进制和文本表示形式都可以按创建时间排序,无需任何特殊的排序逻辑。

2. 无冲突、无需协调、无依赖

虽然 RFC 4122 UUIDv1 确实 包含时间组件,但没有足够的随机字节来提供强有力的防冲突(重复)保护。由于熵如此之低,恶意方可能会猜测生成的 ID,这对于那些安全性隐含或明确地对对手猜测标识符敏感的系统来说是个问题。

为了适应 64 位数字空间,Snowflake ID 及其衍生物需要协调以避免冲突,这显著增加了部署复杂性和操作负担。

KSUID 包含 128 位伪随机数据("熵")。这个数字空间比广泛接受的 RFC 4122 UUIDv4 标准使用的 122 位大 64 倍。额外的时间戳组件可以被视为"额外熵",进一步降低了冲突的概率,在任何实际实现中都达到了物理上不可能的程度。

3. 高度可移植的表示形式

文本 二进制表示形式都可以按字典顺序排序,这允许它们被放入不原生支持 KSUID 的系统中,并保留其时间排序属性。

文本表示是字母数字 base62 编码,所以它可以"适应"任何接受字母数字字符串的地方。不使用分隔符,因此当被设计用于人类可读文本的软件解释时,字符串化的 KSUID 不会被无意中截断或标记化,这是 RFC 4122 UUID 文本表示的一个常见问题。

KSUID 如何工作?

二进制 KSUID 是 20 字节:32 位无符号整数 UTC 时间戳和 128 位随机生成的有效负载。时间戳使用大端编码,以支持字典排序。时间戳纪元调整到 2014 年 5 月 13 日,提供超过 100 年的生命周期。有效负载由加密强度的伪随机数生成器生成。

文本表示始终是 27 个字符,以字母数字 base62 编码,将按时间戳进行字典排序。

高性能

这个库设计用于性能关键的代码路径。其代码已经过优化,以消除所有非必要的开销。KSUID 类型派生自固定大小的数组,这消除了涉及可变宽度类型的额外引用追踪和分配。

API 提供了一个接口,用于对分配敏感的代码路径。例如,Append 方法可用于解析文本表示并替换 KSUID 值的内容,而无需额外的堆分配。

所有公共包级别的"纯"函数都是并发安全的,由全局互斥锁保护。对于从单个 Goroutine 生成大量 KSUID 的热循环,提供了 Sequence 类型以消除潜在的争用。

默认情况下,出于谨慎考虑,使用加密安全的 PRNG 来生成 KSUID 的随机位。在极度关注性能的代码中,可以使用包含的 FastRander 类型来放宽这一要求。FastRander 使用标准 PRNG,种子由加密安全 PRNG 生成。

注意: 虽然没有证据表明 FastRander 会增加冲突的概率,但在唯一性对安全性很重要的场景中不应使用它,因为对手预测生成的 ID 的机会增加。

经过实战检验

这段代码已在 Segment 的生产环境中使用了多年,跨越了多样化的项目。在 Segment 一些最关键性能、大规模分布式系统中,已经生成了数万亿个 KSUID。

与其他库良好兼容

设计用于与其他库集成,KSUID 类型实现了许多标准库接口,包括:

  • Stringer
  • database/sql.Scannerdatabase/sql/driver.Valuer
  • encoding.BinaryMarshalencoding.BinaryUnmarshal
  • encoding.TextMarshalencoding.TextUnmarshalencoding/json 友好!)

命令行工具

此软件包附带一个命令行工具 ksuid,用于生成 KSUID 以及检查现有 KSUID 的内部组件。它提供机器友好的输出,适用于脚本编写场景。

在 Go 构建环境中,可以使用以下命令安装:

$ go install github.com/segmentio/ksuid/cmd/ksuid

CLI 使用示例

生成一个 KSUID

$ ksuid
0ujsswThIGTUYm2K8FjOOfXtY1K

生成 4 个 KSUID

$ ksuid -n 4
0ujsszwN8NRY24YaXiTIE2VWDTS
0ujsswThIGTUYm2K8FjOOfXtY1K
0ujssxh0cECutqzMgbtXSGnjorm
0ujsszgFvbiEr7CDgE3z8MAUPFt

检查 KSUID 的组件

$ ksuid -f inspect 0ujtsYcgvSTl8PAuAdqWYSMnLOv

表示形式:

  字符串: 0ujtsYcgvSTl8PAuAdqWYSMnLOv
     原始: 0669F7EFB5A1CD34B5F99D1154FB6853345C9735

组件:

       时间: 2017-10-09 21:00:47 -0700 PDT
  时间戳: 107608047
    有效载荷: B5A1CD34B5F99D1154FB6853345C9735

生成 KSUID 并检查其组件

$ ksuid -f inspect

表示形式:

  字符串: 0ujzPyRiIAffKhBux4PvQdDqMHY
     原始: 066A029C73FC1AA3B2446246D6E89FCD909E8FE8

组件:

       时间: 2017-10-09 21:46:20 -0700 PDT
  时间戳: 107610780
    有效载荷: 73FC1AA3B2446246D6E89FCD909E8FE8

使用模板格式化的检查输出来检查 KSUID

$ ksuid -f template -t '{{ .Time }}: {{ .Payload }}' 0ujtsYcgvSTl8PAuAdqWYSMnLOv
2017-10-09 21:00:47 -0700 PDT: B5A1CD34B5F99D1154FB6853345C9735

使用模板格式化输出检查多个 KSUID

$ ksuid -f template -t '{{ .Time }}: {{ .Payload }}' $(ksuid -n 4)
2017-10-09 21:05:37 -0700 PDT: 304102BC687E087CC3A811F21D113CCF
2017-10-09 21:05:37 -0700 PDT: EAF0B240A9BFA55E079D887120D962F0
2017-10-09 21:05:37 -0700 PDT: DF0761769909ABB0C7BB9D66F79FC041
2017-10-09 21:05:37 -0700 PDT: 1A8F0E3D0BDEB84A5FAD702876F46543

生成 KSUID 并使用模板格式化输出 JSON

$ ksuid -f template -t '{ "timestamp": "{{ .Timestamp }}", "payload": "{{ .Payload }}", "ksuid": "{{.String}}"}' -n 4
{ "timestamp": "107611700", "payload": "9850EEEC191BF4FF26F99315CE43B0C8", "ksuid": "0uk1Hbc9dQ9pxyTqJ93IUrfhdGq"}
{ "timestamp": "107611700", "payload": "CC55072555316F45B8CA2D2979D3ED0A", "ksuid": "0uk1HdCJ6hUZKDgcxhpJwUl5ZEI"}
{ "timestamp": "107611700", "payload": "BA1C205D6177F0992D15EE606AE32238", "ksuid": "0uk1HcdvF0p8C20KtTfdRSB9XIm"}
{ "timestamp": "107611700", "payload": "67517BA309EA62AE7991B27BB6F2FCAC", "ksuid": "0uk1Ha7hGJ1Q9Xbnkt0yZgNwg3g"}

OrNil 函数

有时你确信你的 ksuid 是正确的,但你需要从字节或字符串中获取它并将其传递给结构体。为此,有 OrNil 函数在出错时返回 ksuid.Nil,可以直接在结构体中调用。

函数:

  • ParseOrNil()
  • FromPartsOrNil()
  • FromBytesOrNil()

不使用 OrNil 函数的示例:

func getPosts(before, after []byte) {
	b, err := ksuid.FromBytes(before)
	if err != nil {
		// 处理错误
	}

	a, err := ksuid.FromBytes(after)
	if err != nil {
		// 处理错误
	}

	sortOptions := SortOptions{Before: b, After: a}
}

使用 OrNil 函数更方便:

func getPosts(before, after []byte) {
	sortOptions := SortOptions{
		Before: ksuid.FromBytesOrNil(before),
		After:  ksuid.FromBytesOrNil(after),
	}
}

OrNil 函数在许多其他库中也有使用:

其他语言的实现

许可证

ksuid源代码采用MIT许可证

项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

吐司

探索Tensor.Art平台的独特AI模型,免费访问各种图像生成与AI训练工具,从Stable Diffusion等基础模型开始,轻松实现创新图像生成。体验前沿的AI技术,推动个人和企业的创新发展。

Project Cover

SubCat字幕猫

SubCat字幕猫APP是一款创新的视频播放器,它将改变您观看视频的方式!SubCat结合了先进的人工智能技术,为您提供即时视频字幕翻译,无论是本地视频还是网络流媒体,让您轻松享受各种语言的内容。

Project Cover

美间AI

美间AI创意设计平台,利用前沿AI技术,为设计师和营销人员提供一站式设计解决方案。从智能海报到3D效果图,再到文案生成,美间让创意设计更简单、更高效。

Project Cover

AIWritePaper论文写作

AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号