写点什么

面试官系列:讲几个分布式自增 ID 的方案?

发布于: 2021 年 02 月 08 日
面试官系列:讲几个分布式自增ID的方案?

1、问题:分布式系统下,自增 ID 的方案有哪些?

分布式系统下,数据唯一性标识,就是通过 ID。而这个 ID 大有文章。考察的点包括了:你对自增策略的了解,对分布式系统下的中间件使用理解。

方案 1:UUID

原因:唯一性

不足:

  • 非自增,不满足复杂业务场景

  • 对于 mysql 的索引来说,对 UUID 进行索引,由于 UUID 长度太长,消耗的磁盘资源非常大,不可取


UUID 是 通用唯一识别码(Universally Unique Identifier)的缩写,是一种软件建构的标准,亦为开放软件基金会组织在分布式计算环境领域的一部分。其目的,是让分布式系统中的所有元素,都能有唯一的辨识信息,而不需要通过中央控制端来做辨识信息的指定。如此一来,每个人都可以创建不与其它人冲突的 UUID。在这样的情况下,就不需考虑数据库创建时的名称重复问题。目前最广泛应用的 UUID,是微软公司的全局唯一标识符(GUID)

方案 2:微服务架构下的 mysql&redis 的自增 ID 方案

微服务架构下的主(id 表-mysql)从(缓存-redis)ID 自增与同步方案:



可靠性:缓存数据可能被动删除导致的 ID 冲突,因此需要手动同步自增 ID 到缓存中。

拓展性:依赖于微服务架构,独立实现自增 ID 策略。

不足:

  • 某些特殊情况,例如数据库手动插入数据,跳过了主从同步的步骤,需要手动同步业务表的 sequence。

  • 微服务:利用 sdk 接口,从对应微服务数据库获取 id。

方案 3:自增 ID 逻辑以单独服务存在


  • 不同的服务,统一问独立的自增 ID 服务要数据(此时服务 D,面临着高并发以及性能的考验,此处大有文章了)

  • 解决性能的前提下,遇到多机部署的场景,服务数据库假设进行了分库,(导致的 id 自增冲突的问题,可以使用不同的起始值和步长),达到 ID 唯一性的目的。

方案 4:雪花算法

Twitter 的 SnowFlake 就是其中分布式 id 生成算法的一种。

参考文章

SnowFlake 算法生成 id 的结果是一个 64bit 大小的整数,它的结构如下图:



给大家举个例子吧,比如下面那个 64 bit 的 long 型数字:

  • 第一个部分,是 1 个 bit:0,这个是无意义的。

  • 第二个部分是 41 个 bit:表示的是时间戳。

  • 第三个部分是 5 个 bit:表示的是机房 id,10001。

  • 第四个部分是 5 个 bit:表示的是机器 id,1 1001。

  • 第五个部分是 12 个 bit:表示的序号,就是某个机房某台机器上这一毫秒内同时生成的 id 的序号,0000 00000000。


由于在 Java 中 64bit 的整数是 long 类型,所以在 Java 中 SnowFlake 算法生成的 id 就是 long 来存储的。

SnowFlake 可以保证:


  1. 所有生成的 id 按时间趋势递增

  2. 整个分布式系统内不会产生重复 id(因为有 datacenterId 和 workerId 来做区分)


欢迎关注公众号:后台技术汇|获取更多技术干活

  • 博主是一名 Java 后端开发工程师,从业互联网已经已经三年了

  • 目前正在维护一个公众号“后台技术汇”,公众号宗旨是:原创 Java 后台开发技术栈的知识分享,分享程序猿专属干货与福利,希望对各位有所帮助。



发布于: 2021 年 02 月 08 日阅读数: 23
用户头像

Diligence is the mother of success. 2018.03.28 加入

公众号:后台技术汇 笔者主要从事Java后台开发,喜欢技术交流与分享,保持饥渴,一起进步!

评论

发布
暂无评论
面试官系列:讲几个分布式自增ID的方案?