Loading... **百度雪花算法与UID-Generator解析** 在现代分布式系统中,生成唯一ID是非常关键的一部分,因为它能够确保在多个节点之间不会产生重复的标识符。**百度雪花算法(Snowflake)**和**UID-Generator**便是两个用于生成全局唯一ID的经典方案。在本文中,我们将对这两种生成器进行详尽的探讨和比较。 ### 雪花算法概述 百度雪花算法是一种用于生成64位唯一ID的分布式ID生成算法。它由Twitter公司首次提出,后来在国内外得到了广泛的应用和改进。 #### 🌀 **雪花算法的ID结构** 雪花算法生成的64位ID结构如下: | 位数 | 组件 | 说明 | | ---- | ------------ | ---------------------------------------- | | 1 | 符号位 | 总是0,代表正数。 | | 41 | 时间戳 | 表示从一个基准时间到现在的毫秒数。 | | 10 | 工作节点标识 | 标识生成ID的机器节点或数据中心。 | | 12 | 序列号 | 表示同一毫秒内产生的ID序列号,防止冲突。 | 其中,红色标注的**41位时间戳**非常重要,因为它确保了ID生成的顺序性,这对于分布式系统中的日志排序等场景非常有用。 ```vditor mindmap root((雪花算法ID结构)) 1. 符号位 2. 时间戳 - 基准时间 - 顺序性 3. 工作节点标识 - 数据中心 - 机器节点 4. 序列号 - 同一毫秒内的不同ID ``` ### 雪花算法的实现原理 雪花算法的关键思想是将整个ID分成不同部分,各部分共同作用来保证全局唯一性。接下来,我们将深入了解每个部分的作用: - **符号位**:固定为0,表示ID是一个正数。 - **时间戳**:时间戳的位数为41位,表示从某个基准时间(通常是自定义的纪元时间)开始到现在的毫秒数。41位的时间戳大约可以使用69年。 - **工作节点标识**:包含10位,用于区分不同的机器节点,其中5位可以用于标识数据中心,另外5位用于标识机器。这样在一个数据中心内,可以支持最多32个节点。 - **序列号**:12位序列号用于在同一毫秒内生成多个ID,防止冲突。每毫秒最多可以生成2^12 = 4096个不同的ID。 雪花算法具有**时序性、分布性和高效性**的特点,能够在分布式环境下稳定生成全局唯一ID。 #### **雪花算法工作流程** 1. **获取当前时间戳**:获取当前时间相对于基准时间的毫秒数。 2. **获取工作节点信息**:确定当前的工作节点,包括数据中心ID和机器ID。 3. **判断序列号是否溢出**:在同一毫秒内,如果序列号已达到最大值,则等待下一毫秒。 4. **生成ID**:根据符号位、时间戳、工作节点和序列号,组合成唯一ID。 ### UID-Generator解析 **UID-Generator**是由百度开源的高性能唯一ID生成器。相比于经典的雪花算法,UID-Generator具有一些增强的特点,使其更加适用于大规模分布式系统。 #### UID-Generator的ID结构 UID-Generator生成的ID同样为64位,但其结构略有不同,以确保更多的灵活性和可扩展性。 | 位数 | 组件 | 说明 | | ---- | ------------ | -------------------------------------------- | | 1 | 符号位 | 固定为0,代表正数。 | | 28 | 时间戳 | 表示自定义基准时间以来的秒数,而不是毫秒数。 | | 22 | 工作节点标识 | 包括数据中心和机器ID,共计22位。 | | 13 | 序列号 | 用于在同一秒内生成不同的ID。 | 从结构上看,UID-Generator使用**秒级时间戳**和较长的**工作节点标识**,以适应更大规模的分布式环境。这种设计提高了ID生成器的**扩展性**,同时适应更多的场景需求。 ### 🆚 **雪花算法 vs UID-Generator** | 特性 | 雪花算法 | UID-Generator | | ---------------- | -------------------------- | ---------------------- | | 时间戳精度 | 毫秒级 | 秒级 | | 时间戳位数 | 41位 | 28位 | | 工作节点标识位数 | 10位 | 22位 | | 序列号位数 | 12位 | 13位 | | 应用场景 | 通常适用于小规模分布式系统 | 适用于大规模分布式系统 | ### Python实现雪花算法 为了更好地理解雪花算法,我们通过Python来实现一个简化版本的雪花算法。 ```python import time import threading class SnowflakeIDGenerator: def __init__(self, data_center_id, machine_id): self.data_center_id = data_center_id self.machine_id = machine_id self.sequence = 0 self.last_timestamp = -1 # ID部分的位数 self.timestamp_bits = 41 self.data_center_bits = 5 self.machine_bits = 5 self.sequence_bits = 12 # 最大值设置 self.max_sequence = (1 << self.sequence_bits) - 1 self.max_data_center_id = (1 << self.data_center_bits) - 1 self.max_machine_id = (1 << self.machine_bits) - 1 # 左移位数 self.data_center_shift = self.sequence_bits self.machine_shift = self.sequence_bits + self.data_center_bits self.timestamp_shift = self.sequence_bits + self.data_center_bits + self.machine_bits def _current_timestamp(self): return int(time.time() * 1000) def generate_id(self): timestamp = self._current_timestamp() if timestamp < self.last_timestamp: raise Exception("时钟回退,无法生成ID") if timestamp == self.last_timestamp: self.sequence = (self.sequence + 1) & self.max_sequence if self.sequence == 0: while timestamp <= self.last_timestamp: timestamp = self._current_timestamp() else: self.sequence = 0 self.last_timestamp = timestamp # 生成ID unique_id = ((timestamp << self.timestamp_shift) | (self.data_center_id << self.machine_shift) | (self.machine_id << self.data_center_shift) | self.sequence) return unique_id # 实例化生成器 generator = SnowflakeIDGenerator(data_center_id=1, machine_id=1) print(f"生成的ID: {generator.generate_id()}") ``` **代码解释**: - **时间戳计算**:`_current_timestamp()`方法返回当前时间的毫秒数。 - **序列号处理**:在相同毫秒内递增序列号,直到达到最大值时,进入下一毫秒。 - **位移操作**:使用位移将各部分信息合并,形成唯一的ID。 ### 工作流程:UID生成器实现步骤 | 步骤 | 雪花算法 | UID-Generator | | ------------ | ---------------------------- | ---------------------------- | | 时间戳获取 | 获取毫秒时间戳 | 获取秒级时间戳 | | 工作节点识别 | 根据数据中心ID和机器ID分配 | 扩展到更大规模的节点标识 | | 生成唯一ID | 时间戳、节点和序列号合并 | 时间戳、节点、序列号合并 | | 序列号处理 | 毫秒内生成4096个ID,避免冲突 | 秒内生成8192个ID,确保唯一性 | ### 结论 雪花算法和UID-Generator都是分布式系统中高效的唯一ID生成工具。**雪花算法**更适合于中小规模的分布式场景,因其设计较为简单且生成速度快。而**UID-Generator**则为了适应大规模、高并发环境,进行了优化和扩展,通过较长的节点标识和秒级时间戳,实现了更强的扩展能力。 🚀 **下一步建议**: - 探索其他的ID生成工具,如Leaf(美团开源)等,进一步了解分布式ID生成的多样性。 - 尝试在实际项目中整合这些ID生成算法,测试其性能和可扩展性。 - 探索如何通过数据库等方式来管理和持久化这些生成的唯一ID。 最后修改:2024 年 10 月 20 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏