应用场景(Scenario)

现实中很多业务都有生成唯一ID的需求,例如:

  • 用户ID
  • 微博ID
  • 聊天消息ID
  • 帖子ID
  • 订单ID

需求(Needs)

这个ID往往会作为数据库主键,所以需要保证全局唯一。数据库会在这个字段上建立聚集索引(Clustered Index,参考 MySQL InnoDB),即该字段会影响各条数据再物理存储上的顺序。

ID还要尽可能,节省内存,让数据库索引效率更高。基本上64位整数能够满足绝大多数的场景,但是如果能做到比64位更短那就更好了。需要根据具体业务进行分析,预估出ID的最大值,这个最大值通常比64位整数的上限小很多,于是我们可以用更少的bit表示这个ID。

查询的时候,往往有分页或者排序的需求,所以需要给每条数据添加一个时间字段,并在其上建立普通索引(Secondary Index)。但是普通索引的访问效率比聚集索引慢,如果能够让ID按照时间粗略有序,则可以省去这个时间字段。为什么不是按照时间精确有序呢?因为按照时间精确有序是做不到的,除非用一个单机算法,在分布式场景下做到精确有序性能一般很差。

这就引出了ID生成的三大核心需求:

  • 全局唯一(unique)
  • 按照时间粗略有序(sortable by time)
  • 尽可能短

下面介绍一些常用的生成ID的方法。

UUID

用过MongoDB的人会知道,MongoDB会自动给每一条数据赋予一个唯一的ObjectId,保证不会重复,这是怎么做到的呢?实际上它用的是一种UUID算法,生成的ObjectId占12个字节,由以下几个部分组成,

  • 4个字节表示的Unix timestamp,
  • 3个字节表示的机器的ID
  • 2个字节表示的进程ID
  • 3个字节表示的计数器

UUID是一类算法的统称,具体有不同的实现。UUID的有点是每台机器可以独立产生ID,理论上保证不会重复,所以天然是分布式的,缺点是生成的ID太长,不仅占用内存,而且索引查询效率低。

多台MySQL服务器

既然MySQL可以产生自增ID,那么用多台MySQL服务器,能否组成一个高性能的分布式发号器呢? 显然可以。

假设用8台MySQL服务器协同工作,第一台MySQL初始值是1,每次自增8,第二台MySQL初始值是2,每次自增8,依次类推。前面用一个 round-robin load balancer 挡着,每来一个请求,由 round-robin balancer 随机地将请求发给8台MySQL中的任意一个,然后返回一个ID。

Flickr就是这么做的,仅仅使用了两台MySQL服务器。可见这个方法虽然简单无脑,但是性能足够好。不过要注意,在MySQL中,不需要把所有ID都存下来,每台机器只需要存一个MAX_ID就可以了。这需要用到MySQL的一个REPLACE INTO特性。

这个方法跟单台数据库比,缺点是ID是不是严格递增的,只是粗略递增的。不过这个问题不大,我们的目标是粗略有序,不需要严格递增。

Twitter Snowflake

比如 Twitter 有个成熟的开源项目,就是专门生成ID的,Twitter Snowflake 。Snowflake的核心算法如下:

最高位不用,永远为0,其余三组bit占位均可浮动,看具体的业务需求而定。默认情况下41bit的时间戳可以支持该算法使用到2082年,10bit的工作机器id可以支持1023台机器,序列号支持1毫秒产生4095个自增序列id。

Instagram用了类似的方案,41位表示时间戳,13位表示shard Id(一个shard Id对应一台PostgreSQL机器),最低10位表示自增ID,怎么样,跟Snowflake的设计非常类似吧。这个方案用一个PostgreSQL集群代替了Twitter Snowflake 集群,优点是利用了现成的PostgreSQL,容易懂,维护方便。

有的面试官会问,如何让ID可以粗略的按照时间排序?上面的这种格式的ID,含有时间戳,且在高位,恰好满足要求。如果面试官又问,如何保证ID严格有序呢?在分布式这个场景下,是做不到的,要想高性能,只能做到粗略有序,无法保证严格有序。

如何设计一个分布式ID生成器相关推荐

  1. 来吧,自己动手撸一个分布式ID生成器组件

    在经过了众多轮的面试之后,小林终于进入到了一家互联网公司的基础架构组,小林目前在公司有使用到架构组研究到分布式id生成器,前一阵子大概看了下其内部的实现,发现还是存在一些架构设计不合理之处.但是又由于 ...

  2. 5 大分布式 ID 生成器优缺点简单对比

    点击上方"业余草",选择"置顶公众号" 第一时间获取技术干货和业界资讯! 首选,不管是不是分布式系统,都有 ID 唯一的使用场景.而在分布式场景下,对 ID 的 ...

  3. 五大分布式ID生成器优缺点及对比

    首选,不管是不是分布式系统,都有 ID 唯一的使用场景.而在分布式场景下,对 ID 的唯一性要求更严格! 常见的,我们上淘宝买东西的订单 ID,就是一种分布式 ID.淘宝,前期的订单 id 好像是 1 ...

  4. 五大分布式ID生成器优缺点及对比(Java)

    首选,不管是不是分布式系统,都有 ID 唯一的使用场景.而在分布式场景下,对 ID 的唯一性要求更严格! 常见的,我们上淘宝买东西的订单 ID,就是一种分布式 ID.淘宝,前期的订单 id 好像是 1 ...

  5. 美团(Leaf)分布式ID生成器,好用的一批!

    不了解分布式ID的同学,先行去看<一口气说出 9种 分布式ID生成方式,面试官有点懵了>温习一下基础知识,这里就不再赘述了 美团(Leaf) Leaf是美团推出的一个分布式ID生成服务,名 ...

  6. 分布式ID生成器的解决方案总结

    转载自 分布式ID生成器的解决方案总结 在互联网的业务系统中,涉及到各种各样的ID,如在支付系统中就会有支付ID.退款ID等.那一般生成ID都有哪些解决方案呢?特别是在复杂的分布式系统业务场景中,我们 ...

  7. 融云发送图片消息_IM消息ID技术专题(五):开源分布式ID生成器UidGenerator的技术实现...

    1.引言 很多人一想到IM应用开发,第一印象就是"长连接"."socket"."保活"."协议"这些关键词,没错,这些确 ...

  8. 分布式id生成器:彻底解决雪花算法时间回拨问题

    Butterfly 简介 雪花算法是twitter提出的分布式id生成器方案,但是有三个问题,其中前两个问题在业内很常见: 时间回拨问题 机器id的分配和回收问题 机器id的上限问题 Butterfl ...

  9. IM消息ID技术专题(五):开源分布式ID生成器UidGenerator的技术实现

    1.引言 很多人一想到IM应用开发,第一印象就是"长连接"."socket"."保活"."协议"这些关键词,没错,这些确 ...

最新文章

  1. 《第一行代码》学习笔记18-广播接收器Broadcast_Receiver(1)
  2. 牛客java面试题总结版(一)
  3. Oversea company interview question.
  4. Android 使用NineOldAndroids实现绚丽的ListView左右滑动删除Item效果
  5. 软件工程网络15个人阅读作业2(201521123024丁树乐)
  6. SHELL实战day12
  7. 记账程序及GitHub学习记录3
  8. tinyint数据类型php筛选时怎么判断_PHP从入门到精通(三)PHP语言基础
  9. SAP 服务器文件上传和下载
  10. win10-ubuntu-软件配置-开机root无密码-风扇转速调节
  11. 解决硬盘打不开的问题
  12. 机器人庄园作文_赛尔号作文
  13. 压缩access数据库
  14. pdf怎么删除其中一页与添加新页面
  15. 我的Cocos2d-x学习笔记(十一)触摸、触摸优先级
  16. 分布式事务详解【分布式事务的几种解决方案】彻底搞懂分布式事务
  17. 1058: 素数判定
  18. 【第5篇】人工智能(AI)语音测试原理和实践
  19. Hash学习(3)-冲突的解决
  20. Unity 物体自发光

热门文章

  1. 【codeforces 731D】80-th Level Archeology
  2. 数字图像处理、拼接,图像静态滤镜(GPUImage/GPU加速) - Android
  3. mysql+HTML+css01
  4. java mapreduce 读hbase数据 写入hdfs 含maven依赖
  5. windows10连接共享打印机报错:操作无法完成(错误 0x00000709)
  6. 自己写的asp.net网站在URL传值过程中隐藏真正值的方法
  7. ERP的核心管理思想
  8. 以下哪些属于android控件的touch事件?_聊聊 Android 的 GUI 系统
  9. Service Mesh 最火项目 Istio 架构解析
  10. 二、项目组队(华为项目管理法-孙科炎读书摘要)