分布式 - 消息队列Kafka:Kafka分区常见问题总结

文章目录

      • 01. Kafka 的分区是什么?
      • 02. Kafka 为什么需要分区?
      • 03. Kafka 分区有什么作用?
      • 03. Kafka 为什么使用分区的概念而不是直接使用多个主题呢?
      • 04. Kafka 分区的数量有什么限制?
      • 05. Kafka 分区的副本有什么作用?
      • 06. Kafka 分区的消息是如何分配到不同的分区中的?
      • 07. Kafka 分区可以增加或者减少吗?
      • 08. Kafka 的分区数大于服务器台数时如何分配存储副本?
      • 09. Kafka 创建Topic时如何将分区设置到不同的broker中?
      • 10. Kafka 为什么需要手动调整分区的副本分配?
      • 11. Kafka 如何手动的调整分区的副本分配?
      • 12. kafka 如何手动增加分区的副本数量?
      • 13. Kafka 为什么需要手动增加分区的副本数量?
      • 14. Kafka 分区负载均衡如何实现?
      • 15. Kafka Leader分区负载平衡如何实现?
      • 16. Kafka 集群如何选择合适的Topic/Partition数量?
      • 17. Kafka 分区数量是否越多越好呢?
      • 18. Kafka 如何确定分区数量?
      • 19. Kafka 如何保证顺序的消费主题中的消息?
      • 20. Kafka 如何保证顺序的消费分区中的消息?
      • 21. Kafka 自动分区分配机制是什么?
      • 22. Kafka 自动分区分配机制如何开启?

01. Kafka 的分区是什么?

Kafka是一种分布式流处理平台,它将数据分成多个主题(topics),每个主题可以分成多个分区(partitions)。分区是Kafka中最基本的概念之一,它是一种逻辑上的概念,用于将主题中的数据分散存储在不同的节点上,以实现数据的并行处理和高可用性。每个分区都是一个有序的、不可变的消息序列,其中的消息按照写入的顺序进行排序,并且每个消息都有一个唯一的偏移量 offset 来标识它在分区中的位置。消费者可以通过指定偏移量来读取分区中的消息,从而实现对数据的随机访问和重放。

分区的数量是在创建主题时指定的,一般情况下,每个主题都会有多个分区,以便实现数据的并行处理和负载均衡。分区的数量应该根据数据量和处理能力来确定,通常建议每个分区的大小不要超过1GB。

02. Kafka 为什么需要分区?

我们在使用 Apache Kafka 生产和消费消息的时候,肯定是希望能够将数据均匀地分配到所有服务器上。比如很多公司使用 Kafka 收集应用服务器的日志数据,这种数据都是很多的,特别是对于那种大批量机器组成的集群环境,每分钟产生的日志量都能以 GB 数,因此如何将这么大的数据量均匀地分配到 Kafka 的各个 Broker 上,就成为一个非常重要的问题。

分布式 - 消息队列Kafka:Kafka分区常见问题总结_第1张图片

Kafka 之所以要分区,是为了实现数据的分布和负载均衡。

在 Kafka 中,一个 Topic 可以被分成多个 Partition,每个 Partition 可以被存储在不同的 Broker 上。当你向一个 Topic 发送消息时,Kafka 会根据消息的 Key 计算出该消息应该被存储在哪个 Partition 上。如果该 Partition 存在多个副本,Kafka 会将消息复制到所有副本中。

通过将一个 Topic 分成多个 Partition,Kafka 可以将数据分布到多个 Broker 上,从而实现数据的分布和负载均衡。如果一个 Topic 只有一个 Partition,那么所有的消息都会被存储在同一个 Broker 上,这会导致该 Broker 的负载过高,而其他 Broker 的资源却没有得到充分利用。

另外,通过将一个 Topic 分成多个 Partition,Kafka 还可以实现消息的并发处理。每个 Partition 都可以被多个消费者组中的消费者并发地消费,从而提高消息的处理速度。

需要注意的是,Partition 的数量和副本数需要根据实际情况进行设置。如果 Partition 的数量过少,会导致数据无法充分分布到多个 Broker 上,从而影响负载均衡和并发处理的效果。如果 Partition 的数量过多,会导致 Kafka 集群的管理和维护变得复杂,从而影响系统的可靠性和稳定性。

03. Kafka 分区有什么作用?

Kafka 分区的作用主要有以下几个方面:

① 提高并发性能:多个消费者可以同时消费同一个主题的不同分区,从而提高消费的并发性能。
② 实现负载均衡:将一个主题分成多个分区后,可以将不同的分区分配到不同的 Kafka 节点上,从而实现负载均衡。
③ 提高可靠性:将一个主题分成多个分区后,即使某个分区出现故障,其他分区仍然可以正常工作,从而提高可靠性。

03. Kafka 为什么使用分区的概念而不是直接使用多个主题呢?

Kafka 有主题(Topic)的概念,它是承载真实数据的逻辑容器,而在主题之下还分为若干个分区,也就是说Kafka 的消息组织方式实际上是三级结构:主题 - 分区 - 消息。主题下的每条消息只会保存在某一个分区中,而不会在多个分区中被保存多份,如下所示:

分区的作用就是提供负载均衡的能力,或者说对数据进行分区的主要原因,就是为了实现系统的高伸缩性。不同的分区能够被放置到不同节点的机器上,而数据的读写操作也都是针对分区这个粒度而进行的,这样每个节点的机器都能独立地执行各自分区的读写请求处理。并且,我们还可以通过添加新的节点机器来增加整体系统的吞吐量。

除了提供负载均衡这种最核心的功能之外,利用分区也可以实现其他一些业务级别的需求,比如实现业务级别的消息顺序的问题。

① 使用分区可以将一个主题分成多个部分,每个部分可以在不同的服务器上进行存储和处理。这样可以更好地利用集群中的资源,提高处理能力和吞吐量。而如果直接使用多个主题,每个主题都需要独立地进行管理和维护,会增加系统的复杂度和管理成本。

② 使用分区可以提供更好的消息顺序保证。在一个分区内,消息的顺序是有序的,而在不同分区之间,消息的顺序是不确定的。这样可以更好地保证消息的顺序性,避免消息乱序的情况发生。

③ 使用分区可以提供更好的容错性。如果一个分区出现故障,只会影响该分区内的消息,而不会影响整个主题。这样可以更好地保证系统的可用性和稳定性。

因此,Kafka 使用分区的概念而不是直接使用多个主题,是为了提供更好的可扩展性、性能、消息顺序保证和容错性。

04. Kafka 分区的数量有什么限制?

Kafka 分区的数量没有明确的限制,但是分区数量过多会影响 Kafka 的性能。一般来说,建议将分区数量控制在几百到几千个之间。

05. Kafka 分区的副本有什么作用?

Kafka 分区的副本可以提高数据的可靠性。每个分区可以有多个副本,当某个副本出现故障时,其他副本可以继续工作,从而保证数据的可靠性。

06. Kafka 分区的消息是如何分配到不同的分区中的?

Kafka 分区的消息是根据消息的 key 进行哈希计算后分配到不同的分区中的。如果消息没有 key,那么 Kafka 会使用轮询的方式将消息分配到不同的分区中。

07. Kafka 分区可以增加或者减少吗?

在 Kafka 中,分区的数量是在创建 Topic 时指定的,一旦创建后就不能直接增加或减少分区的数量。这是因为 Kafka 的分区机制是基于一致性哈希算法实现的,如果直接增加或减少分区的数量,会导致哈希算法重新计算,从而影响已经存储的消息的分区和副本的分配。

如果需要增加或减少分区的数量,需要进行以下步骤:

① 创建一个新的 Topic,分配新的分区数量。

② 将原来的 Topic 中的消息重新发送到新的 Topic 中。

③ 停止消费者消费原来的 Topic,开始消费新的 Topic。

需要注意的是,将消息从原来的 Topic 中重新发送到新的 Topic 中可能会导致消息的顺序发生变化,因此需要在应用程序中进行相应的处理。

另外,增加或减少分区的数量也会影响 Kafka 集群的负载均衡和性能。如果分区的数量过多,会导致 Kafka 集群的管理和维护变得复杂,从而影响系统的可靠性和稳定性。如果分区的数量过少,会导致数据无法充分分布到多个 Broker 上,从而影响负载均衡和并发处理的效果。因此,在创建 Topic 时需要根据实际情况进行分区数量的设置,避免频繁地增加或减少分区的数量。

08. Kafka 的分区数大于服务器台数时如何分配存储副本?

如果 kafka 服务器只有 3 个节点,那么设置 kafka 的分区数大于服务器台数,在 kafka底层如何分配存储副本:

[root@localhost kafka-01]# bin/kafka-topics.sh --zookeeper localhost:2182 --create --partitions 9 --replication-factor 3  --topic test2
Created topic test2.
[root@localhost kafka-01]# bin/kafka-topics.sh --zookeeper localhost:2182 --describe --topic test2
Topic:test2     PartitionCount:9        ReplicationFactor:3     Configs:
Topic: test2    Partition: 0    Leader: 1       Replicas: 1,0,2 Isr: 1,0,2
Topic: test2    Partition: 1    Leader: 2       Replicas: 2,1,0 Isr: 2,1,0
Topic: test2    Partition: 2    Leader: 0       Replicas: 0,2,1 Isr: 0,2,1
Topic: test2    Partition: 3    Leader: 1       Replicas: 1,2,0 Isr: 1,2,0
Topic: test2    Partition: 4    Leader: 2       Replicas: 2,0,1 Isr: 2,0,1
Topic: test2    Partition: 5    Leader: 0       Replicas: 0,1,2 Isr: 0,1,2
Topic: test2    Partition: 6    Leader: 1       Replicas: 1,0,2 Isr: 1,0,2
Topic: test2    Partition: 7    Leader: 2       Replicas: 2,1,0 Isr: 2,1,0
Topic: test2    Partition: 8    Leader: 0       Replicas: 0,2,1 Isr: 0,2,1

这样是为了leader和follower均匀的分配在每个服务器上,尽量不让每个分区的leader和follower都分配在某几个服务器上,比如只分配在broker0、broker1上,那么这2个服务器挂掉后,数据就丢失了,这样分配的好处是除非3个服务器都挂掉,不然就还可以从broker2同步数据。

在 Kafka 中,如果设置的分区数大于服务器节点数,Kafka 会将多个 Partition 存储在同一个 Broker 上,从而实现多个 Partition 共享同一个 Broker 的存储空间。在这种情况下,Kafka 会将每个 Partition 的副本分配到不同的 Broker 上,以保证数据的可靠性和容错性。

具体来说,Kafka 会使用一致性哈希算法来计算每个 Partition 的副本应该存储在哪个 Broker 上。一致性哈希算法会将每个 Broker 和 Partition 映射到一个哈希环上,然后根据哈希值来确定每个 Partition 的副本应该存储在哪个 Broker 上。如果某个 Broker 宕机,Kafka 会自动将该 Broker 上的 Partition 副本迁移到其他 Broker 上,以保证数据的可靠性和容错性。

需要注意的是,如果设置的分区数过多,会导致 Kafka 集群的管理和维护变得复杂,从而影响系统的可靠性和稳定性。因此,在设置分区数时需要根据实际情况进行权衡,避免设置过多的分区数。

09. Kafka 创建Topic时如何将分区设置到不同的broker中?

在 Kafka 中,一个 Topic 可以被分成多个 Partition,每个 Partition 可以被存储在不同的 Broker 上。在创建 Topic 时,你可以指定 Partition 的数量和副本数,但是不能直接指定 Partition 存储在哪个 Broker 上。

Kafka 使用 Partition 的方式来实现数据的分布和负载均衡。当你向一个 Topic 发送消息时,Kafka 会根据消息的 Key 计算出该消息应该被存储在哪个 Partition 上。如果该 Partition 存在多个副本,Kafka 会将消息复制到所有副本中。

10. Kafka 为什么需要手动调整分区的副本分配?

Kafka是一个分布式的消息队列系统,它的分区副本机制是保证数据可靠性和高可用性的重要手段之一。在Kafka中,每个分区都有多个副本,其中一个副本作为leader,负责处理读写请求,其他副本作为follower,负责从leader同步数据。当leader副本出现故障时,Kafka会自动将其中一个follower副本提升为新的leader,以保证服务的可用性。

然而,由于Kafka集群的规模和复杂性,有时候需要手动调整分区副本的分配情况,以优化集群的性能和可靠性。例如:

① 副本分配不均衡:如果某些分区的副本分配不均衡,可能会导致某些broker的负载过重,影响整个集群的性能。此时需要手动调整副本分配,使得每个broker的负载均衡。

② 副本同步延迟:如果某些follower副本同步leader副本的延迟过高,可能会导致数据不一致,影响数据可靠性。此时需要手动调整副本分配,将follower副本分配到延迟较低的broker上。

③ 副本故障:如果某些副本出现故障,需要手动将其替换为新的副本,以保证数据可靠性和高可用性。

因此,手动调整分区副本是Kafka集群管理中的重要工作之一,需要根据实际情况进行调整,以保证集群的性能和可靠性。

11. Kafka 如何手动的调整分区的副本分配?

在生产环境中,每台服务器的配置和性能不一致,但是Kafka只会根据自己的代码规则创建对应的分区副本,就会导致个别服务器存储压力较大,所以需要手动调整分区副本的存储。可以通过手动调整分区的副本来实现数据的容错和可靠性。具体来说,可以将一个分区的副本从一个 Broker 迁移到另一个 Broker,以保证数据的可靠性和容错性。

kafka-reassign-partitions工具可以通过重新分配分区副本来实现负载均衡和副本同步延迟的调整。

① 创建一个新的 topic,3个分区,2个副本,并查看副本存储情况

[root@localhost kafka-01]# bin/kafka-topics.sh --zookeeper localhost:2183 --create --partitions 3 --replication-factor 2  --topic test3
Created topic test3.

[root@master01 kafka01]# bin/kafka-topics.sh --zookeeper localhost:2183 --describe --topic test3
Topic:test3     PartitionCount:3        ReplicationFactor:2     Configs:
Topic: test3    Partition: 0    Leader: 1       Replicas: 1,0   Isr: 1,0
Topic: test3    Partition: 1    Leader: 2       Replicas: 2,1   Isr: 2,1
Topic: test3    Partition: 2    Leader: 0       Replicas: 0,2   Isr: 0,2

② 创建副本存储计划(所有副本都指定存储在 broker0、broker1 中)

[root@hadoop101 kafka_2.12-2.2.1]# vi increase-replication-factor.json
{
    "version":1,
    "partitions":[{"topic":"test3","partition":0,"replicas":[0,1]},
                  {"topic":"test3","partition":1,"replicas":[0,1]},
                  {"topic":"test3","partition":2,"replicas":[1,0]}]
}

③ 执行以下命令,执行副本存储计划,将JSON文件作为参数传入:

[root@master01 kafka01]# bin/kafka-reassign-partitions.sh --zookeeper localhost:2183 --reassignment-json-file increase-replication-factor.json --execute
Current partition replica assignment

{"version":1,"partitions":[{"topic":"test3","partition":2,"replicas":[0,2],"log_dirs":["any","any"]},{"topic":"test3","partition":1,"replicas":[2,1],"log_dirs":["any","any"]},{"topic":"test3","partition":0,"replicas":[1,0],"log_dirs":["any","any"]}]}

Save this to use as the --reassignment-json-file option during rollback
Successfully started reassignment of partitions.

④ 等待重新分配完成后,执行以下命令,验证分区副本是否已经重新分配成功:

[root@master01 kafka01]# bin/kafka-reassign-partitions.sh --zookeeper localhost:2183 --reassignment-json-file increase-replication-factor.json --verify
Status of partition reassignment:
Reassignment of partition test3-0 completed successfully
Reassignment of partition test3-1 completed successfully
Reassignment of partition test3-2 completed successfully

⑤ 查看分区副本存储情况,可以看到所有副本都指定存储在 broker0、broker1 中了

[root@master01 kafka01]# bin/kafka-topics.sh --zookeeper localhost:2183 --describe --topic test3
Topic:test3     PartitionCount:3        ReplicationFactor:2     Configs:
Topic: test3    Partition: 0    Leader: 0       Replicas: 0,1   Isr: 1,0
Topic: test3    Partition: 1    Leader: 0       Replicas: 0,1   Isr: 1,0
Topic: test3    Partition: 2    Leader: 1       Replicas: 1,0   Isr: 0,1

12. kafka 如何手动增加分区的副本数量?

① 创建一个主题,分区数量为3,副本数量为1,并查看主题的分区副本数:

[root@master01 kafka01]# bin/kafka-topics.sh --zookeeper localhost:2183 --create --partitions 3 --replication-factor 1 --topic test4
Created topic test4.
[root@master01 kafka01]# bin/kafka-topics.sh --zookeeper localhost:2183 --describe --topic test4
Topic:test4     PartitionCount:3        ReplicationFactor:1     Configs:
Topic: test4    Partition: 0    Leader: 0       Replicas: 0     Isr: 0
Topic: test4    Partition: 1    Leader: 1       Replicas: 1     Isr: 1
Topic: test4    Partition: 2    Leader: 2       Replicas: 2     Isr: 2

② 创建副本存储计划,用于指定新的副本分配方案,每个分区增加2个副本,分别存储在 broker0、broker1、broker2 中:

[root@master01 kafka01]# vi increase-replication-factor.json
{
    "version":1,
    "partitions":[{"topic":"test4","partition":0,"replicas":[0,1,2]},
                  {"topic":"test4","partition":1,"replicas":[0,1,2]},
                  {"topic":"test4","partition":2,"replicas":[0,1,2]}]
}

③ 执行副本存储计划:

[root@master01 kafka01]# bin/kafka-reassign-partitions.sh --zookeeper localhost:2183 --reassignment-json-file increase-replication-factor.json --execute
Current partition replica assignment

{"version":1,"partitions":[{"topic":"test4","partition":2,"replicas":[2],"log_dirs":["any"]},{"topic":"test4","partition":1,"replicas":[1],"log_dirs":["any"]},{"topic":"test4","partition":0,"replicas":[0],"log_dirs":["any"]}]}

Save this to use as the --reassignment-json-file option during rollback
Successfully started reassignment of partitions.

④ 验证副本存储计划:

[root@master01 kafka01]# bin/kafka-reassign-partitions.sh --zookeeper localhost:2183 --reassignment-json-file increase-replication-factor.json --verify
Status of partition reassignment:
Reassignment of partition test4-0 completed successfully
Reassignment of partition test4-1 completed successfully
Reassignment of partition test4-2 completed successfully

⑤ 当所有分区的副本重分配完成后,就成功地手动增加了 Kafka 主题的副本数量,查看副本和分区:

[root@master01 kafka01]# bin/kafka-topics.sh --zookeeper localhost:2183 --describe --topic test4
Topic:test4     PartitionCount:3        ReplicationFactor:3     Configs:
Topic: test4    Partition: 0    Leader: 0       Replicas: 0,1,2 Isr: 0,2,1
Topic: test4    Partition: 1    Leader: 1       Replicas: 0,1,2 Isr: 1,2,0
Topic: test4    Partition: 2    Leader: 2       Replicas: 0,1,2 Isr: 2,0,1

13. Kafka 为什么需要手动增加分区的副本数量?

Kafka 是一个分布式的消息系统,它的设计目标是高可用性和高吞吐量。为了实现这个目标,Kafka 采用了副本机制来保证数据的可靠性和容错性。每个分区都可以配置多个副本,每个副本都保存了完整的分区数据,其中一个副本被指定为 leader,负责处理读写请求,其他副本则作为 follower,负责复制 leader 的数据。

手动增加副本是为了增加系统的可用性和容错性。当某个副本出现故障时,Kafka 会自动将其替换为其他副本,但是如果副本数不足,就无法保证数据的可靠性和容错性。因此,手动增加副本可以提高系统的可用性和容错性,减少数据丢失的风险。

此外,手动增加副本还可以提高系统的读取性能。由于每个副本都可以处理读请求,增加副本可以提高读取请求的并发处理能力,从而提高系统的读取性能。

14. Kafka 分区负载均衡如何实现?

Kafka是一个分布式消息系统,它将消息分成多个分区并将其存储在多个Broker上。每个分区都有一个Leader和多个Follower副本。Leader负责处理读写请求,而Follower只是简单地复制Leader的数据。

分区负载平衡是指在Kafka集群中,将分区均匀地分配给不同的Broker,以确保每个Broker的负载均衡。这可以通过使用Kafka的自动分区分配机制来实现。当新的Broker加入集群或现有的Broker离开集群时,Kafka会自动重新分配分区以保持负载平衡。此外,Kafka还提供了手动分区分配机制,允许管理员手动指定分区分配方案。

15. Kafka Leader分区负载平衡如何实现?

正常情况下,Kafka本身会自动把 Leader 分区均匀分散在各个机器上,来保证每台机器的读写吞吐量都是均匀的。但是如果某些broker宕机,会导致Leader 分区过于集中在其他少部分几台broker上,这会导致少数几台broker的读写请求压力过高,其他宕机的broker重启之后都是follower 分区,读写请求很低,造成集群负载不均衡。

分布式 - 消息队列Kafka:Kafka分区常见问题总结_第2张图片

① auto.leader.rebalance.enable,默认是true:用于控制是否启用自动的 leader rebalance(分区 leader 的重新分配)功能。

当该参数设置为 true 时,Kafka 会自动检测 broker 的变化(例如 broker 的上线、下线、宕机等),并尝试重新分配分区的 leader,以保证集群的负载均衡和高可用性。

当该参数设置为 false 时,Kafka 将不会自动进行 leader rebalance,而是需要手动进行操作。

② leader.imbalance.per.broker.percentage,默认是10%:用于控制每个 Broker 上的分区领导者数量的平衡程度。具体来说,它表示每个 Broker 上领导者分区数量的最大偏差百分比。

例如,如果设置 leader.imbalance.per.broker.percentage 为 10,则表示每个 Broker 上领导者分区数量的最大偏差百分比为 10%。如果某个 Broker 上的领导者分区数量超过了平均值的 10%,则该 Broker 将不再接受新的领导者分区,直到其他 Broker 上的领导者分区数量增加,使得整个集群的领导者分区数量平衡。

通过调整 leader.imbalance.per.broker.percentage 参数,可以控制集群中分区领导者的分布情况,从而提高集群的可用性和性能。但是,如果设置过小,可能会导致某些 Broker 上的领导者分区数量过多,从而影响整个集群的稳定性。

③ leader.imbalance.check.interval.seconds,默认值300秒:用于控制Kafka集群中leader分区的负载均衡检查的时间间隔。

它表示每隔多少秒,Kafka就会检查集群中所有分区的leader副本的负载情况,如果发现某个broker上的leader分区负载过重,就会尝试将其迁移到负载较轻的broker上,以实现更好的负载均衡。

需要注意的是,leader.imbalance.check.interval.seconds的值越小,Kafka集群的负载均衡就会越频繁地进行检查和调整,但同时也会增加集群的负担。因此,在设置这个参数时需要根据实际情况进行权衡和调整。

16. Kafka 集群如何选择合适的Topic/Partition数量?

为Kafka集群选择合适的Topic/Partition数量需要考虑多个因素,包括:

① 数据量:如果数据量较大,可以增加Partition数量以提高并行处理能力。

② 消费者数量:如果有多个消费者,可以增加Partition数量以提高并行消费能力。

③ 硬件资源:如果硬件资源充足,可以增加Partition数量以提高集群的吞吐量。

④ 数据保留时间:如果数据保留时间较长,可以增加Partition数量以分散数据存储的压力。

⑤ 数据处理方式:如果数据需要按照某种方式进行处理,可以根据处理方式将数据分配到不同的Partition中。

一般来说,建议将Partition数量设置为集群中Broker数量的2-3倍,这样可以充分利用集群的资源,同时保证数据的高可用性。但具体的数量还需要根据实际情况进行调整。

17. Kafka 分区数量是否越多越好呢?

显然不是,因为每个分区都有自己的开销:

一、客户端/服务器端需要使用的内存就越多

Kafka0.8.2之后,在客户端producer有个参数batch.size,默认是16KB。它会为每个分区缓存消息,一旦满了就打包将消息批量发出。看上去这是个能够提升性能的设计。不过很显然,因为这个参数是分区级别的,如果分区数越多,这部分缓存所需的内存占用也会更多。假设你有10000个分区,按照默认设置,这部分缓存需要占用约157MB的内存。而consumer端呢?我们抛开获取数据所需的内存不说,只说线程的开销。如果还是假设有10000个分区,同时consumer线程数要匹配分区数(大部分情况下是最佳的消费吞吐量配置)的话,那么在consumer client就要创建10000个线程,也需要创建大约10000个Socket去获取分区数据。这里面的线程切换的开销本身已经不容小觑了。

服务器端的开销也不小,如果阅读Kafka源码的话可以发现,服务器端的很多组件都在内存中维护了分区级别的缓存,比如controller,FetcherManager等,因此分区数越多,这种缓存的成本就越大。

二、文件句柄的开销

每个分区在底层文件系统都有属于自己的一个目录。该目录下通常会有两个文件:base_offset.log和base_offset.index。Kafak的controller和ReplicaManager会为每个broker都保存这两个文件句柄(file handler)。很明显,如果分区数越多,所需要保持打开状态的文件句柄数也就越多,最终可能会突破你的ulimit -n的限制。

三、降低高可用性

Kafka通过副本(replica)机制来保证高可用。具体做法就是为每个分区保存若干个副本(replica_factor指定副本数)。每个副本保存在不同的broker上。其中的一个副本充当leader 副本,负责处理producer和consumer请求。其他副本充当follower角色,由Kafka controller负责保证与leader的同步。如果leader所在的broker挂掉了,contorller会检测到然后在zookeeper的帮助下重选出新的leader——这中间会有短暂的不可用时间窗口,虽然大部分情况下可能只是几毫秒级别。但如果你有10000个分区,10个broker,也就是说平均每个broker上有1000个分区。此时这个broker挂掉了,那么zookeeper和controller需要立即对这1000个分区进行leader选举。比起很少的分区leader选举而言,这必然要花更长的时间,并且通常不是线性累加的。如果这个broker还同时是controller情况就更糟了。

18. Kafka 如何确定分区数量?

可以遵循一定的步骤来尝试确定分区数:创建一个只有1个分区的topic,然后测试这个topic的producer吞吐量和consumer吞吐量。假设它们的值分别是Tp和Tc,单位可以是MB/s。然后假设总的目标吞吐量是Tt,那么分区数 = Tt / max(Tp, Tc)

说明:Tp表示producer的吞吐量。测试producer通常是很容易的,因为它的逻辑非常简单,就是直接发送消息到Kafka就好了。Tc表示consumer的吞吐量。测试Tc通常与应用的关系更大, 因为Tc的值取决于你拿到消息之后执行什么操作,因此Tc的测试通常也要麻烦一些。

19. Kafka 如何保证顺序的消费主题中的消息?

Kafka 通过分区(Partition)和偏移量(Offset)来保证顺序消费主题中的消息。

在 Kafka 中,每个主题可以被分成多个分区,每个分区都是一个有序的消息队列。消费者可以订阅一个或多个分区,并从每个分区的起始位置开始消费消息。消费者可以通过指定偏移量来控制从哪个位置开始消费消息,这个偏移量可以是任意位置,不一定是分区的起始位置。

当一个消费者订阅了一个分区后,它会不断地从分区中拉取消息,直到消费者关闭或者分区被删除。消费者可以通过轮询的方式来拉取消息,每次拉取一批消息,然后处理这些消息。消费者处理完一批消息后,可以提交这批消息的偏移量,表示这批消息已经被消费了。Kafka 会记录每个消费者在每个分区上消费的偏移量,以便下次消费者继续从上次消费的位置开始消费。

通过分区和偏移量的机制,Kafka 可以保证同一个分区内的消息是有序的,而不同分区之间的消息则可能是无序的。如果一个主题只有一个分区,那么消费者就可以保证按照消息的顺序消费这个主题中的所有消息。

20. Kafka 如何保证顺序的消费分区中的消息?

Kafka 通过分区(partition)和消费者组(consumer group)来保证顺序消费分区中的消息。

首先,Kafka 将一个主题分成多个分区,每个分区内的消息是有序的。消费者可以订阅一个或多个分区,每个消费者只能消费一个分区内的消息。这样,每个分区内的消息顺序就得到了保证。

其次,Kafka 允许多个消费者组同时消费同一个主题。每个消费者组内的消费者可以消费不同的分区,但同一个分区只能被同一个消费者组内的一个消费者消费。这样,同一个分区内的消息顺序也得到了保证。

因此,如果要保证顺序消费分区中的消息,需要满足以下两个条件:

  • 每个分区内的消息是有序的。
  • 同一个分区只能被同一个消费者组内的一个消费者消费。

需要注意的是,如果消费者组内的消费者数量大于分区数量,就会出现一些消费者无法消费到消息的情况。此时,可以通过增加分区数量或减少消费者数量来解决。

21. Kafka 自动分区分配机制是什么?

Kafka的自动分区分配机制是指在Kafka集群中新增或删除broker时,Kafka会自动重新分配分区以保证负载均衡和高可用性。具体来说,Kafka的自动分区分配机制包括以下几个步骤:

① 计算每个broker的分区数:Kafka会统计每个broker当前拥有的分区数,并计算出每个broker应该拥有的分区数,以保证负载均衡。

② 计算每个消费者组的消费者数:Kafka会统计每个消费者组中的消费者数,并计算出每个消费者应该消费的分区数,以保证消费者之间的负载均衡。

③ 分配分区:Kafka会根据每个broker的分区数和每个消费者组的消费者数,计算出每个消费者应该消费的分区,并将分区分配给对应的消费者。

④ 重新分配分区:当新增或删除broker时,Kafka会重新计算每个broker的分区数,并重新分配分区,以保证负载均衡和高可用性。

需要注意的是,Kafka的自动分区分配机制是基于消费者组的,因此同一个消费者组中的消费者会共同消费分配给该消费者组的分区。如果需要实现多个消费者组消费同一个主题的分区,可以使用Kafka的多消费者组机制。

22. Kafka 自动分区分配机制如何开启?

Kafka的自动分区分配机制是默认开启的,但是在某些情况下可能会被禁用。如果需要开启自动分区分配机制,可以按照以下步骤进行操作:

① 确认partition.assignment.strategy参数设置为 org.apache.kafka.clients.consumer.RangeAssignor,这是默认的分区分配策略。

② 确认auto.partition.assignment参数设置为true,这是默认的自动分区分配开关。

③ 如果使用自定义的分区分配策略,需要确保该策略实现了org.apache.kafka.clients.consumer.ConsumerPartitionAssignor接口,并在partition.assignment.strategy参数中指定该策略的类名。

④ 如果需要手动分配分区,可以将auto.partition.assignment参数设置为false,然后在消费者启动后调用assign()方法手动分配分区。

需要注意的是,如果消费者组中新增或删除了消费者,或者主题的分区数发生了变化,Kafka会自动触发分区重新分配。

你可能感兴趣的:(【分布式-消息队列Kafka】,分布式,kafka)