前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >系统日报-20220127(听说面试常考高性能分布式 ID 生成算法?)

系统日报-20220127(听说面试常考高性能分布式 ID 生成算法?)

作者头像
木鸟杂记
发布2022-03-31 20:33:58
3090
发布2022-03-31 20:33:58
举报
文章被收录于专栏:木鸟杂记木鸟杂记

分布式高性能 ID 生成算法——Snowflake ID。

维基百科 Snowflake ID 格式Untitled

来源https://blog.twitter.com/engineering/en_us/a/2010/announcing-snowflake[2]

摘要雪花算法(Snowflake ID) 是时下应用相当广的一个分布式全序 ID 生成算法,这篇 Twitter 官方博客 2010 年的文章,宣告了雪花算法的诞生,概略的介绍了 Twitter 当时对分布式 ID 生产算法需求的背景(context)、可选项和最终方案。理解了其产生时的需求,也就理解了算法的一半,推荐一读。

问题背景。Twitter 的数据库经历了一个从小到大、从单机到分布式的增长过程。但无论在分布式数据库 Cassandra[3] 中,还是使用 gizzard[4] 方案水平扩容的多机 MySQL 中,都没有一个满足 Twitter 当时需求的全局 ID 生成方案。那 Twitter 当时对全局 ID 的要求是什么呢?

  1. 每秒产生数万个 ID。这就限制了不能使用依赖多机沟通来产生 ID。毕竟一次网络通信延迟都会有 1ms+,自然难以实现超过 1k 的 qps。
  2. 所有 ID 满足全序(roughly sortable)关系。即任意两个 id 都是可比的,毕竟 Feed 流中所有 Tweet 的排序都依赖此 ID。
  3. 长度不超过 64 bit 。Twitter 以前经历过随着系统体量的增大而痛苦的增加 ID bit 数的过程,这次希望一步到位,但同时又不太长。

可选项。基于 MySQL 的自增 id,类似于 flickr[5] 的方案。但不通过多机同步,难以提供全序保证。

一些现成的 UUID 算法,但其生成的 ID 都是 128 bit。

基于 Zookeeper 的全局自增 id 。自然,由于 Zab 等共识算法,其能保证全序,却不能满足 Twitter 的性能需求。

最终方案。通过组合时间戳、进程编号、自增序号,Twitter 找到了一种分布式高性能全序 ID 生成算法。基本思想是,大体保证机器间的时钟同步,并利用机器时钟生成时间戳作为自增 ID,如果两个进程产生了相同时间戳,则通过进程编号进一步确认其大小。由于一般时间戳会精确到毫秒,为了满足 QPS 需求,会留几位给自增 id,使得 1ms 内产生 10+ 个 id。

最终格式如上图,1 bit 的符号位,固定为0,以保证在有符号数体系下 ID 也为正数。41 bit 的时间戳,单位 ms,时间戳本身是个相对值,其起始点可以自行设置。10 bit 的进程编号,最终可支持含有 1024 个进程的单机或者集群,但一般来说,每个机器一个进程。12 bit 的自增序号,每毫秒最多允许产生 4k+ 个 ID。

在实际使用时,可以在保证总 bit 数的情况下,按需调整三个字段的 bit 数。比如进程数确定不会超过 100 个,则可以将对应字段缩短为 7 bit。进程序号可以在初始时通过一个全局发号器来分配,比如 Zookeeper。在之后的运行或者重启时,无需再改。

开源代码在此[6],其优点如下:

  1. 高性能(Performance)。单进程 10k+ 的 QPS,平均 2ms 的延迟。
  2. 无需沟通(Uncoordinated)。产生 ID 的这组进程,可以分布在多个数据中心的多个机器,而在产生数据时无需进行互相沟通(除了 NTP 时间戳同步)。
  3. 大致按时间有序(Roughly Time Ordered)。可以从 ID 中解析出时间戳。
  4. 可直接排序(Directly Sortable)。无需解析即可直接排序。
  5. 紧凑(Compact)。不要 128 bit 就要 64 bit。
  6. 高可用(Highly Available)。将进程分布在多数据中心的多台机器上,只要有一台机器活着,就仍能提供服务。

一些问题。雪花算法会隐式的依赖机器时钟,虽然并不严格。但使用者需要保证产生 ID 的所有机器通过 NTP 保持大致的时间同步。snowflake 算法可以处理由于 NTP 时钟同步带来的时钟回退问题。但解决方法很粗暴,即发现时钟回退了就死等到时钟超过上一次 ID 产生的对应时间点。也正因如此,需要维持所有机器时钟大致同步。

参考资料

[1]任何想法都欢迎来提 issue: https://github.com/DistSysCorp/ArticleListWeekly/issues

[2]Announcing Snowflake: https://blog.twitter.com/engineering/en_us/a/2010/announcing-snowflake

[3]Cassandra: Open Source NoSQL Database: http://cassandra.apache.org/

[4]gizzard: http://github.com/twitter/gizzard

[5]Ticket Servers: Distributed Unique Primary Keys on the Cheap: https://code.flickr.net/2010/02/08/ticket-servers-distributed-unique-primary-keys-on-the-cheap/

[6]snowflake 2010: https://github.com/twitter-archive/snowflake/tree/snowflake-2010

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-01-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 木鸟杂记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 分布式高性能 ID 生成算法——Snowflake ID。
    • 参考资料
    相关产品与服务
    云数据库 MySQL
    腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档