写点什么

打造全球最大规模 Kafka 集群,Uber 的多区域灾备实践

2021 年 1 月 20 日

打造全球最大规模Kafka集群,Uber的多区域灾备实践

Uber 的 Kafka 生态系统

Uber 拥有世界上最大的 Kafka 集群,每天处理数万亿条消息和几个 PB 的数据。如图 1 所示,Kafka 现在成了 Uber 技术栈的基石,我们基于这个基石构建了一个复杂的生态系统,为大量不同的工作流提供支持。其中包含了一个用于传递来自乘客和司机 App 事件数据的发布/订阅消息总线、为流式分析平台(如 Apache Samza、Apache Flink)提供支持、将数据库变更日志流到下游订阅者,并将各种数据接收到 Uber 的 Hadoop 数据湖中。



图 1:Uber 的 Kafka 生态系统

 

为了能够基于 Kafka 构建一个可伸缩、可靠、高性能、易于使用的消息传递平台,我们克服了许多挑战。在这篇文章中,我们将着重介绍在进行灾难恢复(因集群宕机导致)时所面临的一个挑战,并分享我们如何构建一个多区域的 Kafka 基础设施。

Uber 的 Kafka 多区域部署

 

提供业务弹性和连续性是 Uber 的首要任务。我们制定了详细的灾难恢复计划,尽量减少自然和人为灾难(如停电、灾难性软件故障和网络中断)对业务的影响。我们采用多区域部署策略,将服务与备份一起部署在分布式的数据中心中。当一个区域的物理基础设施不可用时,服务仍然可以在其他区域运行。

 

我们构建了一个多区域 Kafka 架构,实现了数据冗余,为区域故障转移提供支持。Uber 技术栈中的很多服务都依赖 Kafka 来实现区域级故障转移。这些服务是 Kafka 的下游,并假定 Kafka 中的数据是可用且可靠的。

 

图 2 描绘了多区域 Kafka 架构。我们有两种集群:生产者在本地向区域集群发布消息,将来自区域集群的消息复制到聚合集群,以此来提供全局视图。为简单起见,图 2 只显示了两个区域的集群。

图 2:两个区域之间的 Kafka 复制拓扑

 

在每个区域,生产者总是在本地生产消息,以便获得更好的性能,当 Kafka 集群不可用时,生产者会转移到另一个区域,然后向该区域的区域集群生产消息。

 

这个架构中的一个关键部分是消息复制。消息从区域集群异步复制到其他区域的聚合集群。我们开发了 uReplicator(https://eng.uber.com/ureplicator)——Uber 的 Kafka 数据复制解决方案,健壮且可靠。uReplicator 扩展了 Kafka 的 MirrorMaker,专注于可靠性、零数据丢失保证和易维护性。

从多区域 Kafka 集群消费消息

从多区域集群消费消息比生产消息更为复杂。多区域 Kafka 集群支持两种类型的消费模式。

双活模式

 

一种常见的类型是双活(Active/Active)消费模式,消费者在各自区域中消费聚合集群的主题。Uber 的很多应用程序使用这种模式消费多区域 Kafka 集群里的消息,而不是直接连接到其他区域。当一个区域发生故障时,如果 Kafka 流在两个区域都可用,并且包含了相同的数据,那么消费者就会切换到另一个区域。

 

例如,图 3 显示了 Uber 的动态定价服务(即峰时定价)如何使用双活模式来构建灾备计划。价格是根据附近地区最近一系列打车数据来计算的。所有的打车事件都被发送到 Kafka 区域集群,然后聚合到聚合集群中。然后,在每个区域,一个复杂的、占用大量内存的 Flink 作业负责计算不同区域的价格。接下来,一个全活服务负责协调各个区域的更新服务,并分配一个区域作为主区域。主区域的更新服务将定价结果保存到双活数据库中,以便进行快速查询。

图 3:双活消费模式架构

 

当主区域发生灾难时,双活服务会将另一个区域作为主区域,峰时价格计算会转移到另一个区域。需要注意的是,Flink 作业的计算状态规模太大了,无法在区域之间同步复制,因此必须使用聚合集群的输入消息来计算其状态。


我们从实践中获得了一个很关键的经验,可靠的多区域基础设施服务(如 Kafka)可以极大地简化应用程序针对业务连续性计划的开发工作。应用程序可以将状态存储在基础设施层中,从而变成无状态的,将状态管理的复杂性(如跨区域的同步和复制)留给基础设施服务。

主备模式

另一种多区域消费模式是主备模式(Active/Passive):一次只允许一个消费者(通过唯一名称标识)从一个区域(即主区域)的聚合集群中消费消息。多区域 Kafka 集群跟踪主区域的消费进度(用偏移量表示),并将偏移量复制到其他区域。在主区域出现故障时,消费者可以故障转移到另一个区域并恢复消费进度。主备模式通常被支持强一致性的服务(如支付处理和审计)所使用。


在使用主备模式时,区域间消费者的偏移量同步是一个关键问题。当用户故障转移到另一个区域时,它需要重置偏移量,以便恢复消费进度。由于 Uber 的很多服务不能接受数据丢失,所以消费者无法从高水位(即最新消息)恢复消费。另外,为了避免过多的积压,消费者也不能从低水位(即最早的消息)恢复消费。此外,从区域集群聚合到聚合集群的消息可能会变得无序。由于跨区域复制延迟,消息从区域集群复制到本地聚合集群的速度比远程聚合集群要快。因此,聚合集群中的消息顺序可能会不一样。例如,在图 4a 中,消息 A1、A2、B1、B2 几乎是同时发布到区域 A 和区域 B 的区域集群中,但经过聚合后,它们在两个聚合集群中的顺序是不一样的。


图 4:a.跨区域消息复制 b.消息复制检查点

 

为了管理这些区域的偏移量映射,我们开发了一个复杂的偏移量管理服务,架构如图 5 所示。当 uReplicator 将消息从源集群复制到目标集群时,它会定期检查从源到目标的偏移量映射。例如,图 4b 显示了图 4a 消息复制的偏移量映射。表的第一行记录了区域 A 区域集群的消息 A2(在区域集群中的偏移量是 1)映射到区域 A 聚合集群的消息 A2(在聚合集群中的偏移量是 1)。同样,其余行记录了其他复制路线的检查点。


偏移量管理服务将这些检查点保存在双活数据库中,并用它们来计算给定的主备消费者的偏移量映射。同时,一个偏移量同步作业负责定期同步两个区域之间的偏移量。当一个主备消费者从一个区域转移到另一个区域时,可以获取到最新的偏移量,并用它来恢复消费。

图 5:偏移量管理服务架构


偏移量映射算法的工作原理如下:在活跃的消费者正在消费的聚合集群中找到每个区域集群的最近检查点。然后,对于每个区域检查点的源偏移量,找到它们在另一个区域聚合集群对应的检查点。最后,在另一个区域的聚合集群中取最小的那个偏移量。

 

在图 6 中,假设活跃消费者目前的进度是区域 B 的 A3 消息(偏移量为 6)。根据右边的表检查点,最近的两个检查点分别是偏移量为 3(蓝色)的 A2 和偏移量为 5(红色)的 B4,分别对应区域集群 A 中偏移量 1(蓝色)和区域集群 B 的偏移量 3(红色)。这些源偏移量映射到区域 A 聚合集群的偏移量 1(蓝色)和偏移量 7(红色)。根据算法,被动消费者(黑色)取两者中较小的偏移量,即偏移量 1。

图 6:主备消费者从一个区域失效转移到另一个区域 

结论

 

在 Uber,业务的连续性取决于高效、不间断的跨服务数据流,Kafka 在公司的灾备计划中扮演着关键角色。在这篇文章中,我们简要地强调了在 Uber 多区域 Kafka 集群的总体架构,以及当灾难发生时不同区域的故障转移策略。但是,我们还有更具挑战性的工作要做,目前要解决如何在不进行区域故障转移的情况下容忍单个集群故障的细粒度恢复策略。

 

英文原文链接:https://eng.uber.com/kafka/

2021 年 1 月 20 日 12:491315
用户头像
蔡芳芳 InfoQ高级编辑

发布了 548 篇内容, 共 258.7 次阅读, 收获喜欢 1671 次。

关注

评论

发布
暂无评论
发现更多内容

面试官再问你优先级队列,请把这篇文章丢给他

Silently9527

Java 优先级队列 二叉堆

Hadoop之YARN的内部机制

hanke

大数据 hadoop 开源 YARN 大数据技术

学无定法——知识反转效应

Justin

心理学 28天写作 游戏设计

整理 自动备份MYSQL数据库shell脚本

edd

Navicat操作MySQL简易教程

Simon

MySQL navicat

09|PPT 教程|目录页的设计和制作

青城

初识Golang之聊聊类型

Kylin

golang新手 3月日更 21天挑战 Java转go

用户行为分析模型实践(一)—— 路径分析模型

vivo互联网技术

大数据 数据分析 用户行为分析

Ubuntu 日常系列:常用软件

TroyLiu

Linux ubuntu Ubuntu20.04

有状态容器应用,从入门到实践

焱融科技

Kubernetes 云原生 焱融科技 分布式存储 容器存储

基于 SparkMLlib 智能课堂教学评价系统 - 系统实现(四)

大数据技术指南

大数据 spark 智能时代 28天写作 3月日更

混合编程:如何用python11调用C++

华为云开发者社区

c++ 编程 语言 python11 混合编程

前端开发:项目运行npm install 提示XXX packages are looking for funding run `npm fund` for details的解决方法

三掌柜

vue.js 前端 3月日更

写代码这件事

ES_her0

28天写作 3月日更

书单|互联网企业面试案头书之程序员软技能篇

博文视点Broadview

大作业

瑾瑾呀

高并发HTTP请求实践

namelij

数据营销“教父”宋星十年倾心之作,让数据真正赋能企业

博文视点Broadview

利用深度元学习对城市销量进行预测 | AAAI 2021论文解读

京东科技开发者

零售 预测

在PostgreSQL中使用ltree处理层次结构数据

PostgreSQLChina

数据库 postgresql 开源 软件 开源社区

Spring AOP 执行顺序 && Spring循环依赖(面试必问)

hepingfly

Java spring aop 循环依赖

一文搞懂PID控制算法

不脱发的程序猿

3月日更 PID 控制算法 智能控制 工业控制

分布式事务

insight

分布式事务 3月日更

javascript中的Strict模式

程序那些事

JavaScript ES6 程序那些事

干货!户外广告如何精准触达消费者

󠀛Ferry

七日更 3月日更

Elasticsearch Segments Merging 磁盘文件合并

escray

elastic 28天写作 死磕Elasticsearch 60天通过Elastic认证考试 3月日更

52条SQL语句性能优化策略,建议收藏

Java小咖秀

MySQL 性能优化 后端 MySQL性能优化

区块链打造医疗服务,提供医疗纵深平台(下)

茜茜公主

3月日更

AI开发效率低,你可以试试华为NAIE AutoML

华为云开发者社区

华为 AI 框架 AutoML NAIE平台

【LeetCode】螺旋矩阵Java题解

HQ数字卡

算法 LeetCode 28天写作 3月日更

啥子叫递归哟!!!(阶乘)

依旧廖凯

28天挑战 3月日更

打造全球最大规模Kafka集群,Uber的多区域灾备实践-InfoQ