也许我可以更好地为您分解它,这不仅仅是因为用户 ID 不适合。
他们正在使用 Twitter Snowflake ID。这是为了在多个服务器、多个数据中心、并行生成唯一 ID。例如,在同一时刻,两个“地方”中的两个“项目”需要一个保证的唯一 ID,以便在同一时刻相隔不到一毫秒,甚至可能在同一纳秒内……这个唯一 ID 具有以下要求需要以极快的速度生成、高效、以可以有效解析的逻辑方式构建,可以容纳在 64 位内,并且生成它的方法需要能够处理大量的 ID,如果 ID 跨越许多人的一生。这意味着他们无法进行数据库查找以获取尚未使用的唯一 ID,无法在生成 ID 后验证生成的 ID 是否唯一,并且他们不能 t 使用可能会产生重复的现有方法,即使很少像 UUID 一样。于是他们想了一个办法。。
他们设置了一个自定义的共同纪元,例如今天以一个长整数作为基点。所以有了这个,他们有一个 42 位长的整数,从那个时代开始的 0+时间开始。
然后他们还添加了一个 12 位长整数的序列,以防单台机器上的单个进程必须在同一毫秒内生成 2 个或更多 ID。现在它们有 42+12=54 位在使用中,当您考虑多台机器上的多个进程(通常每个数据中心只有一台机器提供 ID,但可能更多,并且通常每台机器只有一个工作人员/进程)时,您意识到你需要的不仅仅是 42+12..
因此他们还必须对数据中心 ID 和“工人”(进程)ID 进行编码。这将涵盖多个数据中心,每个数据中心有多个工作人员。这两个 ID 都是 5 位长的整数。所有这些整数都是无符号的,所以这 5 位整数可以达到 31,这为每个部分 ID 提供了 32 种可能性,包括 0。所以,32 个数据中心,每个数据中心最多有 32 个工作人员。所以现在我们在42+12+5+5=64 位,最多 32x32=1024 个工作人员生成这些 ID。
所以.. 42 位部分的寿命长达 139 年... 10 位用于节点 ID(或数据中心 + 工作人员 ID)... 12 位序列(每毫秒 4096 个 ID每个工人)...您提出了一个最大保证 64 个唯一 ID 系统/公式,该系统/公式在 139 年中的扩展性惊人地好,它不以任何方式依赖数据库,但可以有效地生成并存储在数据库中。
所以,这个 ID 系统的结果是 42+12+10,你可以将这 10 位分开,也可以不分开,但是你喜欢,不要在任何地方存储一个 64 位无符号长整数。非常灵活,效果很好。
同样,它被称为雪花 ID,Twitter 提出了它。这 10 位可以称为分片 ID、节点 ID 或数据中心 ID 和工作人员 ID 的组合,这取决于您的需求。但是,通过不将该分片/节点 ID 绑定到用户,而是绑定到多个进程,并且能够在多个“事物”中使用该 ID,您不必担心很多事情,并且您可以跨越多个数据库,其中包含多个事物和和和..
重要的一件事是,分片/节点 ID 只能保存 1024 个不同的值,并且没有用户 ID 或他们可以使用的任何唯一 ID 只会从 0 变为 1023,因为他们不会自己将其分配给任何东西.
所以你看,这10 位必须是静态的、可分配的并且无论如何都易于解析。
这是一个简单的 python 函数,它将生成雪花 ID:
def genSnowflakeId(worker_id, data_center_id, ids_generated):
"Returns a snowflake ID - This function will generate a unique ID that fits in a 64 bit unsigned number that scales for multiple workers running in mutiple datacenters. You must manage a timestamp and sequence sanity with ids_generated (i.e. increment if time apart < 1 millisecond or always increment and roll over to 0 if > 4095). Ultimately this will allow you to efficiently generate unique IDs across multiple locations for 139 years that fits in a bigint(20) database field and can be parsed for the created timestamp, worker ID, and datacenter ID. See https://github.com/twitter-archive/snowflake/tree/snowflake-2010"
import sys
import time
# Mon Jul 8 05:07:56 EDT 2019
twepoch = 1562576876131L
sequence = 0L
worker_id_bits = 5L
data_center_id_bits = 5L
sequence_bits = 12L
timestamp_bits = 42L
#total bits 64
max_worker_id = -1L ^ (-1L << worker_id_bits)
max_data_center_id = -1L ^ (-1L << data_center_id_bits)
max_ids_generated = -1L ^ (-1L << sequence_bits)
worker_id_shift = sequence_bits
data_center_id_shift = sequence_bits + worker_id_bits
timestamp_left_shift = sequence_bits + worker_id_bits + data_center_id_bits
sequence_mask = -1L ^ (-1L << sequence_bits)
# Sanity checks for input
if worker_id > max_worker_id or worker_id < 0:
raise ValueError("worker_id", "worker id can't be greater than %i or less than 0" % max_worker_id)
if data_center_id > max_data_center_id or data_center_id < 0:
raise ValueError("data_center_id", "data center id can't be greater than %i or less than 0" % max_data_center_id)
if ids_generated > max_ids_generated or ids_generated < 0:
raise ValueError("ids_generated", "ids generated can't be greater than %i or less than 0" % max_ids_generated)
timestamp = long(int(time.time() * 1000))
new_id = ((timestamp - twepoch) << timestamp_left_shift) | (data_center_id << data_center_id_shift) | (worker_id << worker_id_shift) | sequence
return new_id
希望这个答案能满足你:)