Master-Worker 架构的灰度发布困难

莱莱  金牌会员 | 2024-6-15 00:44:31 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 574|帖子 574|积分 1722

作者:石超



一、媒介

Master-Worker 架构是成熟的分布式体系设计模式,具有集中控制、资源使用率高、容错简朴等长处。我们数据中心内的险些全部分布式体系都采用了如许的架构。

我们曾经发生过级联故障,造成了整个集群范围的服务中断。这让我们反思到 Master-Worker 架构难以有效的分批灰度发布的问题。本文试图分析此中原因,并实验提出几种办理方案。

二、Master-Worker 架构

Master-Worker 架构有时也被称为 Master-Server 架构 或 Master-Slave 架构。

在实践中,为了避免 Master 成为单点故障,Master 通常由多个节点用 Raft 构成的服务,以一主多从的形式出现。有时在一个 Raft 服务中,我们也用 Master 和 Slave 述语指代主和从节点。为了避免肴杂,这里我们称为 Master 的“主节点”和“从节点”,主从节点统称为“一组 Master 节点”。

据体系的规模的不同,Master 节点通常能够管理数台至数万台 Worker 节点。

下面介绍几种常见的 Master-Worker 架构。第一种是经典的分布式体系架构,后两种是常见变种。其实它们都披着外衣而本质相的架构。
2.1 经典架构





根在有些体系中,用户总是必要访问 Master 才能得到服务。若 Master 故障,则整个集群服务中断。必要指出的是,这里说的故障不肯定是步伐瓦解,还包括性能下降、死锁等其他形式的功能失效。Raft 的高可用机制能很利益理如宕机、步伐瓦解等明确的问题,却难以处理这些“半死不活”的问题。我们曾经遇到过部门线程失效而心跳线程仍旧好好的活着的问题。墨菲定律说,只要大概发生的事,终极都会发生。在我们如许云计算数据中心规模和长时间的摆设中,各种特别古怪的问题都会被撞见。
2.2 数据面和控制面分离





在数据面和控制面分离的设计中,用户直接和数据面的节点交互。有中心化摆设的管控节点,负责负载均衡、宕机恢复、限流等集中工作。用户的哀求路径不颠末中心管控节点。中心管控节点和数据面节点构成 Master-Worker 架构。只管数据面划分了多个集群,但中心管控同时毗连了多个集群的数据面,同样有级联故障隐患。假想如许的场景:中心管控升级后,发送了新格式哀求到数据节点。后者无法正确处理新格式的哀求,产生 coredump。
2.3 有网络功能的基础组件库





步伐倚赖的公共基础组件,如安全、运维、监控等,很多以 SDK 库的形式嵌入在服务进程中。SDK 作为客户端和公共组件服务的服务端通讯,或上报信息,或拉取配置。如许,SDK 和服务端也构建经典的 Master-Worker 架构。这些 SDK 只管是旁路体系,但仍旧有机会“兴风作浪”,像上面“数据面和控制面分离”一节那样引发数据节点的级联故障。公共服务通常被众多服务使用,一旦发生如许的问题,影响面积将更大。

三、灰度发布的困难

灰度发布是防范故障的最重要手段。典范的灰度发布是如许工作的:在一个集群中,依次升级每个节点,同时观察整个服务有单机异常或团体服务受损。一旦观测到服务受损,则立刻中止发布。由于分布式体系自身具有自动恢复(failover)能力,除非是如 coredump 之类的明显问题,从服务团体角度观测必要肯定时间。
3.1 分片架构

在普通服务中,如许的灰度发布机制能很好工作。考虑一个由多个节点构成的服务,分批发布,每批一个节点。每批之间观察哀求乐成率,若跌破阈值则中止发布。现在我们发布一个带 bug 的新版本。在完成第二批发布后,我们观察到体系哀求乐成率下跌超过阈值,因此中止发布。

这个模子比较简朴,但足够说明问题。在实际中,自动恢复机制能粉饰错误。比方,网关服务能够将失败的哀求发送至别的的节点重试。但我们仍旧能通过蛛丝马迹发现故障。在前述例子中,我们能够通过网关重试率指标来辨认到问题。




3.2 Master-Worker 架构

然而在 Master-Worker 架构中,灰度发布机制却不是总是有效。让我们看看在如许的体系中如何进行灰度发布,并分析它无效的原因。




假如现在有 A、B、C 三个 master 节点,此中 B 是主节点。灰度发布步骤如下:
1.升级 A 到新版本。
2.升级 C 到新版本。
3.主从切换,由新升级的 A 作为主节点。
4.升级 B 到新版本。

在执行每步时,我们同样要观察现有服务是否受损。一旦服务受损就立刻中止发布。用如许的方法,看似做了灰度,其实第三步主从切换的有很大的风险。考虑假想的极端情况:A 的新版本增长了新的功能,在 A->Worker 心跳等广播类报文中增长新的哀求字段。而 Worker 恰好无法处理这个新增字段,导致了死锁或步伐瓦解。如许就会导致整个集群内大范围的服务中断。

灰度发布机制对防范此类问题无能为力。Master 的主节点的新代码,只有在第三步主从节换后才能运行起来。一旦新代码被运行起来,在 Master 如许重要的节点,对整个集群大概产生庞大影响。这些影响是 0 或 1 的影响,而不是渐近式的影响。因此,在如许的架构无法有效实现灰度发布。

四、办理方案

解法一:Master 分片





在经典的 Master-Worker 架构中,Master 主节点是单体式的。我们可以将它的功能拆分成到多个分片,让每个分片能够单独地升级。如许,整个体系的发布酿成渐近式的,给我们创造出了观察窗口。

这种方法能够防止 Master 服务自身出现庞大故障。但如果 Master 和 Worker 仍旧是高度互联的,无法避免故障沿网络传播至 Worker 全部节点,终极造成服务中断。此外,Master 承担的某些功能天然是集中式的,也就无法用这个方法拆分成多个分片。

解法二:分批推送





另一个思绪是堵截故障的快速传播途径。级联故障之所以发生,是由于 master 在升级到新版本后立刻运行了新的代码路径,发送了新的 RPC 给 worker 节点,从而造成 worker 节点运行到了未经测试的代码路径。这个过程是立时发生,没有分批灰度的。我们可以在这里也引入分批灰度的机制。

这个方案也有短板。在复杂体系中 Master->Server 交互众多,很难针对每个交互都增长如许分批灰度的限制。实际中,分批机制一样寻常只能覆盖到几个重点功能。
解法三:小而稳的 SDK 库


末了一个解法是为公共服务 SDK 库量身定制的。DNS 是最简朴的带有网络功能的 SDK 库,它却很少出问题。究其原因,是由于它的功能足够简朴。借鉴这个思绪,我们可以把 SDK 库做得简朴,控制代码量在一千行以内,颠末充实测试,能做到近乎 bug-free。

据我所知,能做到这个标准最复杂的库是 sqlite,它有 15 万行代码,但分支覆盖率到达了恐怖的 100%。考虑到我们实际的工程水平,一千行代码是我们能做到的极限。如果 SDK 的功能复杂,无法精减,那么可以将部门逻辑拆分到本机摆设的 agent。而 agent 总是比 SDK 更轻易做分批灰度发布。

五、结语

防范集群范围的级联故联是分布式体系中的困难。本文提出了三种方法,但它们都有各自的范围。在写作本文时,我找了很多同事讨论,也在互联网上搜刮,以及问 ChatGPT,但是都没有得到令人满足的答案。本文抛砖引玉,如果读者想到更好的方法,欢迎一起讨论。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

莱莱

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表