背景
在互联网业务中,很多场景需要全局唯一的ID,比如消息系统用一个ID标记唯一的消息,用一个唯一的ID标记一个系统对象等。这些业务场景需要有一个分布式ID生成器。
分布式ID的特性
- 全局唯一
- 递增
- 高可用: ID生成器服务往往服务于多个业务系统模块,访问压力大,所以需要保证高可用。
- 信息安全: 为了避免恶意推测出批量的ID,有一些场景下ID需要无规则的。
分布式ID的生成方案
方案一: UUID
UUID核心思想是结合机器的网卡、当地时间、一个随机数来生成。
- 优点
性能高 - 本地生成,无需网络请求
生成简单- 没有高可用风险
较为安全 - 没有规律
- 缺点
太长 - 不利于存储
不利于安全性 - 基于MAC地址生成的算法可能会泄露MAC地址
无序-在InnoDB存储引擎中,无序性会导致数据位置频繁变动,性能低下
方案二: 数据库自增主键
利用数据库自增ID的特性来生成,如 MySQL 的auto_increment
。
- 优点
利用数据库自有功能实现,有序
- 缺点
如果数据库发生主从切换,有重复发号的风险。
受限于数据库性能瓶颈,扩容成本大
方案三: 使用Redis自增的原子命令
Redis 提供了自增的原子命令,可以保证唯一、有序。
- 优点
简单,高并发
维护成本低
- 缺点
发生主从切换时,有重复发号的风险。
需要特别保障其高可用。
方案三: snow flak算法
生成规则如下:
代码语言:javascript复制时间戳 机器标识 自增序列号
高位是用时间戳(ms),保证了有序性(趋势递增),再加上机器标识和自增序列号,保证了唯一性。
- 优点
生成性能高。灵活,可以根据自身业务特点分配bit位。
- 缺点
强依赖机器时钟,如果时钟回拨,就会导致服务异常。