Grab 利用 Apache Kafka 2.3 功能降低 AWS 成本
Grab 通过利用 Apache Kafka 2.3 引入的消费者能够连接到同一可用区(AZ)的代理节点功能,成功将 AWS 上的流量成本降低至零。这一变更显著减少了在 AWS 上运行 Apache Kafka 的整体基础设施成本。
初始配置与问题
Grab 构建了一个围绕 Apache Kafka 的流数据平台,支持公司所有产品。遵循 Kafka 最佳实践,他们最初的配置为每个 Kafka 分区使用了三个副本,分布在 AWS 区域内的三个不同可用区。团队观察到,跨 AZ 流量占 Kafka 平台成本的一半,因为 AWS 对跨 AZ 数据传输收费。
Fabrice Harbulot 和 Quang Minh Tran 指出,初始设计的问题在于它产生了巨大的跨 AZ 网络流量。这是因为 Kafka 客户端默认仅与分区领导者通信,而领导者有 67% 的概率位于不同的 AZ。跨 AZ 流量包括新发布的消息、代理之间的数据复制以及消费者获取的消息。
解决方案
自 Apache Kafka 2.3 起,可以配置消费者从分区副本获取数据。这样,如果消费者仅从同一 AZ 的代理获取消息,则可以避免数据传输成本。此功能要求 Kafka 代理和消费者都知晓它们所在的 AZ。对于 Kafka 代理,团队配置了 broker.rack 参数,值为 AZ ID(如 az1、az2、az3 等),而不是 AZ 名称(如 1a、1b、1c 等),因为后者在 AWS 账户之间不一致。他们还设置了 replica.selector.class 参数,值为 org.apache.kafka.common.replica.RackAwareReplicaSelector。
在消费者端,团队更新了内部 Kafka SDK,以根据 EC2 主机元数据配置 client.rack 参数,使应用团队能够通过导出环境变量启用此功能。
实施效果与注意事项
在向部分服务推出新设置后,团队观察到跨 AZ 流量成本下降,并发现了一些值得注意的副作用。首先,端到端延迟增加了最多 500 毫秒,这是可以预期的,因为大多数消费者从副本获取消息,因此复制时间导致了额外的延迟。对于对延迟敏感的数据流,理想情况下应始终从分区领导者获取消息,即使涉及额外成本。
其次,在代理维护期间,直接从副本获取消息的消费者可能会遇到代理不可用的情况,因此应等待/重试,直到同一 AZ 的代理重新上线。最后,团队观察到跨 AZ 消费者数量导致的代理负载不均衡,这意味着消费者的均匀分布对于确保代理负载均衡至关重要。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。