关于分布式唯一ID生成的几点思考
目录
- 什么是分布式唯一ID?
- 唯一ID需要满足什么特性?
- 市面上通用的解决方案
- 几点自己的疑问和思考
什么是分布式唯一ID?为什么要用全局唯一ID?
先说一个具体例子:
某商城订单数据表,如果订单数据放到一张表内,那订单ID可以简单使用数据库表的自增id,可以保证订单id递增不会重复。但是,随着业务越来越庞大,单表数据量太大,会出现数据库瓶颈问题,这时往往要对订单表进行分库分表,多机房部署,可以按日期或取模的方式分表,这时就带来一个问题,分表后每张表自增id是独立的,肯定会生成重复的ID,因此,就不能使用数据库自增id来作为订单ID,必须使用全局唯一ID,每个订单id在全局是唯一的。
唯一ID需要满足什么特性?
全局唯一ID需要满足3个特性:
- 全局唯一性:不能出现重复的ID号,
- 趋势递增,保证数据库索引插入是有序写入,且方便例如消息、订单等数据的排序
- 占用空间尽可能小,一般使用64bit
市面上通用的解决方案
美团的这篇文章介绍得很详细:[https://tech.meituan.com/MT_Leaf.html]
主要分为两大类:
1.借助第三方组件(数据库/redis/zookeper)保证唯一
利用数据库自增id来保证,使用一张独立共同使用的表来生成自增ID,生成后再insert到其他业务表id中。
优点:
- 简单,利用现有数据库系统的功能实现,成本小。
缺点:
- 强依赖DB,当DB异常时整个系统不可用,属于致命问题。
- ID发号性能瓶颈限制在单台MySQL的读写性能。
第二种:类snowflake方案
把64bit进行划分:时间戳+工作机器id+自增id
几点自己的思考
- 为什么snowflake方案要单独部署服务?
问题:在分布式系统中,多一个服务,就多一层维护,需要做好容灾等各种异常,维护成本相当大。
我的想法:也不是必须要单独部署,不管是不同业务、不同机器、不同运行进程,都是通过workID来区分,划分不同的段来区分,如果使用进程内生成,那需要根据进程id来不同区分。 - 进程内自增,怎么解决多机部署问题?
snowflake方案最低12位是进程内自增的id,如果部署多台同一业务同一毫秒会出现id重复,怎么解决?
我的想法:这种情况只能使用不同的workID。启动进程使用不同的workID。
相关资料
- Leaf——美团点评分布式ID生成系统:[https://tech.meituan.com/MT_Leaf.html]
- 分布式唯一id:snowflake算法思考:[https://juejin.im/post/5a7f9176f265da4e721c73a8]
- 百度开源UID:[https://github.com/baidu/uid-generator/blob/master/README.zh_cn.md]
- 高并发分布式系统中生成全局唯一Id汇总:[https://www.jianshu.com/p/1be3f15cbc57]