在这篇文章中,我们将带您在整合和利用之旅LinkedIn的布鲁克林平台作为一个镜像技术来代替卡夫卡镜制造商(KMM)。

我们将解释我们是如何从配置,使用和维护转变212独特的卡夫卡镜子制造商集群,只有14布鲁克林集群,支持33个地方卡夫卡集群和17个总卡夫卡集群。在转变,我们用较少的57%的CPU,同时成功地管理我们的卡夫卡环境获得新的能力。我们进行这种迁移与成千上万的机器和数以千计的CPU,处理每秒超过15万条信息组成的环境没有全球性的停机时间。

在我们深入实施细则,让我们来讨论关键技术和难题,以获得对土地打下了手柄设置一些背景。

卡夫卡,卡夫卡无处不在...

卡夫卡从分布式流媒体平台Apache软件基金会,是我们在Wayfair大数据平台的重要组成部分。我们用卡夫卡建立实时数据流应用和数据管道供应种类繁多的使用情况,包括事件消息,网络活动跟踪,变更数据捕获(CDC)流,记录和度量聚集,流处理。

自部署以来4年前,我们已经观察到卡夫卡的使用和采用的急剧增加。这主要是由两个因素推动。首先,出现了在我们的核心店面的网络流量的持续增长通过我们快速增长的客户群的推动。其次,很多球队从传统消息和批量为基础的系统的实时数据管道是规模搬走。今天,卡夫卡的网友发布的共约90K主题,围绕创建每秒15万条信息周围每天1.3万亿的消息。交通运行对地理上分散的数据中心(DC)的极少数中的一个内完全运行我们的内部部署,并在谷歌云(GCP)操作33个地方卡夫卡集群这种高容量。

卡夫卡的建立是为了在单个数据中心内运行,虽然它可以跨多个可用区的单个DC内建成。我们还运行另一个17簇用作骨料卡夫卡簇,组合来自位于各个数据中心内的多个本地卡夫卡簇的数据。例如,我们有一个本地卡夫卡集群记录工作负载在我们所有的数据中心。系统发送其日志本地卡夫卡集群中的ownDC,但是,我们也希望能够处理汇总后的数据。要做到这一点,我们运行两个区议会两个额外的聚合卡夫卡集群,专门致力于为记录工作负载。这两个聚合Kafka集群不仅运行我们的日志摄取、聚合和报告系统,而且帮助实现高可用性,使我们能够承受单个数据中心的损失并保持日志流动。

更多镜子庄家

现在的问题是 - 我们如何在卡夫卡从一个数据中心获取数据到另一个数据中心?更具体地讲,我们如何复制从本地卡夫卡集群总结卡夫卡集群数据?这其中,卡夫卡镜制造商(KMM)镜像设备配合是他们自己的类型服务器的“集群”的,所以我们会打电话给他们KMM集群。为了支持来自33个地方卡夫卡集群的数据复制到相应的总结17个卡夫卡集群,我们需要操作212 (!)不同的KMM集群,围绕〜8000虚拟中央处理器。毫不奇怪,这种复杂的拓扑结构导致了高额的资金和运营成本。

我们只好跑这么多KMMs,因为他们只支持单一的源将数据发送到一个单一的目标。也就是说,KMM可以从一个地方卡夫卡集群将数据发送到一个聚合卡夫卡集群。下图描绘了用于为简单起见两个靶的DC卡夫卡镜像过程:

图1:Wayfair上的Kafka镜像

为了说明集群数量不断增加带来的高可维护性和成本问题,让我们以两个odc为例。下图演示了使用的KMM数据聚合的拓扑DC1DC2。在给定的例子,你会发现,一共有四个KMM集群(被描绘为紫色框)正在使用。回想一下,KMM仅支持一对一的源和目的地的映射。

图2:卡夫卡镜制造者拓扑

图2:卡夫卡镜制造者拓扑

如果我们推断单个数据流和地方卡夫卡集群分散在d从数据中心,复制数据ñ来源目标,我们需要N * M个(哪里d总共具有相同的值)制镜簇。

时间不长,之前的团队意识到,是时候寻找一个替代品,作为当前的系统不符合我们的质量标准,并加入巨大的经营辛劳。具体来说,有以下迫在眉睫的挑战和需要支持不断增长的用户群成为了变革的驱动因素:

  • 每个KMM管道需要一个到一个复制(1个源:1个目的地)导致超过212个集群来支持数据聚合用例。
  • 计算成本(vCPU的#)过高,因为我们是用整个KMM集群8K左右的vCPU。
  • 有几个问题与KMM 1.0版本,导致频繁的服务故障。这些措施包括卡夫卡重新平衡和随后的卡夫卡话题滞后积累,缺少目标群集的话题,并没有得到解决的错误,仅举几例。平均下来,我们正在处理每月〜12个问题。
  • 频繁的服务中断和增加的延迟不仅使我们的内部客户感到不满,而且使我们的支持工作流过度紧张。

我们选择了基于我们的初步研究评估了以下系统:

为了评估这些产品,我们使用的需求记分卡基础上,莫斯科中号UST,小号HOULD或有限公司uld或w ^on't有)优先框架来对一组预定义的功能评价平台。这些特征包括能力很好地扩展,易于配置,成本,细粒主题的对照(选择性主题复制),高性能,弹性等布鲁克林(每人服务器第二消息数)的额定中所有平台的最高的。

更好地与布鲁克林

布鲁克林是LinkedIn的团队开发了一个开源的系统,“在大规模可靠的近线数据流的可扩展的分布式系统。”它可以作为一个数据流平台读取和发布到异构一套系统。要了解更多信息,请参阅开源布鲁克林:近实时数据流的规模博客。下面的图表提供了平台的高级概述。

图3:布鲁克林高层次图

图3:布鲁克林高级示意图[来源:HTTPS://github.com/linkedin/Brooklin/]

布鲁克林建作为一般的流媒体平台,它可以当镜子用设备(MM)跨卡夫卡群集复制数据。要绘制在我们前面的例子(图2)KMM拓扑结构的比较,让我们来看看BMM拓扑两个区议会。如下面的图中可以看出,我们能够使用一个单一的布鲁克林集群从位于不同数据中心的多个来源聚合数据。在多重任务处理模型允许来自多个源的在单个布鲁克林簇多个目的地的数据流创建。这大大降低了镜像的簇的数目。

图4:布鲁克林镜制造者拓扑

图4:布鲁克林镜制造者拓扑

在四大流媒体平台中,Brooklin以绝对优势脱颖而出,原因如下:

  • 可扩展性:BMM允许水平地和垂直缩放任何给定的簇的大小在两个不同的维度。由于该任务分区策略的灵活性,一个可以增加节点上的存储器和CPU在现有的簇(垂直缩放)或添加新节点集群动态(水平缩放)。这种灵活性使我们比簇更多的控制,我们可以将它们调整到工作负载的地址特定需求。
  • 多租户模型:BMM允许来自多个源向多个目的地使用单个簇的镜面。这从中断(并且是一个巨大的进步到)KMM的“每一个源集群:目的地配对”的方法。添加新的数据流不再需要建立一个新的集群。
  • 轻松的设置:布鲁克林的结构是简单的和(在我们的情况下,经由木偶)容易自动化,因此添加新节点到现有的群集,或创建全新的簇很简单,只要在配置重写参数。
  • 数据流管理RESTful API中:向Brooklin添加新的镜像流需要一个单行命令来创建一个新的datastream。现在,简单的REST调用可以执行所需的所有主要管理操作。一个特别的提示:通过api暂停流的能力对于管理镜像制造商的操作非常有帮助。
  • 与Linkedin的早期合作:在项目早期,我们联系了LinkedIn与问题,并修复了很多问题,我们在测试中发现的。该团队欢迎我们张开双臂,给了我们洞悉其经验,路线图和配置。与LinkedIn的团队一个开放,合作初期极大​​地帮助我们在我们的实现。
  • 高通量:BMM簇提供〜2.5倍以上的网络吞吐量(以字节/字节出)比KMM簇具有相同的设置和资源。
  • 积极开发管道:一个活跃的开发社区意味着错误和功能将继续固定和添加到该平台。
  • 可扩展性:Brooklin架构是一个通用的数据移动平台。如果迁移进展顺利,我们将有许多其他方法来利用和扩展Brooklin来满足我们的总体数据迁移需求。

实现方法

后评价,我们开始实施该系统,以支持我们目前的关键业务通讯管道同时还要考虑我们的未来缩放需要考虑。这需要在之前在四月Wayfair的大型销售活动为期三个月的时间表来实现。我们分享我们的做法和重要经验如下:

  1. 尝试和应用

在过去,我们进行了多次优化KMM参数的迭代。这些努力没有白费。我们首先在KMM和BMM参数之间绘制平行线并创建一个地图。我们使用了一个N1-标准16机器类型与度量工作量。我们的目标是要配置设置,使我们能够通过调整记录大小,批量大小和超时来实现,如表1所列一个稳定的平台。

布鲁克林的显著优点是可用来调生产者的工作量参数(numProducersPerConnectortransportProvider这有助于提高生产者的整体生产能力。按节点使用两个生产者线程的能力允许我们线性扩展,这导致生产者和消费者之间的字节进出平衡。

下表显示,帮助减少内存异常(奥姆斯)的重新平衡和Out的数量,并且可以通过站立时的初始稳定的测试环境增加了结果:

表1:BMM参数整定结果

参数 描述 KMM BMM
max.poll.records 在一个单一的调用返回的调查记录()的最大数量 1000-6000 500
max.poll.interval.ms

(毫秒)

使用消费群的管理时,民意调查()的调用之间的最大延迟 600000毫秒 120000毫秒
pollTimeoutMs

(毫秒)

超时(毫秒)花费在民意调查电话卡夫卡等待如果没有数据可用 NA 900000 -1,505,000毫秒
batch.size 记录在一个单一批次生产数量 32K-100K 16,384
buffer.memory(兆字节) 的总字节数的存储器中的生产者可以使用缓冲正在等待被发送到服务器记录 256-1024 MB 128-512 MB

我们在2019年12月进行了试点,部署Brooklin作为备用实例度量总结卡夫卡集群,在我们的GCP的数据中心的一个运行。在圣诞节和新年之间的假期周的高峰负荷期间进行了成功试验进一步验证了我们的工作。

2.首先解决最复杂的问题

在Wayfair,我们有三个主要卡夫卡的工作负载,日志,点击流,度量,在很大程度上推动我们对卡夫卡和所有其他相关服务的需求。为每个规格而变化,但它们通常被表征为:

  • 高消息率,小消息(度量
  • 低消息率,大消息(记录
  • 较低的消息率,异构消息的大小(点击流

下面下列2X2矩阵映射消息的这三种工作负载的消息大小和输入速率,并提供了这些系统的体积和速度感。

图5:记录,指标,点击流工作负载的2X2负载简档矩阵

图5:记录,指标,点击流工作负载的2X2负载简档矩阵

在下表中,我们列出了特定的消息率、Kafka主题的总数、平均分区数、平均消息大小和每个数据中心每个工作负载接收到的平均字节数。

表2:工作负载概要度量,日志记录,点击流每个数据中心

工作量

(每DC)

消息率

每秒(消息)

总主题# 平均分区#复制 平均消息大小(KB) 平均bytes_in

(MB / s)的

度量 1-5万元 4 68 20-22 250 - 400
记录 400-450ķ 205 442 55-65 200-275
点击流 200-400ķ 365 302 80 - 100 128-512

对于我们的第一个迁移从KMM到BMM,我们选择了度量Kafka集群在所有DCs上每秒处理超过1060万条消息。我们认为这是最具挑战性的工作流程,因为这些集群处理的消息速度非常快。此外,这些集群对正常运行时间有最严格的要求,对主题延迟的容忍度最低。因此,解决这些挑战度量第一工作流将作为我们的数据管道的其余部分的试金石。

3.协作,贡献

在这个项目的过程中,团队密切配合,在LinkedIn内部团队和外部合作伙伴合作。LinkedIn的团队是非常有帮助的,并分享了它的建筑和环境,非常符合我们的决策帮助我们的详细信息。有我们的实施过程中发现的两个主要问题。

首先,我们遇到了一些bug。我们发现了一个导致Brooklin集群因为处理Zookeeper会话过期事件而无领导的bug。我们报告了一个bug并发布了一个pull request (PR) -ZooKeeper的会话泄漏修复。我们遇到了另一个在目标主题中丢失记录键的bug,再次发布PR来解决这个问题-缺少卡夫卡目标主题记录键

其次,我们发现,部分集群关机期间,负载均衡会发出太多的任务的一些活动节点。这偶尔会压倒节点的子集,导致Linux的奥姆斯和后续节点故障。要解决这个问题,我们引入了一个新的参数(见新的maxTasksPerInstance选项)限制每个数据流分配给单个节点实例的任务数量。通过限制任何单个节点处理的任务数量,我们现在可以防止由于节点故障而导致的domino效应,最终减少重新平衡的数量并提高总体稳定性。

在项目的不同阶段,我们还与这三队的合作是拥有度量,日志记录,点击流工作量,以得到早期反馈。在一种情况下,我们进行了压力测试与记录度量团队成功地测试他们的3倍典型负载。在另一种情况下,我们协助度量团队调试中,他们的背压机制踢的问题。原来的团队承担了一定的滞后性,而调整后的压力。布鲁克林复制恢复如此之快,它看起来像一个流量高峰,造成背压机制在踢。这导致了度量团队执行他们的系统和一套合理回压阈值的重新校准。

通过紧密的合作,我们确保从卡夫卡镜面制造商的过渡是无缝为我们的客户。

4.学习和迭代!

Wayfair文化的尝试;测量;提高。我们有证明这种心态两个快速的例子。首先,我们最初部署的虚拟机上的布鲁克林。当我们提到这对LinkedIn的球队,他们有兴趣听听它如何去,因为他们已经部署了体检,但也考虑到迁移的虚拟机。虚拟机都很好,但我们想做得更多。由于集装箱的许多好处,我们决定采取集装布鲁克林。我们取得了一些初步的成功,但是,我们发现,布鲁克林服务是正常的维护非常敏感/重建K8S荚的周期。在Wayfair K8S队只在那个时间点支持无状态的应用程序。 In order to avoid instability in the environment, we decided to pivot away from K8s back to VMs.

在摆动我们的部署回虚拟机,我们需要确定相应的设置在我们的集群应用。我们想选择哪个,我们可以为了简化和精简这些集群的管理工作流程,跨应用的标准化群集配置。每个工作流被在一个时间迭代测试,调谐一个设置来衡量其影响,然后移动到下一个设置。多的测试后,我们的工作将它们合并到,可以在所有三个工作流应用单一的配置。虽然这些工作流程的特点不同,我们发现,我们能够找到一个“甜蜜点”,在我们的一些设置,而性能造成负面影响。

要微调的最佳性能的系统,我们的表现团队紧密合作,系统地优化网络流量(配置所有工作负荷bytes_inbytes_out最初用于单个消费者和生产者线程。经过第二轮调优,我们能够将Brooklin系统扩展到单次提供约30 MB /秒的吞吐量N1-标准16节点GCP。这给了我们一个标准“的演出单位”然后我们可以使用水平扩展。接下来,我们使用的单元,计算达到一定量的吞吐量的需要的节点的数目。

下面描述了图横向扩展的具有约1.15十亿滞后的影响。我们的目标是看到处理消息的速度如何缩小与BMM集群中的节点数量。为了进行这种测量,我们跨越相关的三个不同卡夫卡主题产生未处理的消息的队列中的单个数据中心度量

图6:滞后恢复时间未处理的消息5,10和30个BMM节点

图6:滞后恢复时间未处理的消息5,10和30个BMM节点

为1.15十亿的给定的总滞后,一个30节点的配置所带来的恢复时间缩短到〜18分钟相比于具有10个节点的〜40分钟内。红线描绘了在其被处理的消息的数量的斜率或速率。更高(负)斜率是指信息的处理速度更快,有较快的恢复时间。我们确认,信息处理速度与节点的数量很好地扩展。

这个节点级性能基准测试使我们能够很容易地计算出从滞后基于特定的服务级别目标(SLO)一定的时间恢复所需的节点数量,使得大多数其他设置不变。

  1. 测量一次,测试两次

严格全面测试是重点放在稳定性,韧性,以及系统的可测量的性能相结合物中进行,结果共享。这些测试是针对三种不同的工作流程来进行;度量记录点击流,每服独一无二的使用情况。

除了基于系统的度量之外,例如CPU利用率,内存利用率,bytes_inbytes_outDatadog,Kafka特定的度量标准,比如num_rebalances。producer.waiting_threads计数,aggregate.events_byte_processed_rate.mean_rate被用来比较的性能。Kibana / ElasticSearch被用于测量日志在不同级别的错误频率,重新平衡的数记录处理率

上面列出的度量被捕获用于以下测试方案:

  • 重新启动布鲁克林集群
  • 重新启动布鲁克林簇为1小时和4小时值得滞后
  • 重新启动布鲁克林与约1个十亿消息滞后
  • 原因停止源和目标卡夫卡代理节点卡夫卡再平衡。
  • 通过停止高达布鲁克林集群的5个节点造成布鲁克林再平衡

我们进一步调整max.poll.interval.ms,commitIntervalMs,daemonThreadIntervalInSecondsnonGoodStateThresholdMs尽量减少布鲁克林服务的重新启动过程中的滞后。调整还讨论了Java线程任务被杀的问题,由于意外的错误。下表显示了三个工作负载的最后一簇级配置设置。

表3:最终集群级别配置设置度量,记录点击流工作负载(即比其余不同的配置设置标记为粗体)

工作负载的名字 总#BMM节点 消费性 监制性质
每簇消费任务# max.poll.records 每个节点的生产任务# 缓冲。记忆体(MB) batch.size
度量 60 40 500 2 128 16384
记录 40 32 500 2 512 16384
点击流 40 32 500 2 512 16384

结果与结论

迁移到布鲁克林,不仅为我们提供了镜像的平台以较低的复制延迟一个稳定的卡夫卡,但也减少了镜面机集群从数212以区区14布鲁克林集群。这是一个93%系统下降,我们不得不配置和操作。这一举措布鲁克林镜像也产生了57%需要减少在的vCPU。总体而言,迁移导致了数十万美元的部署后的每年节省。

除了降低的基础设施投资,用于保持镜子的庄家操作开销减少了90%,由于较少数量的簇的,简化的配置管理和部署过程。到BMM迁移导致了每月超过10倍,减少了生产问题,同时提高了系统的可用性和客户满意度。

该项目已于2020年3月完成,三个月开始到结束之内。这包括飞行员,安装,测试,部署,培训和文档。成功部署到生产后,我们准备Wayfair的四月保存大,还给销售活动。该系统在大型活动期间的完美无缺。

特别感谢!

建立一个新的大规模流管线和紧迫的时间限制内迁移到这是一个非常艰巨的任务。这将是不可能没有管理层的支持,剃须刀中心的团队,以及强大的利益相关者的合作伙伴关系。

我们想我们感谢我们的团队成员(阿尼尔弗雷德克里希纳桑托什Sukhvinder汤姆)及计划赞助商(佩里Vinay)。我们还要感谢所有其他跨职能团队,其支持和反馈的帮助我们从的PoC快速移动到试点再到最终的部署。

关于我们

Wayfair的大数据工程(BDE)团队是一个核心基础团队,专注于构建安全、可伸缩和可靠的下一代平台。我们推动企业利用数据为数百万网上购买家具的Wayfair用户创造最佳体验的能力。

参考文献

  1. LinkedIn工程:开源布鲁克林
  2. 布鲁克林配置
  3. 卡夫卡文件