这张图片是作者自己创作的。
简介两周前我在我的通讯中发布了这篇文章。免费订阅我的通讯 https://vutr.substack.com,这样您就能更早地在我的通讯中收到我的文章。
本周,我们将回到我的系列节目“大型科技公司如何管理数据”,来看看美国最大的食品配送平台之一DoorDash如何利用Apache Kafka和Flink进行实时处理。
这篇简短的笔记是我读了DoorDash的这篇文章《使用Kafka和Flink构建实时可扩展事件处理》后的感想和笔记。
让我们来看看概要吧在DoorDash平台,实时数据流非常重要。
然而,构建一个能够处理数十亿个事件的系统不容易。
来自DoorDash服务或用户设备中的数据必须在实时进行处理后路由到不同的接收点:
- 大多数事件需要被导入到Snowflake数据仓库中。
- 某些事件将被送入ML平台。
- 基于某些移动事件进行监控和报警。
我们来看看DoorDash平台的原有的实时处理系统。
遗留系统最初,公司有不同的数据流从 web 应用程序中提取数据并将其导入到 Snowflake 中。每个数据流都是为适应于特定类型的事件或场景而构建的。例如一个管道如下所示:
作者自制的图片。
这种方法有一些问题:
- 为相同目的构建多个管道(例如,将数据导入Snowflake;这些管道只是在处理不同的事件类型时有所不同)是低效的。
- 操作上的问题。
DoorDash 决定要搭建一个新的系统。
新的系统
DoorDash实时事件处理系统的下一代需要满足以下要求:
- 来自多个不同来源的数据支持。
- 可靠的低延迟Snowflake数据摄入。
- 新平台必须让不同团队和服务轻松访问数据流。
- 支持模式评估和强制执行。
- 具有可扩展和容错的特性。
为了实现这些目标,DoorDash 已将其战略从依赖 AWS 和第三方服务转向使用开源解决方案:它选择了 Kafka 和 Flink 作为构建新系统的支柱。
以下是我们新实时处理系统的整体设计:
作者原创的这张图片。
接下来,让我们深入了解这个系统的细节。
事件生成DoorDash选择了Apache Kafka作为其流数据处理的消息队列系统。
在 Kafka 中生成数据的一种常见方式是创建客户端,连接到一组引导服务器,并获取主题领导者信息。只有完成这些步骤后,客户端才能开始向服务器发送消息。
然而,在DoorDash这种规模下部署和运行Kafka,上述流程可能在这样的规模下会遇到一些挑战。
- 每个向Kafka生产消息的服务都必须按照上述方式设置流,从而增加了更多的开销。
- 统一Kafka生产者的配置较为困难。
- 移动和Web应用程序无法直接连接到Kafka。
DoorDash 利用 Confluent Kafka Rest Proxy (https://github.com/confluentinc/kafka-rest)。
来自官方Github:Kafka REST代理服务为Kafka集群提供了一个RESTful接口。它使得生成和消费数据,让查看集群状态和执行管理操作变得简单,而无需使用原生的Kafka协议和客户端。
这个代理允许DoorDash集中和优化Kafka消息的生产。它大大简化了事件发布的流程。DoorDash利用内部CI/CD流程在Kubernetes集群中构建并部署这个代理。
REST代理服务器还自带了一些开箱即用的功能
- 支持不同类型的负载。
- 支持在发送到 Kafka 代理之前批量事件
- 与模式注册中心实现内置集成。
为了更好地满足DoorDash的需求,他们做了一些调整:
- 允许代理向多个集群生成消息。
- 能够异步地将数据发送到代理服务器,无需等待确认信息。此功能有助于显著缩短响应时间。
- 预取Kafka主题元数据。
- 生成测试数据。
除了使用REST代理之外,DoorDash还做了一些调整,以提高吞吐量:
- Kafka 会将主题的分区在代理之间进行复制,以确保数据的持久性。通常,一个分区会被复制三次:一个领导者节点和两个跟随者节点。DoorDash 将复制因子从 3 减少到 2。这是因为 DoorDash 更加重视高吞吐量和高可用性,而非数据一致性。这还能帮助 DoorDash 节省磁盘空间和减少用于数据复制的 CPU 资源。
- 他们将 确认配置 设置为 1,这意味着生产者只要领导者节点接收到消息就会立即收到确认。这有助于缩短响应时间,因为它不需要等待数据被复制到从节点。
- DoorDash 还使用了 Kafka 的粘性分区器,该分区器旨在将生成的消息绑定到一批记录的特定分区。该分区器会尽量将记录发送到同一个分区,直到满足一定条件,如批次达到其大小限制。
通过以上所做的所有调优,Kafka 代理的 CPU 使用率减少了 30 到 40%。
事件管理DoorDash 选择了 Apache Flink 来进行实时数据处理,这是因为 Apache Flink 拥有原生支持基于事件时间的处理方式、容错机制以及与众多数据源和接收器的丰富集成能力。
DoorDash 利用 Flink 流计算 API 和 Flink SQL 来构建实时处理应用程序。
他们为内部团队成员提供了一个包含所有必要配置的基础 Flink Docker 镜像。
为了实现应用间的隔离,他们把每个Flink应用,作为单独的Kubernetes pod部署为。
这是一张作者制作的图片。
在使用 Flink 数据流 API 的过程中,内部用户需要遵循以下步骤:
这张图是由作者绘制的。
- 克隆 Flink 应用模板。
- 根据需要的逻辑调整模板。
- 使用 terraform 模板定义应用程序和 Flink 作业配置,例如设定并行度。
- 部署过程使用 terraform 模板和应用的 Docker 镜像,通过生成的 Helm Chart 在 K8s 集群中部署 Flink 应用。
对于这些数据用户来说,数据流 API 可能不太熟悉。DoorDash 让他们可以用 SQL 来编写 Flink 应用。
- 用户在 YAML 中定义处理逻辑,包括 SQL 逻辑、数据源和接收端等
- 用户然后提交包含 YAML 文件的拉取请求。
- CD 构建流水线将 YAML 编译为 Flink 应用程序并将其部署。
在构建新平台的过程中,DoorDash 第一步定义了一种统一的消息的生产和处理格式,并为事件的生产者和消费者开发了与此格式配合使用的序列化和反序列化的库。
所有通过系统的事件都遵循一个标准格式,包括包裹和内容。
其中包含事件的上下文(例如,创建时间)、元数据(例如,编码方法)以及模式的指针。封装被存储为 Kafka 记录头。
后者包含了事件的实际内容信息,并作为Kafka记录中的值存储。负载将经过模式验证并进行编码。
生产者会丢弃无效的负载,避免发送给 broker。
来自网页或移动设备的事件是以原始的JSON格式生成的,DoorDash 使用专门的Flink应用程序来验证并转换成符合模式验证的格式。
数据仓库整合集成如下所示:
由作者制作的这张图片。
- Flink 应用程序将从 Kafka 消费数据并将其以 Parquet 格式上传到 S3。将数据落地到 S3 具有以下几个好处:数据保留时间更长(比 Kafka 更长),减少数据摄取管道对 Snowflake 的依赖,在发生故障时可以回填数据,并且允许其他分析服务(例如 DoorDash 内部的 Trino 服务)访问这些数据。
- 利用 Snowpipe(Snowflake 提供的一个功能)将数据从 S3 复制到 Snowflake。根据 Amazon SQS 的通知,Snowpipe 将会在数据可用时立即加载数据到 Snowflake,使用 COPY 语句。
为了实现隔离的目的,每种事件都使用专用的Flink作业——Snowpie pipeline。
最后结束谢谢你读到这么远。
我们一窥了DoorDash的实时处理系统,其核心是Kafka和Flink。
如果你对 Kafka 感兴趣,我专门写了一系列关于 Kafka 的文章,你可以在这里查看。
说到 Flink,我一直想了解它。如果你有兴趣,请留言告诉我,我就可以把它提前安排一下。
参考文献王艾伦,使用Kafka和Flink构建可扩展的实时事件处理系统(2022)_
共同学习,写下你的评论
评论加载中...
作者其他优质文章