这是 Beta 探索课程,内容结构、实验步骤和示例可能会继续调整。
全局唯一性
全局唯一性是分布式 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年
碰撞概率 ≈ 02. 实践验证
验证方法:
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 的有序性特性。
👉 下一节:有序性