MySQL 自增 ID
优点:
- 自增数字
- 无需额外操作
缺点:
- 单点问题
- 可以设置 step 解决,例如一个表是
0, 2, 4
另个表是1, 3, 5
。但是这个方法后期扩展性差
- 可以设置 step 解决,例如一个表是
UUID
v1()
真随机
v4()
伪随机效率
v4()
远超v1()
优点:
- 全世界唯一
缺点:
- 太长,做主键会降低性能,并且更多的容量
- 不能生成递增有序的数字
- 可以通过时间算法计算出时间戳
- mac 地址泄漏(?,没有查到这个事情)
Sequenece 表
根据一个唯一 table 值,插入 Sequence 表来获取 nextId()
优点:
支持多表
缺点:
- 所有表写入性能瓶颈取决于 Seqeuence 表的写入速度
- 单点问题(可以通过 主从同步 解决)
- 写入失败会造成 id 断层
- 如果遇到网络延迟可能会造成顺序不一致
- 请求两次 MySQL
Redis
redis.incr()
缺点:
多一个 redis 库。
snowflake
https://github.com/twitter/snowflake
1. 第一位
占用1bit,其值始终是0,没有实际作用。
2. 时间戳
占用41bit,精确到毫秒,总共可以容纳约69 年的时间。
3. 工作机器id
占用10bit,其中高位5bit是数据中心ID(datacenterId),低位5bit是工作节点ID(workerId),做多可以容纳1024个节点。
4. 序列号
占用12bit,这个值在同一毫秒同一节点上从0开始不断累加,最多可以累加到4095。
SnowFlake算法在同一毫秒内最多可以生成多少个全局唯一ID呢?只需要做一个简单的乘法:
同一毫秒的ID数量 = 1024 X 4096 = 4194304
这个数字在绝大多数并发场景下都是够用的。
参考: <http://www.sohu.com/a/232008315_453160>
优点:
- 本地生成,不依赖数据库
- ID 递增趋势
缺点:
- 顺序依赖时钟
- 如果机器的系统时间在服务启动之后回拨,可能造成重复 ID
这边要注意一点是,workId 虽然字面上是工作机器 id。其实是相当于单个服务来说的。如果一个工作机器上同时部署多个服务,或者类似 node cluster 。则还需要分配 workId ,保证每个生产 id 的函数所持有的 workId 唯一。
Leaf 美团分布式 ID 生成服务
https://tech.meituan.com/2019/03/07/open-source-project-leaf.html
基于 ID 服务 (Leaf) 的 ID 生成。
在逻辑上将 id 段分成若干部分,多个 Leaf 服务通过读取 DB 获取长度相同的 id 段。在 id 用完时,主动再次获取,并将之前已经分配完的 id 段的最高的一个 id 持久化。
分发在内存中完成。
优点:
- 全局唯一
- client 不用生成 id
- 性能相对数据库较高
缺点:
- 要重新部署一套服务
- 相对本地生成 id 速度较慢
- client 获取 id 顺序无序【不能保证递增趋势】