SnowFlake
雪花算法概述
雪花算法是由 Twitter 开发的一种分布式唯一 ID 生成算法,主要用于分布式系统中需要生成唯一 ID 的场景。它生成的 ID 既有全局唯一性,又有时间有序性。
雪花算法 ID 结构
一个典型的雪花算法生成的 ID 一共有 64 位,通常由以下几个部分组成:
- 1 位符号位:永远是 0,表示正数。
- 41 位时间戳:表示从一个固定时间点(通常是某个纪元时间,比如 2020-01-01 00:00:00)开始经过的毫秒数。这部分可以使用大约 69 年的时间。
- 10 位机器 ID:用来表示不同的机器或节点,可以支持最多 1024 个节点。
- 12 位序列号:用来表示同一毫秒内产生的不同 ID,每毫秒内可以生成 4096 个不同的 ID。
雪花算法详细实现
以下是使用 Python 实现雪花算法的详细步骤:
1. 导入必要模块
2. 定义 Snowflake
类
| class Snowflake: |
| def __init__(self, datacenter_id, worker_id, sequence=0): |
| self.datacenter_id = datacenter_id |
| self.worker_id = worker_id |
| self.sequence = sequence |
datacenter_id
:数据中心 ID,表示不同的数据中心。
worker_id
:机器 ID,表示不同的机器或节点。
sequence
:序列号,初始化为 0。
3. 定义常量
| self.epoch = 1577836800000 |
| self.datacenter_id_bits = 5 |
| self.worker_id_bits = 5 |
| self.sequence_bits = 12 |
epoch
:纪元时间,即一个固定的时间点,从这个时间点开始计算经过的毫秒数。
datacenter_id_bits
:数据中心 ID 的位数,设为 5 位。
worker_id_bits
:机器 ID 的位数,设为 5 位。
sequence_bits
:序列号的位数,设为 12 位。
4. 计算最大值
| self.max_datacenter_id = -1 ^ (-1 << self.datacenter_id_bits) |
| self.max_worker_id = -1 ^ (-1 << self.worker_id_bits) |
| self.max_sequence = -1 ^ (-1 << self.sequence_bits) |
max_datacenter_id
:数据中心 ID 的最大值。
max_worker_id
:机器 ID 的最大值。
max_sequence
:序列号的最大值。
5. 定义移位数
| self.worker_id_shift = self.sequence_bits |
| self.datacenter_id_shift = self.sequence_bits + self.worker_id_bits |
| self.timestamp_left_shift = self.sequence_bits + self.worker_id_bits + self.datacenter_id_bits |
worker_id_shift
:机器 ID 的移位数。
datacenter_id_shift
:数据中心 ID 的移位数。
timestamp_left_shift
:时间戳的移位数。
6. 定义时间戳获取方法
| def _gen_timestamp(self): |
| return int(time.time() * 1000) |
_gen_timestamp
:获取当前时间戳,单位为毫秒。
7. 定义等待方法
| def _wait_for_next_millis(self, last_timestamp): |
| timestamp = self._gen_timestamp() |
| while timestamp <= last_timestamp: |
| timestamp = self._gen_timestamp() |
| return timestamp |
_wait_for_next_millis
:等待到下一毫秒,确保时间戳唯一性。
8. 生成唯一 ID
| def next_id(self): |
| timestamp = self._gen_timestamp() |
| |
| if timestamp < self.last_timestamp: |
| raise Exception("Clock is moving backwards. Rejecting requests until %d." % self.last_timestamp) |
| |
| if self.last_timestamp == timestamp: |
| self.sequence = (self.sequence + 1) & self.max_sequence |
| if self.sequence == 0: |
| timestamp = self._wait_for_next_millis(self.last_timestamp) |
| else: |
| self.sequence = 0 |
| |
| self.last_timestamp = timestamp |
| |
| return ((timestamp - self.epoch) << self.timestamp_left_shift) | \ |
| (self.datacenter_id << self.datacenter_id_shift) | \ |
| (self.worker_id << self.worker_id_shift) | \ |
| self.sequence |
next_id
:生成唯一 ID 的方法。
- 获取当前时间戳。
- 如果当前时间戳小于上一个时间戳,抛出异常。
- 如果当前时间戳等于上一个时间戳,增加序列号,并检查是否溢出。如果溢出,等待到下一毫秒。
- 否则,重置序列号为 0。
- 更新上一个时间戳。
- 通过位移操作生成唯一 ID。
使用示例
| |
| datacenter_id = 1 |
| worker_id = 1 |
| snowflake = Snowflake(datacenter_id, worker_id) |
| |
| for _ in range(10): |
| print(snowflake.next_id()) |
- 初始化
Snowflake
类实例,传入数据中心 ID 和机器 ID。
- 调用
next_id
方法生成唯一 ID。
要点
- 雪花算法的用途:生成分布式唯一 ID。
- ID 结构:
- 1 位符号位:永远为 0。
- 41 位时间戳:从固定时间点开始的毫秒数。
- 10 位机器 ID:表示不同机器或节点。
- 12 位序列号:同一毫秒内产生的不同 ID。
- 实现步骤:
- 导入
time
模块。
- 定义
Snowflake
类,初始化参数。
- 定义常量:纪元时间、各部分的位数。
- 计算最大值:数据中心 ID、机器 ID、序列号。
- 定义移位数:机器 ID 移位数、数据中心 ID 移位数、时间戳移位数。
- 获取当前时间戳的方法
_gen_timestamp
。
- 等待到下一毫秒的方法
_wait_for_next_millis
。
- 生成唯一 ID 的方法
next_id
。
- 使用示例:初始化
Snowflake
实例,生成唯一 ID。
第三方包
https://blog.csdn.net/m0_61970162/article/details/126474140
安装
启动服务
| snowflake_start_server --worker=1 |
编写程序,获取id
| from snowflake import client |
| |
| print(client.get_guid()) |
本文作者:ssrheart
本文链接:https://www.cnblogs.com/ssrheart/p/18237841
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步