确定系统需求,比如:
这里以下列需求作为本系统的设计需求:
有几种常见的方式用于在分布式环境下生成唯一ID:
通过多个数据库的自增主键来生成唯一ID,不同的服务器从不同的基数开始,每次按k进行自增,这里k是服务器的数量,比如上面的示例,服务器1按1,3,5...的顺序生成ID,服务器按2,4,6...的顺序生成ID。
多主机复制模式在某种程度上解决了扩展问题,但也有几个重大缺陷:
128位的唯一ID,由算法保证唯一性,各个服务器之间无须进行同步即可独立生成UUID。UUID的冲突概率极低,按维基百科的描述,每秒生成10亿个ID,连续生成100年,才有可能达到生成一个UUID时有50%的概率重复,以下是一个UUID的示例:
09c93e62-50b4-468d-bf8a-c07e1040bfb2
优点:
缺点:
使用中心化的发号服务器来生成ID,内部的实现仍然是数据库的自增主键。
优点:
缺点:
采用分治的思想,将ID分成几部分,每部分独立生成,从面保证ID的唯一性,以下是一个64位的ID分布:
每部分描述如下:
使用雪花算法作为分布式ID生成算法,数据中心编号和机器编号在一开始时就应该确定下来,因为后续调整这两个编号将极为麻烦,容易导致ID冲突。
雪花算法的时间戳为41bit,单位为毫秒,一共可表示的时间长度是 2^41 -1 = 2199023255551 milliseconds (ms) ~= 69年,调整起始时间点,将时间设置得更靠近当前时间可延时算法溢出的时间点。另外,在拿到一个ID后,也很容易推算出这个ID的生成时间,只需要加上既定时间点1288834974657,再转化成UTC秒数即可。
雪花算法的另一个问题是时间回拔问题,当服务器时间发生回拔时,会导致ID冲突,这在网上有很多介绍,以下是一些解决方案的描述:
使用雪花算法为分布式下全局ID、订单号等简单解决方案考虑到时钟回拨 - 星朝 - 博客园
时钟回拨问题咋解决?百度开源的唯一ID生成器UidGenerator - 知乎