为什么使用雪花算法,有什么优缺点,如何解决?为什么不使用UUID的方法,如何解决系统回拨的问题?
生成的id应该满足下面的条件:
- 首先是全局唯一,不能出现重复的ID
- 之后是总体应该是递增的,
- 整体上是信息安全,应该是无规则的,不能从Id上获得信息
市面上对于分布式ID生成大致有几种算法:
- 首先是UUID,这种算法是本地生成的,性能很高,但是生成的字符串是128位,通常需要使用字符串类型进行存储,并且是无序的,所以在很多场景下是不适用的。并且也不适用于作为Mysql数据库的逐渐和索引(Mysql官方建议,逐渐越短越好,对于Innodb引擎,索引的无序性可能会引起数据位置的频繁便当,严重影响性能)。
- 第二种是数据库自增ID,这种算法每次获取一个Id都是通过DB的操作,对于DB的压力比较大,性能低,数据库宕机对于服务是毁灭性打击,不过可以依赖数据库激情实现高可用。
- 第三种是数据库号段的算法,一次生成一个号段,这个号段中包含多个ID,号段越长性能越好。如果在一段时间内数据库发生了宕机,可以短时间内还可以对外提供服务。
- 雪花算法,以 时间戳+机器+递增队列组成,基本趋势递增,性能很高,因为强依赖机器时钟,所以需要考虑时钟回拨的问题。
雪花算法的组成:
如何解决时钟回拨的问题?
- 使用等待机制:如果发生系统回拨,就是检测到当前时间戳小于上一次生成ID的时间戳的时候,就停止生成ID,等待系统时钟校准正确之后再继续生成。
- 多时钟算法,当一个时钟发生时钟回拨之后,使用其他的时钟进行生成。