在2020年和2021年,Coinbase的数据团队在AWS MSK、开源的Kafka Connect和Airflow ETL的基础上塑造了一个通用的Kafka基础设施,以增强工程师对事件流、数据分析和pub-sub用例的能力。
随着Kafka应用的加速,我们发现用户在我们的解决方案中仍然遇到了一系列的技术问题和限制。为了解决这些问题和未来的需求,我们的团队在2021年底进行了技术升级和扩展。最有效的工作有以下几点。
- 建立一个全功能的Kafka控制平面,以实现多集群
- 硬化我们自制的Kafka数据平面 - 流媒体SDK
- 改善Kafka的上机体验
- 拥抱Kafka Rest Proxy和schema Registry
- 在Databricks中开发流处理解决方案
MSK 多集群联合
与许多多租户系统一样,Kafka 也存在嘈杂的邻居问题。例如,由于页面缓存污染,滞后的消费者可能会影响其他对延迟要求苛刻的客户端。此外,Kafka 集群不会无限扩展,在某些时候,用户将不得不将一些主题卸载到新集群.
尽管 MSK(Amazon Managed Streaming for Apache Kafka)对网络分裂(单个可用区中断)具有一定程度的容忍度,但跨区域故障转移理论上可以将 Kafka 集群的可用性从99.9%提高到 99.9999%。
这些事实促使我们寻找弹性多集群拓扑。凭借对 AWS MSK 的累积知识,我们成功克服了跨 VPC Kafka 连接的网络挑战。2022 年,在指定的流式 AWS 账户中启动了一些新的 MSK 集群。
今天,除了名为
每个类别都有一些不同的特征——例如,CDC 事件是强排序的,而其他事件类型和发布/订阅消息通常是弱排序的。发布/订阅消息具有更严格的延迟和可用性要求。
功能齐全的 Kafka 控制平面
我们开发了一个 Kafka 控制平面用于以下目的
- 向指定的 MSK 集群提供主题
- 管理 MSK 集群上的主题 ACL
- 向 Kafka 客户端和 SSO 用户验证和授权主题访问
- 在 gRPC 和 REST 端点中公开主题和集群元数据
Kafka 数据平面 - Streaming SDK
Coinbase 的服务使用 Streaming SDK 作为数据平面与不同的消息系统交互,即 Kafka、Kinesis、SQS 和 SNS。对于 Kafka 通信,SDK 会定期到达 Kafka 控制平面以刷新主题和集群元数据,如前所述。服务所有者免于 Kafka 客户端配置的麻烦。SDK 配备断路器,能够根据负载均衡算法重定向消息 { na | 故障转移 | 轮询 | 复制 } 在区域 MSK 中断的情况下。它本质上是 Kafka 集群联邦的一种轻型形式,有利于具有高可用性和低延迟要求的关键任务服务之间的异步通信。
稍微深入一点,典型的发布/订阅主题是弱排序的,消息生产者可以在提供主题的 MSK 集群之间自由切换,只要消费者端订阅所有这些集群。多个 Spark 流同时写入Databricks 中的同一个 Delta 表没有问题,这使得我们的动态路由方案可以端到端地用于数据流管道。
Streaming SDK 为 Kafka 生产者提供了固定和预先调整的设置,进一步简化了入职体验。内置的 Protobuf 序列化程序会自动在Confluent Schema Registry上注册 Protobuf 模式以进行模式验证和实施。在可观察性方面,SDK 会自动发出包括延迟、成功/失败率、消息大小和其他健康指标的指标,以便于监控和警报。
丰富的安全模型
Kafka 主题ACL被编码为 YAML 文件并由 Kafka 控制平面管理。
控制平面负责在所有 MSK 集群中传播读写 ACL 策略。而 user-read 由Kafdrop和AKHQ获取,以确定 SSO 用户是否对该主题的消息具有读取权限。
让卡夫卡体验愉快
Kafdrop是一个方便的 UI 工具,用于显示集群和主题配置、消费者组和滞后以及不同主题的消息。当与 Confluent Schema Registry 集成时,Kafdrop 以 JSON 格式显示protobuf消息,而无需导入 protoc 生成的库。
AKHQ于 2022 年初引入 Coinbase 以支持多 MSK 集群,我们对其管理能力和集成功能印象深刻。在 Github 中分叉 AKHQ 允许我们通过连接我们的 Kafka 控制平面来自定义其安全性,这决定了用户的访问级别。AKHQ 日复一日地执行以下操作:
- 根据用户的要求清空主题
- 删除架构注册表中的 protobuf 架构,以在引入中断架构更改时取消阻止消息发布
- 根据用户请求删除消费者组
- 为消费者组重置提交的偏移量
- 更新不受控制平面监督的主题动态配置
Confluent REST 代理和架构注册表
对于使用缺乏生产级 Kafka 客户端库的编程语言开发的服务,Confluent REST Proxy是推荐的交互方式。
为了鼓励使用结构化数据,并作为Kafka Connect的要求,我们发布了用于轻松注册 protobuf 模式的工具。非向后兼容的模式更改将阻止生产者端的消息发布,以防止工程师破坏下游数据管道。
Kafka 流媒体管道
Coinbase 开发了一个本土流式摄取和数据库复制框架 SOON(Spark cOntinuOus iNgestion),用于将来自各种数据源的 Kafka 消息摄取到 Delta Lake。为了解决旧的基于 Airflow 的 Kafka 到 Snowflake ETL 管道中的可扩展性和延迟挑战,SOON 通过Spark 结构化流提供近乎实时的摄取性能,并支持以下用例的快速上线:
- Append-only场景(只支持insert)
- Merge CDC(Change Data Capture)场景(支持插入、更新和删除)
- 合并非CDC场景(支持insert和update)
- Append-only 和 Merge 非 CDC 场景的数据回填
Kafka 事件和缓解措施
为了正确路由或接收关于特定主题的消息,Kafka 客户端必须了解代理拓扑以找出托管各个分区的代理。客户端必须通过元数据 API 调用以可配置的节奏刷新信息。当代理的请求队列被元数据请求饱和时,生产请求将被阻塞,从而影响 Kafka 生产者的吞吐量。此外,高 TLS 连接率通常会导致代理 CPU 使用率升高和 Kafka 性能下降。这些问题是由客户端服务行为不当引起的,例如,我们发现 AWS Lambda 不断为处理的每个请求建立新的 Kafka 连接。
Kafka broker 可以承受的 TLS 连接数是有限制的。以下是另一家云提供商推荐的最大 TLS 连接数:
这些数字与我们对 MSK 的观察结果非常吻合——一个类型为 kafka.m5.12xlarge 的代理节点可以处理大约 30000 个 TLS 连接。找到正确的 Kafka 消息密钥帮助我们减少了代理连接数。例如,所有 Coinbase 服务发出的可观察性指标都被摄取到指定 Kafka 集群内 512 个分区的同一主题中。如果没有指定消息密钥,每个Telegraf sidecar 将连接到所有代理以进行循环,从而导致可怕的 TLS 连接计数和过度配置的 MSK 集群。选择 EC2 实例 ID 作为消息密钥有效地将代理连接减少到每个 EC2 实例一个。