如何设计一个分布式ID生成器
应用场景(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生成器相关推荐
- 来吧,自己动手撸一个分布式ID生成器组件
在经过了众多轮的面试之后,小林终于进入到了一家互联网公司的基础架构组,小林目前在公司有使用到架构组研究到分布式id生成器,前一阵子大概看了下其内部的实现,发现还是存在一些架构设计不合理之处.但是又由于 ...
- 5 大分布式 ID 生成器优缺点简单对比
点击上方"业余草",选择"置顶公众号" 第一时间获取技术干货和业界资讯! 首选,不管是不是分布式系统,都有 ID 唯一的使用场景.而在分布式场景下,对 ID 的 ...
- 五大分布式ID生成器优缺点及对比
首选,不管是不是分布式系统,都有 ID 唯一的使用场景.而在分布式场景下,对 ID 的唯一性要求更严格! 常见的,我们上淘宝买东西的订单 ID,就是一种分布式 ID.淘宝,前期的订单 id 好像是 1 ...
- 五大分布式ID生成器优缺点及对比(Java)
首选,不管是不是分布式系统,都有 ID 唯一的使用场景.而在分布式场景下,对 ID 的唯一性要求更严格! 常见的,我们上淘宝买东西的订单 ID,就是一种分布式 ID.淘宝,前期的订单 id 好像是 1 ...
- 美团(Leaf)分布式ID生成器,好用的一批!
不了解分布式ID的同学,先行去看<一口气说出 9种 分布式ID生成方式,面试官有点懵了>温习一下基础知识,这里就不再赘述了 美团(Leaf) Leaf是美团推出的一个分布式ID生成服务,名 ...
- 分布式ID生成器的解决方案总结
转载自 分布式ID生成器的解决方案总结 在互联网的业务系统中,涉及到各种各样的ID,如在支付系统中就会有支付ID.退款ID等.那一般生成ID都有哪些解决方案呢?特别是在复杂的分布式系统业务场景中,我们 ...
- 融云发送图片消息_IM消息ID技术专题(五):开源分布式ID生成器UidGenerator的技术实现...
1.引言 很多人一想到IM应用开发,第一印象就是"长连接"."socket"."保活"."协议"这些关键词,没错,这些确 ...
- 分布式id生成器:彻底解决雪花算法时间回拨问题
Butterfly 简介 雪花算法是twitter提出的分布式id生成器方案,但是有三个问题,其中前两个问题在业内很常见: 时间回拨问题 机器id的分配和回收问题 机器id的上限问题 Butterfl ...
- IM消息ID技术专题(五):开源分布式ID生成器UidGenerator的技术实现
1.引言 很多人一想到IM应用开发,第一印象就是"长连接"."socket"."保活"."协议"这些关键词,没错,这些确 ...
最新文章
- 《第一行代码》学习笔记18-广播接收器Broadcast_Receiver(1)
- 牛客java面试题总结版(一)
- Oversea company interview question.
- Android 使用NineOldAndroids实现绚丽的ListView左右滑动删除Item效果
- 软件工程网络15个人阅读作业2(201521123024丁树乐)
- SHELL实战day12
- 记账程序及GitHub学习记录3
- tinyint数据类型php筛选时怎么判断_PHP从入门到精通(三)PHP语言基础
- SAP 服务器文件上传和下载
- win10-ubuntu-软件配置-开机root无密码-风扇转速调节
- 解决硬盘打不开的问题
- 机器人庄园作文_赛尔号作文
- 压缩access数据库
- pdf怎么删除其中一页与添加新页面
- 我的Cocos2d-x学习笔记(十一)触摸、触摸优先级
- 分布式事务详解【分布式事务的几种解决方案】彻底搞懂分布式事务
- 1058: 素数判定
- 【第5篇】人工智能(AI)语音测试原理和实践
- Hash学习(3)-冲突的解决
- Unity 物体自发光
热门文章
- 【codeforces 731D】80-th Level Archeology
- 数字图像处理、拼接,图像静态滤镜(GPUImage/GPU加速) - Android
- mysql+HTML+css01
- java mapreduce 读hbase数据 写入hdfs 含maven依赖
- windows10连接共享打印机报错:操作无法完成(错误 0x00000709)
- 自己写的asp.net网站在URL传值过程中隐藏真正值的方法
- ERP的核心管理思想
- 以下哪些属于android控件的touch事件?_聊聊 Android 的 GUI 系统
- Service Mesh 最火项目 Istio 架构解析
- 二、项目组队(华为项目管理法-孙科炎读书摘要)