Skip to content

A distributed unique ID generator inspired by Twitter's Snowflake

License

Notifications You must be signed in to change notification settings

palaworks/palaflake

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 

Repository files navigation

palaflake V2

snowflake 改进型分布式ID生成方案

概述

palaflake 为低分布式场景提供全局唯一的ID生成方案,并通过时间回拨位为更多场景提供冗余可能。

ID结构

palaflake 同 snowflake 一样,采用64个二进制位来生成 ID,palaflake 也是一个i64值。

下面是一个标准的 palaflake 二进制表示(间隔和换行是出于排版考虑):

01112222 22222222 22222222 22222222
22222222 22223333 33334444 44444444
  • 首位(被标识为0):弃用,置0,因为有符号64位整数在大多数应用场景中更为通用。

  • 第2~4位(共3位,被标识为1):时间回拨位,允许至多承受7次时间回拨。

  • 第5~44位(共40位,被标识为1):精确到毫秒的时间戳,其最大使用年限为34年。

  • 第45~52位(共8位,被标识为3):实例标识,最大可供256个实例同时生成 ID。

  • 第53~64位(共12位,被标识为4):序列号,支持每毫秒生成4096个 ID。

最佳实践

为充分利用 ID 空间,请使用从项目启动时间开始的毫秒级时间戳。

palaflake 默认支持高达每秒400万(4096000)的并发量,可通过降低第5~44位的时间戳的精确程度来降低 palaflake 的并发程度以更加充分地利用ID空间(例如每10毫秒增加一次时间戳)。

注意事项

  • 对于单一实例,palaflake 能够保证系统在线期间每次都产生递增的 ID,但不能保证系统重启后产生的 ID 相较于重启前是递增的(这是因为存在时间回拨位,如果不触发时间回拨,那么仍能保证重启后ID的递增性)。

  • 对于多实例,palaflake 仅能保证 ID 的全局唯一性,不能保证多实例间 ID 的递增性。

  • palaflake 的时间回拨位允许系统至多发生7次时间回拨,在这期间依然能够产生唯一且递增的 ID,应该在触发时间回拨后将后续 ID 映射到安全的ID空间,并置0回拨位。

实现

C#
F#
Kotlin
Rust

均包含一份示例代码和一个可直接编译使用的 library。

使用方法:

//以Kotlin为例,其他语言大同小异。
import Palaflake.Generator

fun main() {
    val g = Generator(1, 2022u)//实例标识和计时起始年
    println(g.next())
}

已知问题

  • 仅对于 Windows 10 测试环境下的 Kotlin 实现,在以极高速度生成ID时有概率发生时间回拨位的过多递增(在单线程下也是如此),此问题并不影响生成 ID 的唯一性与递增性,但会使得容许的时间回拨次数减少。目前在实现中通过引入额外阻塞来限制 ID 生成速度以屏蔽此问题,但仍不能确定该问题是否会在其他情况下复现,详见 Kotlin 实现中的//TODO标记。其他语言的实现版本并无此问题。另对于 macOS 12 测试环境下,此问题未复现。

About V2

去除了保留位,因其意义不明且浪费ID空间。
弃用了首位,以适应更多应用场景。
拓宽了时间回拨位,以容许更多回拨的发生。
提前了时间回拨位和时间戳位,以提高某些场景中对ID的索引性能。

About

A distributed unique ID generator inspired by Twitter's Snowflake

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published