集群环境ID生成要求

全局唯一
趋势递增
高并发
高可用
可读性

生成策略

  1. UUID 实现简单,不占用宽带 无需、查询慢、不可读 32字节
    1. 组成-当前时间+时钟时序+机器识别码
    2. 分布式系统中,可以直接保证唯一
  2. 数据库自增 代码简单,递增 DB单点故障,扩展性瓶颈 自增
    1. 使用mysql自增-通过控制步长来控制集群生成的值不会冲突
    2. 比如有三台服务器,就把步长设置为3,但是如果新增机器会比较麻烦,只能停机-然后修改每台机器的起步值和步长
  3. snowflake 不占用宽带,低位趋势递增 依赖服务器时间 18字节
    1. 雪花算法,Twitter推出的算法,ID趋势递增,方便客户端排序
    2. 可以在github上查看snowflake信息,
  4. redis 无单点故障,性能优于DB,递增 占用宽带,需要redis集群 自定义
    1. redis性能好,推荐使用
    2. incr 命令 自增生成

雪花算法

分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。
有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。
而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移到Cassandra,因为Cassandra没有顺序ID生成机制,所以开发了这样一套全局唯一ID生成服务。

结构

snowflake的结构如下(每部分用-分开):
0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000
第一位为未使用,接下来的41位为毫秒级时间(41位的长度可以使用69年),然后是5位datacenterId和5位workerId(10位的长度最多支持部署1024个节点) ,最后12位是毫秒内的计数(12位的计数顺序号支持每个节点每毫秒产生4096个ID序号)
一共加起来刚好64位,为一个Long型。(转换成字符串长度为18)
snowflake生成的ID整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由datacenter和workerId作区分),并且效率较高。据说:snowflake每秒能够产生26万个ID。