1、分布式、高并发下的ID生成要求
- 全局唯一
- 趋势递增
- 效率高(生成、使用、索引)
- 控制并发
策略一:UUID/GUID(通用唯一识别码)
UUID按照开放软件基金会(OSF)指定的标准计算。
用到了以太网递增(MAC)、纳秒级时间、芯片ID码和许多可能的数组。
由一下几部分的组合:
- 当前日期和时间
- 时钟序列
- 全局唯一的IEEE机器识别号
示例UUID,长度为36的字符串:3skci324-sdf4-842k-4k23d3ea32ff
优点:
- 使用简单
- 不依赖其他组件
- 不影响数据库扩展
缺点
- 数据库索引效率低
- 太过于无意义,用户不友好
- 长度36的字符串,空间占用大
- 应用集群环境,机器多的时候,重复几率大
策略二:数据库自增长
优点
- 无需编码
- 性能不错
- 索引友好
缺点
- 大表不能做水平分表,否则插入删除易出现问题
- 依赖前期规划,拓展性不好
- 依赖mysql内部维护“自增锁”,高并发下插入数据影响性能
- 在业务进行表关联插入时,要"先父后子"
策略三:推特的雪花算法
snowflak算法是Twitter开源的分布式ID生成算法,结果是一个long长整型的ID。
由1bit -未使用的0+41bit-时间戳+10bit-工作机器ID+12bit-序列号四部分组成, 64bit=8字节=long的占用字节(转化为字符串后长度最多19)。
优点
- 性能较优,速度快
- 无需第三方依赖,实现简单
- 可以根据实际情况调整和拓展算法,方便灵活
缺点
- 依赖机器时间,如果发生回拨会可能导致生成重复ID,业界的使用根据snowflak拓展
策略四:基于Redis自增
利用增长技术API,业务系统在自增长的基础上,配合其他信息组装成为一个唯一ID。
Redis的incr(key) API用于将key的值进行递增,并返回增长数组。如果key不存在,则创建并赋值为0。
利用到Redis的特性:单线程原子操作、自增计数API、数据有效期EX。
示例:业务编码+地区+自增数值。(9 020 0000000001)
优点
- 拓展性强,可以方便的结合业务进行处理
- 利用Redis操作原子性的特性,保证在并发的时候不会重复
缺点
- 引入Redis就意味着引入其他第三方的依赖
- 增加一次网络开销
- 需要对Redis服务实现高可用
策略对比