Kafka可以将主题划分为多个分区(Partition
),会根据分区规则选择把消息存储到哪个分区中,只要如果分区规则设置的合理,那么所有的消息将会被均匀的分布到不同的分区中,这样就实现了负载均衡和水平扩展。另外,多个订阅者可以从一个或者多个分区中同时消费数据,以支撑海量数据处理能力。
顺便说一句,由于消息是以追加到分区中的,多个分区顺序写磁盘的总效率要比随机写内存还要高(引用Apache Kafka – A High Throughput Distributed Messaging System
的观点),是Kafka高吞吐率的重要保证之一。
一、副本机制
由于Producer
和Consumer
都只会与Leader角色的分区副本相连,所以kafka需要以集群的组织形式提供主题下的消息高可用。kafka支持主备复制,所以消息具备高可用和持久性。
一个分区可以有多个副本,这些副本保存在不同的broker上。每个分区的副本中都会有一个作为Leader。当一个broker失败时,Leader在这台broker上的分区都会变得不可用,kafka会自动移除Leader,再其他副本中选一个作为新的Leader。
在通常情况下,增加分区可以提供kafka集群的吞吐量。然而,也应该意识到集群的总分区数或是单台服务器上的分区数过多,会增加不可用及延迟的风险。
itcast@Server-node:/mnt/d/kafka_2.12-2.2.1$ bin/kafka-topics.sh --describe --
zookeeper localhost:2181 --topic heima
// hema这个主题有三个分区,一个副本同处在一个节点当中
Topic:heima PartitionCount:3 ReplicationFactor:1 Configs:
Topic: heima Partition: 0 Leader: 0 Replicas: 0 Isr: 0
Topic: heima Partition: 1 Leader: 0 Replicas: 0 Isr: 0
Topic: heima Partition: 2 Leader: 0 Replicas: 0 Isr: 0
二、分区Leader选举
可以预见的是,如果某个分区的Leader挂了,那么其它跟随者将会进行选举产生一个新的leader,之后所有的读写就会转移到这个新的Leader上,在kafka中,其不是采用常见的多数选举的方式进行副本的Leader选举,而是会在Zookeeper
上针对每个Topic
维护一个称为 ISR(in-sync replica,已同步的副本) 的集合,显然还有一些副本没有来得及同步。只有这个ISR列表里面的才有资格成为leader( 先使用ISR里面的第一个,如果不行依次类推,因为ISR里面的是同步副本,消息是最完整且各个节点都是一样的 )。 通过ISR,kafka需要的冗余度较低,可以容忍的失败数比较高。假设某个topic有f+1个副本,kafka可以容忍f个不可用,当然,如果全部ISR里面的副本都不可用,也可以选择其他可用的副本,只是存在数据的不一致。
三、分区重新分配
我们往已经部署好的Kafka集群里面添加机器是最正常不过的需求,而且添加起来非常地方便,我们需要做的事是从已经部署好的Kafka节点中复制相应的配置文件,然后把里面的broker id
修改成全局唯一的,最后启动这个节点即可将它加入到现有Kafka集群中。
但是问题来了,新添加的Kafka节点并不会自动地分配数据,所以无法分担集群的负载,除非我们新建一个topic。但是现在我们想手动将部分分区移到新添加的Kafka节点上,Kafka内部提供了相关的工具来重新分布某个topic的分区。
具体步骤
- 第一步:我们创建一个有三个节点的集群,详情可查看第九章集群的搭建
itcast@Server-node:/mnt/d/kafka-cluster/kafka-1$ bin/kafka-topics.sh --create --
zookeeper localhost:2181 --topic heima-par --partitions 3 --replication-factor 3
Created topic heima-par.
详情查看
itcast@Server-node:/mnt/d/kafka-cluster/kafka-1$ bin/kafka-topics.sh --describe
--zookeeper localhost:2181 --topic heima
-par
Topic:heima-par PartitionCount:3 ReplicationFactor:3 Configs:
Topic: heima-par Partition: 0 Leader: 2 Replicas: 2,1,0 Isr: 2,1,0
Topic: heima-par Partition: 1 Leader: 0 Replicas: 0,2,1 Isr: 0
Topic: heima-par Partition: 2 Leader: 1 Replicas: 1,0,2 Isr: 1,0,2
itcast@Server-node:/mnt/d/kafka-cluster/kafka-1$
从上面的输出可以看出heima-par这个主题一共有三个分区,有三个副本
- 第二步:主题heima-par再添加一个分区
itcast@Server-node:/mnt/d/kafka-cluster/kafka-1$ bin/kafka-topics.sh --alter -- zookeeper localhost:2181 --topic heima-pa
r --partitions 4
WARNING: If partitions are increased for a topic that has a key, the partition
logic or ordering of the messages will be affected
Adding partitions succeeded!
查看详情已经变成4个分区
itcast@Server-node:/mnt/d/kafka-cluster/kafka-1$ bin/kafka-topics.sh --describe
--zookeeper localhost:2181 --topic heima
-par
Topic:heima-par PartitionCount:4 ReplicationFactor:3 Configs:
Topic: heima-par Partition: 0 Leader: 2 Replicas: 2