干货满满!关于Kafka 负载均衡在 vivo 的落地实践

本文详细介绍了vivo如何使用Cruise Control解决Kafka集群负载均衡问题。通过理解Kafka的存储结构,分析了服务端负载不均衡的原因,并探讨了人工和工具进行负载均衡的方法,特别是Cruise Control的架构、功能以及针对其的改造,以适应大规模Kafka集群的运维需求。
摘要由CSDN通过智能技术生成

vivo 互联网服务器团队-You Shuo

副本迁移是Kafka最高频的操作,对于一个拥有几十万个副本的集群,通过人工去完成副本迁移是一件很困难的事情。Cruise Control作为Kafka的运维工具,它包含了Kafka 服务上下线、集群内负载均衡、副本扩缩容、副本缺失修复以及节点降级等功能。显然,Cruise Control的出现,使得我们能够更容易的运维大规模Kafka集群。
备注:本文基于 Kafka 2.1.1开展。

一、 Kafka 负载均衡

1.1 生产者负载均衡

Kafka 客户端可以使用分区器依据消息的key计算分区,如果在发送消息时未指定key,则默认分区器会基于round robin算法为每条消息分配分区;

否则会基于murmur2哈希算法计算key的哈希值,并与分区数取模的到最后的分区编号。

很显然,这并不是我们要讨论的Kafka负载均衡,因为生产者负载均衡看起来并不是那么的复杂。

1.2 消费者负载均衡

考虑到消费者上下线、topic分区数变更等情况,KafkaConsumer还需要负责与服务端交互执行分区再分配操作,以保证消费者能够更加均衡的消费topic分区,从而提升消费的性能;

Kafka目前主流的分区分配策略有2种(默认是range,可以通过
partition.assignment.strategy参数指定):

  • range: 在保证均衡的前提下,将连续的分区分配给消费者,对应的实现是RangeAssignor;
  • round-robin:在保证均衡的前提下,轮询分配,对应的实现是RoundRobinAssignor;
  • 0.11.0.0版本引入了一种新的分区分配策略StickyAssignor,其优势在于能够保证分区均衡的前提下尽量保持原有的分区分配结果,从而避免许多冗余的分区分配操作,减少分区再分配的执行时间。

无论是生产者还是消费者,Kafka 客户端内部已经帮我们做了负载均衡了,那我们还有讨论负载均衡的必要吗?答案是肯定的,因为Kafka负载不均的主要问题存在于服务端而不是客户端。

二、 Kafka 服务端为什么要做负载均衡

我们先来看一下Kafka集群的流量分布(图1)以及新上线机器后集群的流量分布(图2):

 

从图1可以看出资源组内各broker的流量分布并不是很均衡,而且由于部分topic分区集中分布在某几个broker上,当topic流量突增的时候,会出现只有部分broker流量突增。

这种情况下,我们就需要扩容topic分区或手动执行迁移动操作。

图2是我们Kafka集群的一个资源组扩容后的流量分布情况,流量无法自动的分摊到新扩容的节点上。此时,就需要我们手动的触发数据迁移,从而才能把流量引到新扩容的节点上。

2.1 Kafka 存储结构

为什么会出现上述的问题呢?这个就需要从Kafka的存储机制说起。

下图是Kafka topic的存储结构,其具体层级结构描述如下:

  1. 每个broker节点可以通过logDirs配置项指定多个log目录,我们线上机器共有12块盘,每块盘都对应一个log目录。
  2. 每个log目录下会有若干个[topic]-[x]字样的目录,该目录用于存储指定topic指定分区的数据,对应的如果该topic是3副本,那在集群的其他broker节点上会有两个和该目录同名的目录。
  3. 客户端写入kafka的数据最终会按照时间顺序成对的生成.index、.timeindex、.snapshot以及.log文件,这些文件保存在对应的topic分区目录下。
  4. 为了实现高可用目的,我们线上的topic一般都是2副本/3副本,topic分区的每个副本都分布在不同的broker节点上,有时为了降低机架故障带来的风险,topic分区的不同副本也会被要求分配在不同机架的broker节点上。

了解完Kafka存储机制之后,我们可以清晰的了解到,客户端写入Kafka的数据会按照topic分区被路由到broker的不同log目录下,只要我们不人工干预,那每次路由的结果都不会改变。因为每次路由结果都不会改变,那么问题来了

随着topic数量不断增多,每个topic的分区数量又不一致,最终就会出现topic分区在Kafka集群内分配不均的情况。

比如:topic1是10个分区、topic2是15个分区、topic3是3个分区,我们集群有6台机器。那6台broker上总会有4台broker有两个topic1的分区,有3台broke上有3个topic3分区等等。

这样的问题就会

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1/kafka是一个分布式消息缓存系统 2/kafka集群中的服务器都叫做broker 3/kafka有两类客户端,一类叫producer(消息生产者),一类叫做consumer(消息消费者),客户端和broker服务器之间采用tcp协议连接 4/kafka中不同业务系统的消息可以通过topic进行区分,而且每一个消息topic都会被分区,以分担消息读写的负载 5/每一个分区都可以有多个副本,以防止数据的丢失 6/某一个分区中的数据如果需要更新,都必须通过该分区所有副本中的leader来更新 7/消费者可以分组,比如有两个消费者组A和B,共同消费一个topic:order_info,A和B所消费的消息不会重复 比如 order_info 中有100个消息,每个消息有一个id,编号从0-99,那么,如果A组消费0-49号,B组就消费50-99号 8/消费者在具体消费某个topic中的消息时,可以指定起始偏移量 每个partition只能同一个group中的同一个consumer消费,但多个Consumer Group可同时消费同一个partition。 n个topic可以被n个Consumer Group消费,每个Consumer Group有多个Consumer消费同一个topic Topic在逻辑上可以被认为是一个queue,每条消费都必须指定它的Topic,可以简单理解为必须指明把这条消息放进哪个queue里。为了使得Kafka的吞吐率可以线性提高,物理上把Topic分成一个或多个Partition,每个Partition在物理上对应一个文件夹,该文件夹下存储这个Partition的所有消息和索引文件。若创建topic1和topic2两个topic,且分别有13个和19个分区 Kafka的设计理念之一就是同时提供离线处理和实时处理。根据这一特性,可以使用Storm这种实时流处理系统对消息进行实时在线处理,同时使用Hadoop这种批处理系统进行离线处理,还可以同时将数据实时备份到另一个数据中心,只需要保证这三个操作所使用的Consumer属于不同的Consumer Group即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值