写点什么

跨 AZ 部署最佳实践之 Kafka

作者:焦振清
  • 2023-06-23
    北京
  • 本文字数:1982 字

    阅读完需:约 7 分钟

跨 AZ 部署是实现服务高可用较为有效的方法,同时也极具性价比。如果实现了跨 AZ 部署,不仅可以消除服务中的单点,同时还可以逐步建设如下能力:服务隔离,灰度发布,N+1 冗余,可谓一举多得。承接 ES 和 Zookeeper 跨 AZ 部署实践,本文继续介绍 Kafka 如何实现跨 AZ 部署。


实现方式

<broker.rack>是服务端 Broker 配置文件中的一个参数,类似于 ES 中的 Rack。通过 Tag 的方式,对集群中的 Broker 进行“分组”,在分配分区副本时实现跨 Rack 容错。此参数接受一个<string>类型的值,默认为<null>;此外<broker.rack>不支持动态更新,是只读的,更新 Broker 的<broker.rack> 需要重启 Broker。并且:

  • 已经跨 AZ 部署的集群,扩容不需要重启集群中正常运行的 Broker;

  • 集群若要增加此配置实现跨 AZ 部署,需要对集群所有 Broker 进行重启。

具体配置示例如下:

broker.rack=my-rack-id
复制代码


但要注意的是,当集群中存在<broker.rack>参数为<null>的节点时,哪怕只有一台机器,默认参数下创建 Topic 会失败,通过参数<--disable-rack-aware>可以忽略<broker.rack>参数进行分区分配。

当创建 Topic 时会受到<broker.rack>参数的约束,以确保分区副本能够尽可能多的跨 Rack,即 Kafka 根据<replication-factor>的值来进行分区分配,并且是“尽力而为”覆盖到所有的 broker.rack。

还有值得注意的是:Kafka 不像 ES,它不具备副本自动恢复的能力。

在一个 AZ 内部,实现 Broker 的高可用部署其实有较为简单的方式,如公有云的高可用组即可。

场景验证

我们通过一些场景验证跨 AZ 部署时 Kafka 分区分配的机制。创建一个有 3 个 AZ 的集群,每个 AZ 有 2 个 Broker:

验证如下三个场景下的 Topic 的分区分配情况:


  • 当副本数小于 AZ 数量时:

./kafka-topics.sh --create  --zookeeper $ZK_ADDR --replication-factor 2 --partitions 1 --topic test1                
复制代码

 可用区 A 用红色框,可用区 B 用黄色框,可用区 C 用蓝色框表示。



  • 当副本数等于 AZ 数量时:

./kafka-topics.sh --create  --zookeeper $ZK_ADDR --replication-factor 3 --partitions 1 --topic test2
复制代码



  • 当副本数大于 AZ 数量时:

./kafka-topics.sh --create  --zookeeper $ZK_ADDR --replication-factor 4 --partitions 1 --topic test3
复制代码



  • 特别的,当集群中有 2 个 AZ,采用 4 副本,副本会均匀分布在 2 个 AZ,即每个 AZ 有 2 套分区,则可以在 AZ 内部以及跨 AZ 同时具备容灾能力,对于较重要的数据是必要的(图中:0/1 为 AZ1,2/3 为 AZ2)。



最佳实践

当集群出现故障的 Broker 时,Kafka 不具备基于分区的自动迁移和恢复的能力,这点和 ES 是不同的。因此,当跨 AZ 部署的集群一旦出现机房故障,若 Topic 是两副本,Topic 各分区不再有冗余,存在较大风险。所以至少 3 副本对于 Topic 是非常重要的,下图是跨 AZ 部署架构设计的两种方案(ZK 部署参考文章:跨 AZ 部署最佳实践之 Zookeeper)。

  • 方案一是双机房 4 副本部署架构,每个 AZ 包含两套副本;

  • 方案二是三机房 3 副本部署架构,每个 AZ 包含一套副本。



评估两套方案的优劣:

从上文来看,方案二提高了冗余度,并且降低了存储成本,生产环境中建议使用方案二的多 AZ 部署架构。

成本与网络延时

首先是成本问题,Kafka 作为消息队列,承担的是消息临时存储和分发的角色,Messages 的存储周期较短,设置为天级别即可(线上当前设置为 3 天,方便下游服务故障恢复后从 Kafka 中拉去故障期间的数据)。因此 Kafka 在成本方面,因为存储时间较短,因此 3 副本并不会带来太大的成本。

第二个问题就是网路延迟,通过压测,同 AZ 和跨 AZ 的网络延时分别为 0.42ms 和 0.51ms。

具体压测方法,在可用区 A 和可用区 B 创建一套集群:

  • 基准集群:在华北可用区 A 部署的 2 台机器组成的集群;

  • 跨 AZ 集群:在华北可用区 A 和可用区 B 部署的 2 台机器组成的集群。

两个 AZ 直接的 ping 延迟和 AZ 内部的 ping 延迟均值分别为:0.070ms 和 1.171ms。

生产者以异步<acks=1>的方式向 Kafka 集群发送消息,采用 Kafka 自带的压测工具<kafka-producer-perf-test.sh>两个集群进行压测。

在上述两个集群各创建一个 Topic<--replication-factor 2 --partitions 1>,Leader 位于可用区 A 上。

压测机位于华北可用区 A,每条消息的大小为 300 字节(为了体现网络的问题,弱化自身处理每条消息的能力),每秒发送 10000 条数据。

压测结果两者分别是<0.42 ms avg latency>和<0.51 ms avg latency>,两个集群的平均延迟几乎没有差别。

压测参数:

./kafka-producer-perf-test.sh  --topic pressure \ --num-records 500000 \ --record-size 300 \ --throughput 10000 \ --producer-props bootstrap.servers=10.10.101.22:9092
复制代码

基准集群压测结果:



跨 AZ 集群压测结果:



Kafka 跨 AZ 架构使用上的优化点:

  • 写入。可以将 Topic 的 Leader 全部集中在一个 AZ 中,生产者采用异步的方式写入时,跨 AZ 延迟对集群的吞吐量影响不大。

  • 消费,消费者组的延迟可以通过如下参数,消除跨 AZ 消费时的延迟影响:

client.rack    #此参数接受一个string类型的值, 并与broker.rack的值保持一致。
复制代码


发布于: 2023-06-23阅读数: 16
用户头像

焦振清

关注

让运维因我们而不同! 2018-12-04 加入

架构师

评论

发布
暂无评论
跨AZ部署最佳实践之Kafka_焦振清_InfoQ写作社区