【问题标题】:creating a topic with partitions more than the brokers创建一个分区多于代理的主题
【发布时间】:2020-08-26 14:28:46
【问题描述】:

我在本地机器上设置了 3 个代理,并使用5 分区创建了一个主题, bin/kafka-topics.sh --create --bootstrap-server localhost:9092 --replication-factor 3 --partitions 5 --topic test-partitions

然后来描述我的test-partitions话题,

bin/kafka-topics.sh --describe --bootstrap-server localhost:9092 --topic test-partitions

导致

Topic: test-partitions  PartitionCount: 5   ReplicationFactor: 3    Configs: segment.bytes=1073741824
    Topic: test-partitions  Partition: 0    Leader: 1   Replicas: 1,2,0 Isr: 1,2,0
    Topic: test-partitions  Partition: 1    Leader: 0   Replicas: 0,1,2 Isr: 0,1,2
    Topic: test-partitions  Partition: 2    Leader: 2   Replicas: 2,0,1 Isr: 2,0,1
    Topic: test-partitions  Partition: 3    Leader: 1   Replicas: 1,0,2 Isr: 1,0,2
    Topic: test-partitions  Partition: 4    Leader: 0   Replicas: 0,2,1 Isr: 0,2,1

Kafka 不会在此处引发任何错误。

现在,当我使用生产者/消费者 API 时,一切正常,但我无法理解的是,在生产者/消费者端的配置中,我没有定义要连接的分区。我的问题是,当我对同一主题有多个分区时,kafka 如何决定将消息推送到同一代理中的哪个分区?这不是不一致的行为吗?

【问题讨论】:

    标签: apache-kafka


    【解决方案1】:

    在 Kafka 中,在多台机器上传播/分布数据处理的是分区(而不是单个记录)。下面描述的场景

    数据和分区:关系

    当生产者发送数据时,它会转到一个主题 - 但那是 50,000 英尺的视图。你必须明白这一点

    数据实际上是一个键值对 它的存储发生在分区级别

    默认行为

    由于 Kafka 使用一致的哈希算法将 key 映射到分区,因此相同 key 的数据会进入同一个分区。

    hash(key) % number_of_partitions
    

    如果是空键(是的,这是可能的),数据会随机放置在任何分区上。如果您只有一个分区:所有数据都转到该单个分区

    您可以插入自定义算法来对数据进行分区。

    通过实现 Partitioner 接口并配置 Kafka 生产者来使用它。

    这是一个例子

    public class RandomKakfaPartitioner implements Partitioner {
    
        @Override
        public int partition(String topic, Object key, byte[] keyBytes, Object val, byte[] valBytes, Cluster cluster) {
    
              // logic to calculate targetPartition
    
              return targetPartition;
        }
    
        @Override
        public void close() {
            //no-op
        }
    
        @Override
        public void configure(Map<String, ?> map) {
            //no-op
        }
    

    https://www.confluent.io/blog/apache-kafka-producer-improvements-sticky-partitioner/

    【讨论】:

      【解决方案2】:

      Kafka 不会在这里引发任何错误。

      不需要引发错误。我猜您将分区与复制混为一谈。理论上,您可以拥有任意数量的分区,并且通常只有复制因子与代理的数量相关联。

      当我有多个分区用于同一主题时,kafka 如何决定将消息推送到同一代理中的哪个分区?

      如果消息有key,kafka会对key进行hash并使用结果映射 到特定分区的消息,基本上:

      hash(key) % number_of_partitions
      

      这意味着具有相同密钥的所有消息将转到相同的分区。如果 key 为 null 并且使用了默认的 Partitioner,则记录将被发送到一个随机的 Partition(使用循环算法)。

      但是,您可以覆盖此行为并提供您自己的分区方案。例如,如果您将有许多具有特定键的消息,您可能希望一个分区仅保存这些消息。这将确保具有相同密钥的所有消息在使用消息时保持有序。

      【讨论】:

        【解决方案3】:

        您对两个概念感到困惑:

        分区和复制

        分区只是同一主题的“部分”,它们不依赖于可用代理的数量。

        当生产者生成数据时,您可以使用循环、散列机制进行生成 - 这些是 Kafka 文档中有关这些的默认策略。其他选项是指定要生成数据的分区(如果您在逻辑上分离数据)。

        对于消费者,如果您不手动“分配”分区,Kafka 会自动将所有分区“分配”给您的消费者实例。

        如果您有多个消费者,Kafka 会尝试平衡连接,即如果您有 5 个分区和 2 个消费者(具有相同的消费者组),第一个消费者可能会从 2 个分区和第二个消费者将从剩余的 3 个分区或其他方式获取数据。

        此外,分区的数量决定了您可以为具有相同消费者组的单个主题实现的并行度。例如:最多 50 个消费者实例(每个 1 个连接)可以并行处理 50 个分区主题数据。

        另一方面,复制明显依赖于可用代理的数量,因为在 3 个代理上进行 4 次复制是不合逻辑的,即一个代理最终将拥有相同数据的 2 个副本。

        复制是指整个主题,即所有分区都根据“复制因子”进行复制。

        因此,如果您有 5 个分区且复制因子为 3,那么您基本上拥有所有 5 个分区的 3 个副本。

        在此处阅读更多信息:https://kafka.apache.org/documentation/

        希望这会有所帮助:)

        【讨论】:

          猜你喜欢
          • 2017-07-31
          • 2019-07-24
          • 1970-01-01
          • 2016-04-05
          • 2017-04-05
          • 1970-01-01
          • 2018-02-16
          • 2020-09-02
          • 1970-01-01
          相关资源
          最近更新 更多