全局唯一性

全局唯一性是分布式 ID 生成器的最核心要求。让我们深入理解为什么必须唯一,以及如何保证唯一性。

为什么必须唯一

1. 数据一致性保证

问题场景

用户A下单:订单号 20240410001
用户B下单:订单号 20240410001 (重复!)

结果:
- 两个订单关联到同一记录
- 支付混乱
- 发货错误
- 用户投诉

数据影响

  • 主键冲突 → 数据库写入失败
  • 外键关联错误 → 数据不一致
  • 业务逻辑错误 → 用户体验差

2. 业务逻辑正确性

真实案例

某电商系统订单号冲突导致:
1. 用户A支付成功,订单状态未更新
2. 用户B支付同一订单,金额错误
3. 客服处理困难,用户流失
4. 赔偿成本:500万元

业务影响

  • 支付失败 → 资金损失
  • 库存混乱 → 超卖或少卖
  • 用户信息冲突 → 隐私泄露
  • 消息追踪失败 → 问题无法排查

3. 法律和合规风险

合规要求

支付行业:订单号必须唯一(央行要求)
金融行业:交易流水号必须唯一(银监会要求)
医疗行业:患者ID必须唯一(卫健委要求)

违规后果

  • 监管处罚
  • 业务整改
  • 声誉损失
  • 法律诉讼

唯一性的定义

数学定义

对于任意两个不同的实体 E1 和 E2:
ID(E1) ≠ ID(E2)

其中 ID 是一个从实体到标识符的映射函数

分布式环境下的唯一性

在分布式系统中,唯一性意味着:

对于任意两个节点 N1 和 N2 在任意时间生成的 ID:
ID(N1, t1) ≠ ID(N2, t2)

其中 t1 和 t2 可能相同也可能不同

保证唯一性的方法

1. 中央协调器

原理:使用一个中心化的服务统一分配 ID。

实现方式

单机计数器:单机递增
分布式锁:Redis SETNX
数据库主键:AUTO_INCREMENT

优点

  • ✅ 绝对保证唯一
  • ✅ 实现简单

缺点

  • ❌ 性能瓶颈
  • ❌ 单点故障
  • ❌ 网络开销

2. 分区策略

原理:将 ID 空间划分为多个独立区域,每个区域独立生成。

实现方式

节点ID + 序列号
数据中心ID + 节点ID + 序列号
业务类型 + 时间戳 + 序列号

示例

节点A:1001, 1002, 1003, ...
节点B:2001, 2002, 2003, ...
节点C:3001, 3002, 3003, ...

优点

  • ✅ 无需协调
  • ✅ 高性能
  • ✅ 分布式友好

缺点

  • ❌ 需要预先分配
  • ❌ 扩展需要规划

3. 随机生成

原理:使用足够大的随机空间,使碰撞概率趋近于零。

实现方式

UUID:128位随机空间
GUID:128位全局唯一标识符
ULID:基于时间的唯一ID

碰撞概率

UUID v4:128位随机
生成 10^18 个 UUID,碰撞概率 < 0.0000000001%

优点

  • ✅ 无需协调
  • ✅ 无限扩展
  • ✅ 实现简单

缺点

  • ❌ 理论上有碰撞可能
  • ❌ 无序
  • ❌ 较长

唯一性的验证

1. 数学验证

验证方法

ID空间大小 > 需要生成的ID数量

碰撞概率 = 1 - (1 - 1/S)^N

其中:
S = ID空间大小
N = 需要生成的ID数量

示例计算

UUID:S = 2^128 ≈ 3.4 × 10^38
每天生成:N = 10^9
运行时间:T = 100年

碰撞概率 ≈ 0

2. 实践验证

验证方法

1. 收集所有生成的 ID
2. 使用 Set 或 Bloom Filter 检测重复
3. 定期审计 ID 唯一性
4. 设置重复告警机制

验证工具

Redis Set:内存去重
数据库唯一索引:强制唯一性
Bloom Filter:高效检测
日志分析:事后审计

3. 运行时保护

保护机制

1. 数据库唯一索引:最后防线
2. 重复检测前置:生成时检测
3. 冲突重试机制:遇到冲突重试
4. 熔断降级:异常时降级

示例流程

生成 ID

检测是否已存在?
  ├─ 是 → 重新生成 / 报错
  └─ 否 → 使用 ID

常见错误

错误1:假设碰撞不会发生

❌ 错误做法:
概率太小,忽略不计

✅ 正确做法:
理论上证明不碰撞,实践上验证不碰撞

错误2:依赖单一机制

❌ 错误做法:
只用数据库唯一索引

✅ 正确做法:
生成器保证唯一 + 索引作为最后防线

错误3:忽略时钟回拨

❌ 错误做法:
直接使用时间戳,不考虑回拨

✅ 正确做法:
检测时钟回拨并处理

错误4:忽视分布式环境

❌ 错误做法:
各节点独立计数,不区分节点

✅ 正确做法:
每个节点有独立的 ID 空间

唯一性检查清单

在实现分布式 ID 生成器时,确保:

  • 理论上证明唯一性
  • ID 空间足够大
  • 考虑分布式环境下的冲突
  • 处理时钟回拨问题
  • 设置重复检测机制
  • 数据库唯一索引作为最后防线
  • 有冲突重试机制
  • 有监控和告警
  • 定期审计 ID 唯一性
  • 故障场景下仍然保证唯一

下一步

了解了全局唯一性后,我们继续学习 ID 的有序性特性。

👉 下一节:有序性