跨AZ部署最佳实践之Kafka
Posted 智能运维
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了跨AZ部署最佳实践之Kafka相关的知识,希望对你有一定的参考价值。
跨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:
Broker ID |
broker.rack |
备注 |
---|---|---|
0 |
az1 | 可用区A |
1 |
az1 |
可用区A |
2 |
az2 |
可用区B |
3 | az2 |
可用区B |
4 |
az3 |
可用区C |
5 |
az3 | 可用区C |
验证如下三个场景下的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包含一套副本。
评估两套方案的优劣:
项目 | 双机房4副本方案 |
三机房3副本方案 |
---|---|---|
冗余度 |
单机房故障无损 |
双机房故障无损 |
存储成本 | 4副本 |
3副本 |
网络延迟 |
跨机房 |
跨机房 |
从上文来看,方案二提高了冗余度,并且降低了存储成本,生产环境中建议使用方案二的多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的值保持一致。
往期推荐
以上是关于跨AZ部署最佳实践之Kafka的主要内容,如果未能解决你的问题,请参考以下文章
AWS 最佳实践:我应该在每个 AZ 中都有一个 NAT 网关吗?
Flink 最佳实践之 通过 TiCDC 将 TiDB 数据流入 Flink
在 kubernetes 上以分布式模式部署 kafka 连接器的最佳实践