分布式面试题总结

谈谈常用的分布式 ID 的设计方案?Snowflake 是否受冬令时切换影响?

典型回答

首先,我们需要明确通常的分布式 ID 定义,基本的要求包括:

全局唯一,区别于单点系统的唯一,全局是要求分布式系统内唯一。

有序性,通常都需要保证生成的 ID 是有序递增的。例如,在数据库存储等场景中,有序 ID 便于确定数据位置,往往更加高效。

目前业界的方案很多,典型方案包括:

基于数据库自增序列的实现。这种方式优缺点都非常明显,好处是简单易用,但是在扩展性和可靠性等方面存在局限性。

基于 Twitter 早期开源的Snowflake的实现,以及相关改动方案。这是目前应用相对比较广泛的一种方式,其结构定义你可以参考下面的示意图。

整体长度通常是 64 (1  41  10  12 = 64)位,适合使用 Java 语言中的 long 类型来存储。

头部是 1 位的正负标识位。

紧跟着的高位部分包含 41 位时间戳,通常使用 System.currentTimeMillis()。

后面是 10 位的 WorkerID,标准定义是 5 位数据中心  5 位机器 ID,组成了机器编号,以区分不同的集群节点。

最后的 12 位就是单位毫秒内可生成的序列号数目的理论极限。

Snowflake 的官方版本是基于 Scala 语言,Java 等其他语言的参考实现有很多,是一种非常简单实用的方式,具体位数的定义是可以根据分布式系统的真实场景进行修改的,并不一定要严格按照示意图中的设计。

Redis、Zookeeper、MangoDB 等中间件,也都有各种唯一 ID 解决方案。其中一些设计也可以算作是 Snowflake 方案的变种。例如,MongoDB 的ObjectId提供了一个 12 byte(96 位)的 ID 定义,其中 32 位用于记录以秒为单位的时间,机器 ID 则为 24 位,16 位用作进程 ID,24 位随机起始的计数序列。

国内的一些大厂开源了其自身的部分分布式 ID 实现,InfoQ 就曾经介绍过微信的seqsvr,它采取了相对复杂的两层架构,并根据社交应用的数据特点进行了针对性设计,具体请参考相关代码实现。另外,百度、美团等也都有开源或者分享了不同的分布式 ID 实现,都可以进行参考。

关于第二个问题,Snowflake 是否受冬令时影响。

我认为没有影响,你可以从 Snowflake 的具体算法实现寻找答案。我们知道 Snowflake 算法的 Java 实现,大都是依赖于 System.currentTimeMillis(),这个数值代表什么呢?从 Javadoc 可以看出,它是返回当前时间和 1970 年 1 月 1 号 UTC 时间相差的毫秒数,这个数值与夏 / 冬令时并没有关系,所以并不受其影响。

考点分析

今天的问题不仅源自面试的热门考点,并且也存在着广泛的应用场景,我前面给出的回答只是一个比较精简的典型方案介绍。我建议你针对特定的方案进行深入分析,以保证在面试官可能会深入追问时能有充分准备;如果恰好在现有系统使用分布式 ID,理解其设计细节是很有必要的。

涉及分布式,很多单机模式下的简单问题突然就变得复杂了,这是分布式天然的复杂性,需要从不同角度去理解适用场景、架构和细节算法,我会从下面的角度进行适当解读:

我们的业务到底需要什么样的分布式 ID,除了唯一和有序,还有哪些必须要考虑的要素?

在实际场景中,针对典型的方案,有哪些可能的局限性或者问题,可以采取什么办法解决呢?

知识扩展

如果试图深入回答这个问题,首先需要明确业务场景的需求要点,我们到底需要一个什么样的分布式 ID?

除了唯一和有序,考虑到分布式系统的功能需要,通常还会额外希望分布式 ID 保证:

有意义,或者说包含更多信息,例如时间、业务等信息。这一点和有序性要求存在一定关联,如果 ID 中包含时间,本身就能保证一定程度的有序,虽然并不能绝对保证。ID 中包含额外信息,在分布式数据存储等场合中,有助于进一步优化数据访问的效率。

高可用性,这是分布式系统的必然要求。前面谈到的方案中,有的是真正意义上的分布式,有得还是传统主从的思路,这一点没有绝对的对错,取决于我们业务对扩展性、性能等方面的要求。

紧凑性,ID 的大小可能受到实际应用的制约,例如数据库存储往往对长 ID 不友好,太长的 ID 会降低 MySQL 等数据库索引的性能;编程语言在处理时也可能受数据类型长度限制。

在具体的生产环境中,还有可能提出对 QPS 等方面的具体要求,尤其是在国内一线互联网公司的业务规模下,更是需要考虑峰值业务场景的数量级层次需求。

第二,主流方案的优缺点分析。

对于数据库自增方案,除了实现简单,它生成的 ID 还能够保

对于数据库自增方案,除了实现简单,它生成的 ID 还能够保证固定步长的递增,使用很方便。

但是,因为每获取一个 ID 就会触发数据库的写请求,是一个代价高昂的操作,构建高扩展性、高性能解决方案比较复杂,性能上限明显,更不要谈扩容等场景的难度了。与此同时,保证数据库方案的高可用性也存在挑战,数据库可能发生宕机,即使采取主从热备等各种措施,也可能出现 ID 重复等问题。

实际大厂商往往是构建了多层的复合架构,例如美团公开的数据库方案Leaf-Segment,引入了起到缓存等作用的 Leaf 层,对数据库操作则是通过数据库中间件提供的批量操作,这样既能保证性能、扩展性,也能保证高可用。但是,这种方案对基础架构层面的要求很多,未必适合普通业务规模的需求。

与其相比,Snowflake 方案的好处是算法简单,依赖也非常少,生成的序列可预测,性能也非常好,比如 Twitter 的峰值超过 10 万 /s。

但是,它也存在一定的不足,例如:

时钟偏斜问题(Clock Skew)。我们知道普通的计算机系统时钟并不能保证长久的一致性,可能发生时钟回拨等问题,这就会导致时间戳不准确,进而产生重复 ID。

针对这一点,Twitter 曾经在文档中建议开启NTP,毕竟 Snowflake 对时间存在依赖,但是也有人提议关闭 NTP。我个人认为还是应该开启 NTP,只是可以考虑将 stepback 设置为 0,以禁止回调。

从设计和具体编码的角度,还有一个很有效的措施就是缓存历史时间戳,然后在序列生成之前进行检验,如果出现当前时间落后于历史时间的不合理情况,可以采取相应的动作,要么重试、等待时钟重新一致,或者就直接提示服务不可用。

另外,序列号的可预测性是把双刃剑,虽然简化了一些工程问题,但很多业务场景并不适合可预测的 ID。如果你用它作为安全令牌之类,则是非常危险的,很容易被黑客猜测并利用。

ID 设计阶段需要谨慎考虑暴露出的信息。例如,Erlang 版本的 flake 实现基于 MAC 地址计算 WorkerID,在安全敏感的领域往往是不可以这样使用的。

从理论上来说,类似 Snowflake 的方案由于时间数据位数的限制,存在与2038 年问题相似的理论极限。虽然目前的系统设计考虑数十年后的问题还太早。

如果更加深入到时钟和分布式系统时序的问题,还有与分布式 ID 相关但又有所区别的问题,比如在分布式系统中,不同机器的时间很可能是不一致的,如何保证事件的有序性?Lamport 在 1978 年的论文(Time, Clocks, and the Ording of Events in a Distributed System)中就有很深入的阐述,有兴趣的同学可以去查找相应的翻译和解读。

最后,我再补充一些当前分布式领域的面试热点,例如:

分布式事务,包括其产生原因、业务背景、主流的解决方案等。

理解CAP、BASE等理论,懂得从最终一致性等角度来思考问题,理解Paxos、Raft等一致性算法。

理解典型的分布式锁实现,例如最常见的Redis 分布式锁。

负载均衡等分布式领域的典型算法,至少要了解主要方案的原理。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • 关于Mongodb的全面总结 MongoDB的内部构造《MongoDB The Definitive Guide》...
    中v中阅读 31,894评论 2 89
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,585评论 18 139
  • 昨天我在《外婆的道歉信》里看到了一句触动人心的话,爱莎的外婆是这么形容谎言的——真相的另一种版本。 ...
    冰舞盛夏阅读 1,013评论 0 1
  • 命世 - 从八王之乱到鸦片战争 十六国遗事 而既然是说了十六国的历史,有始有终,接下来简单说一说剩下的一些地方...
    月轮阅读 216评论 0 2
  • 不记得这是第几次写自我介绍了,因为这一年多,连续参加了 5 期的百人百天跑步班,断断续续参加了 3 期好报的写作班...
    朱家晓晓阅读 373评论 0 0