Wix如何零停机将将2000个微服务迁移到多集群Kafka?


为了更轻松地将 2000 个微服务的生产者和消费者迁移到多个托管的 Kafka 集群,最初的设计依赖于首先完全排空每个数据中心(DC)的流量。
这种设计意味着只需将生产者和消费者的连接细节切换到他们的新 Kafka 集群。由于 Wix 微服务使用 Greyhound 层连接到 Kafka 集群,因此只需要在一个地方更改连接——Greyhound 生产配置(同时确保只有 1 个 DC 受到影响)。
尽管这个设计很简单,但遗憾的是无法实现和执行。有几个原因:

  1. 有些服务只部署在其中一个数据中心,很难移动。
  2. 这种设计意味着全有或全无,并且在流量返回的那一刻非常危险。在未切换的边缘情况下,它们可能会遭受数据丢失。
  3. 流量不能在很长一段时间内完全从数据中心排出,因为这可能会大大增加某些服务停机的风险。

相反,计划进行一项新设计,涉及实时流量期间的迁移。

随流量迁移
在实时流量期间执行迁移意味着必须进行细致的规划和执行。
这个过程必须是渐进的(每次只影响一些微服务,以便在出现问题时减少爆炸半径)并且完全自动化,以减少手动错误的机会,包括回滚过程的自动化。
首先迁移生产者(在消费者之前)不是一种选择,因为这意味着需要相当长的时间来确保所有消费者都完成了对自托管集群上的所有记录的处理,并且可以安全地切换到新的集群主题。这将导致处理中的相当大的延迟,从而可能损害某些 OLTP 业务流程和用户。此外,如果没有数据丢失,由于某些意外问题而回滚消费者是不可能的。
必须首先切换活动的 Kafka 消费者,同时确保没有消息丢失并且对记录的重新处理最少。这样做的唯一方法是首先将所有消费主题的记录从自己的主机集群复制到目标托管集群。

复制
为了确保在迁移过程中不会丢失消息处理,我们创建了一个专用的复制服务。一旦确定了所有消费者主题,复制器服务就会被命令在适当的云集群中创建主题,并开始使用自托管集群中的记录并将它们生成到目标集群。

消费者迁移
为了方便消费者迁移,Replicator 还持久化了每个分区的偏移量映射,以便 Greyhound 消费者可以从正确的偏移量开始处理云集群中的记录——该偏移量是从自托管集群中的第一个未提交的偏移量映射的.
除了 Replicator 之外,还有一个 Migration Orchestrator 可以确保复制主题、映射所有偏移量,然后继续请求 Greyhound 消费者取消订阅自托管集群。验证成功后,Orchestrator 请求消费者订阅云集群,同时首先寻找正确的映射偏移量。
如果发生故障,Orchestrator 能够请求使用者恢复到自托管集群。
所有这些 Orchestrator 到消费者的通信本身都是通过专门的 Kafka 迁移主题完成的。Greyhound 消费者在这些主题开始时就开始侦听。

生产者迁移
一旦某个主题的所有消费者被迁移,就有可能迁移其生产者。
最初的迁移设计需要请求生产者切换集群连接,同时仍然接受传入的生产请求。这意味着在内存中缓冲这些请求,而且被认为是相当危险的。
后来我们想出了一个更简单的设计,它依赖于Wix的渐进式Kubernetes部署过程。每个新的pod只有在其所有的健康检查都正常时才开始接受传入的请求,包括与Kafka的连接。由于这个过程是循序渐进的,总有一些 "老 "的pod在运行,这样服务作为一个整体总是可以接受传入的请求。
在pod启动时,Greyhound生产者只需检查一个数据库,以确定他们应该连接到哪个集群。这比动态集群切换和记录缓冲要简单得多。这意味着迁移是安全的,没有请求会丢失,服务保持在高可用性。

复制的瓶颈
只有当生产者被迁移后,停止话题的复制才是可以接受的。但是为了迁移生产者,首先必须迁移其所有的主题消费者。
事实证明,许多主题有来自不同服务的多个消费者,这意味着Replicator消费者需要处理和复制的流量越来越多。
这就造成了一个问题,由于我们相对较老的自营Kafka经纪人版本的技术限制,消费者可以处理的主题数量达到了限制。在几次尝试增加message.max.bytes的结果都适得其反(见KAFKA-9254 bug),并造成了严重的问题后,我们决定简单地增加Replicator消费者,并在他们之间分片处理要复制的主题。

最佳实践和提示
以下是成功进行Kafka集群迁移的最佳实践和技巧清单。

  • 创建一个脚本,自己检查状态,如果没有达到预期状态就停止
    让迁移过程尽可能的自动化是关键,所以让脚本自己检查是否可以进入下一阶段,可以大大加快迁移过程。另一方面,自动回滚和自我修复是很难做到的,所以最好把它留给人工干预。
  • 准备好随时可以使用的回滚
    不管你的迁移代码测试得有多好,生产环境是不确定的领域。为每个阶段准备一个现成的回滚选项是非常重要的。一定要提前准备好,并在开始运行迁移之前尽可能多地测试它。
  • 从测试/中继主题和无影响主题开始
    迁移可能是非常危险的,因为记录有可能丢失,或者恢复起来很痛苦。请确保用测试主题开始测试你的迁移代码。为了有一个真实的检查。使用测试主题,通过将真实的生产记录复制到一个特殊的测试应用中的测试主题,实际模仿生产主题。这样,消费者迁移过程中的失败不会对生产产生任何影响,但它将为你提供一个更真实的生产模拟。
  • 创建自定义的指标仪表板,显示当前和演变的状态
    即使你创建了一个完全无人值守的自动迁移过程,你仍然需要能够监控正在发生的事情,并在出现问题时拥有调查的工具。请确保提前准备好专门的监控仪表板,清楚地显示你正在迁移的消费者和生产者的当前和历史状态。
  • 确保你的自我托管的Kafka代理处于最新的补丁版本上
    由于我们的自营Kafka代理没有使用最新的补丁版本,当我们多次尝试增加message.max.bytes的值时,最终出现了生产事故(详见本篇文章的复制瓶颈部分)。我的建议是,首先增加你的自营集群Kafka Broker的版本。如果不是最新的,那至少也要增加到最新的补丁版本。