分布式系统生成全剧唯一ID

公司业务需要,将mpp数据库迁移到kudu中去,而kudu不支持自增序列,所以准备自己实现一下。
一般情况,实现全局唯一ID,有三种方案,分别是通过中间件方式、UUID、雪花算法。

方案一,通过中间件方式,可以是把数据库或者redis缓存作为媒介,从中间件获取ID。这种呢,优点是可以体现全局的递增趋势(优点只能想到这个),缺点呢,倒是一大堆,比如,依赖中间件,假如中间件挂了,就不能提供服务了;依赖中间件的写入和事务,会影响效率;数据量大了的话,你还得考虑部署集群,考虑走代理。这样的话,感觉问题复杂化了。

方案二,通过UUID的方式,java.util.UUID就提供了获取UUID的方法,使用UUID来实现全局唯一ID,优点是操作简单,也能实现全局唯一的效果,缺点呢,就是不能体现全局视野的递增趋势;太长了,UUID是32位,有点浪费;最重要的,是插入的效率低,因为呢,我们使用mysql的话,一般都是B+tree的结构来存储索引,假如是数据库自带的那种主键自增,节点满了,会裂变出新的节点,新节点满了,再去裂变新的节点,这样利用率和效率都很高。而UUID是无序的,会造成中间节点的分裂,也会造成不饱和的节点,插入的效率自然就比较低下了。

方案三,雪花算法SnowFlake,是推特公司使用的一款通过划分命名空间并行生成的算法,来解决全局唯一ID的需求,类似的还有MongoDB的object_id。

雪花算法,是64位二进制,转换十进制,不超过20位。第一位是符号位,一般是不变的0,第二阶梯的是41位的毫秒,第三阶梯是10位的机器ID,第四阶梯是12位的序列号,雪花算法能保证一毫秒内,支持1024*4096个并发,400多W了,对付绝大多数场景,都适用了。优点就是方案一和方案二的不足的反例—不依赖中间件、可以体现趋势递增,且通过第三阶梯的机器ID可以知道是哪一台机器生成的ID,缺点呢,就是因为雪花算法是依赖毫秒,而毫秒又是通过本机来获取的,假如本机的时钟回拨了,那就乱套了,可能会造成ID冲突或者ID乱序。

原文:https://blog.csdn.net/zy_281870667/article/details/80173863

你可能感兴趣的:(工作)