要聊分布式id,首先要说一下分布式id产生的背景。
当业务系统进行分库分表的时候,传统的单表自增的主键就会产生id冲突的情况。分布式id 就是为了解决这个问题而出现的。
说白了其实就是一个协调问题,任何分布式多节点的协调问题基本上都可以通过引入中间件来解决。分布式id就可以使用一些常见中间件的特性来解决,比如redis 的自增、zookeeper的顺序id。
但是引入中间件也是给系统引入了额外的复杂度。分布式id 的问题本质上还是id冲突的问题,那么也可以通过某种算法,保证每个节点之间产生的id不会重复,比如uuid,但是uuid占用16个字符,而且非有序id在数据库中索引效率下降。
为此有人研究了雪花算法,雪花算法的目的是在多节点情况下,生成不会冲突的long类型的id。long类型有64位,首位作为符号位,接着41位为时间戳,随后10位用来区分不同节点,最后12位作为递增序列号。即在同一时间戳,最多有2的12次方个id。一毫秒4096个id已经足够用了。
子问题
1、雪花算法如何处理不同机器的workid
不同机器的workid本质上还是要求不能产生冲突,通用解决办法还是引入中间件,通过redis,zookeeper甚至mysql都可以去解决这个问题,因为这个需求没有并发和性能的要求,所以可以使用mysql去解决,建一张自增表,存储机器的ip,端口,则其自增id就可以作为workid。
2、雪花算法的实现 ,41位用于存放时间戳,但是时间戳是64位的,怎么处理的
取一个初始时间,取和当前时间的差值
引申问题
数据库的索引效率和什么有关?
uuid 的生成逻辑?
如何保证redis的高可用?
如何保证zookeeper 的高可用?
常见的分库分表策略?