# 雪花算法在分布式场景下生成重复的Id

<LinkCard
  title="雪花算法"
  description="了解一下雪花算法"
  href="/software-engineer/algorithm/snow-flake-id"
/>

### 背景
{/* 2024年第一个工作日,我入职新公司的第一天还是第二天,就听说团队所负责的一个分布式ID生成器项目生成了重复的ID问题。已经查明是workId重复导致的。具体原因就是同一个服务部署了多个节点,每个节点的workId都是一致导致的。 */}
workId重复导致生成重复的ID

### 如何解决
给每个节点分配不同的workId即可。

### 实现途径
1. 每个节点所在服务器预置不同的workId,然后由程序来读取。
2. 搞一个协调者,来统一记录已使用的workId,其他节点获取记录的最大值,自增后使用。另外需要将自增后的值回写到配置。全程需要使用分布式锁,防止并发问题

### 方案分析
1. 第一种方案需要在服务器上维护,不灵活,如果有什么变动(例如临时扩容)就需要修改服务器上的配置
2. 第二种方案不需要再服务器上维护任何数据,但是需要引入一个协调者和一个分布式锁来解决。

最终我们选择了第二种方案。原因如下:
- 只在初始化时执行一次分配workId,后续都不需要执行
- 分布式配置中心和基于Redis的分布式锁在项目中是成熟的,可以直接使用

#### 流程图
一图胜千言,直接上图

> 这里核心采用的是分布式配置中心做workId的注册抢占方案,而Redis只是做了一个分布式锁。当然这里完全也可以使用Redis做抢占注册。原理都是一样的,只是实现不同而已

![](/software-engineer/drawio/Moatkon-SnowFlakeWorkId.drawio.svg)