MySQL自增主键与雪花算法分布式ID对比
MySQL自增主键(AUTO_INCREMENT)在分布式环境中有什么问题?雪花算法相比MySQL自增主键有什么优势和劣势?在分库分表场景下,如何选择主键生成策略?
回答
我是大山
MySQL自增主键问题:
- 单点瓶颈:所有插入依赖同一数据库的AUTO_INCREMENT锁
- 不适合分库分表:各分库的自增ID会重复
- 解决方案:设置不同的初始值和步长(
AUTO_INCREMENT=1 INCREMENT=4、AUTO_INCREMENT=2 INCREMENT=4等) - 缺陷:扩容时步长调整复杂
- 解决方案:设置不同的初始值和步长(
- ID暴露业务量:通过ID可推断订单量/用户量
- 机房隔离难:跨数据中心ID冲突
雪花算法特点:
| 对比 | MySQL自增主键 | 雪花算法(Snowflake) |
|---|---|---|
| 全局唯一 | ❌(需改造) | ✅ |
| 有序性 | ✅(严格递增) | ✅(趋势递增) |
| 性能 | 低(DB瓶颈) | 高(本地生成) |
| 无中心化 | ❌ | ✅ |
| 趋势递增 | ✅(利于B+Tree写入) | ✅(时间戳高位) |
| 可读性 | 无业务含义 | 可解析时间戳+机器ID |
| 长度 | 4/8字节(INT/BIGINT) | 8字节(BIGINT) |
分库分表主键选型建议:
-
单库单表:MySQL自增主键(简单高效)
-
分库分表(需全局唯一):
- 推荐:雪花算法 或 号段模式(Leaf)
- 雪花算法变种:百度UidGenerator、美团Leaf-snowflake
- 号段模式:美团Leaf-segment(批量获取ID段,性能高)
-
要求严格递增(如金融交易流水号):
- 美团Leaf号段模式(数据库+缓存,保证递增)
- 或Redis INCR(需考虑持久化问题)
-
要求业务含义:
- 雪花算法变种:可编码时间、机房、机器、序列
- 或自定义组合:时间戳+业务编码+随机数
注意:雪花算法需要解决时钟回拨问题(详见分布式ID专题)。