创建一个分区多于代理的主题

7cjasjjr  于 2021-06-05  发布在  Kafka
关注(0)|答案(3)|浏览(326)

我在本地机器上设置了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在这里没有提出任何错误。
现在,当我使用producer/consumerapi时,一切都正常,但我不能理解的是,在producer/consumer端的配置中,我没有定义要连接的partition。我的问题是,当同一主题有多个分区时,kafka如何决定将消息推送到同一个代理中的哪个分区?这不是一种前后矛盾的行为吗?

anhgbhbe

anhgbhbe1#

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

数据和分区:关系
当制作人发送数据时,它会指向一个主题——但这是50000英尺的视图。你必须明白这一点
数据实际上是一个键值对,它的存储发生在分区级别
默认行为
由于kafka使用一致的散列算法将密钥Map到分区,所以同一密钥的数据将进入同一分区。

hash(key) % number_of_partitions

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

您可以插入一个自定义算法来划分数据。
通过实现partitioner接口并配置kafka producer来使用它。
下面是一个例子

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/

xpcnnkqh

xpcnnkqh2#

Kafka在这里没有提出任何错误。
不需要提出错误。我猜你把分区和复制混为一谈了。从理论上讲,您可以拥有任意多的分区,并且通常只有复制因子与代理的数量相关联。
当同一主题有多个分区时,kafka如何决定将消息推送到同一个代理中的哪个分区?
如果消息有密钥,kafka会对密钥进行哈希运算,并使用结果将消息Map到特定分区,基本上:

hash(key) % number_of_partitions

这意味着具有相同密钥的所有消息将转到同一分区。如果密钥为null并且使用默认分区器,则记录将被发送到随机分区(使用循环算法)。
但是,您可以重写此行为并提供自己的分区方案。例如,如果您将有许多具有特定密钥的消息,那么您可能希望一个分区只保存这些消息。这将确保具有相同密钥的所有消息在使用消息时保持有序。

c90pui9n

c90pui9n3#

您正在混淆两个概念:
分区和复制
分区只是同一主题的“部分”,它们不依赖于可用代理的数量。
当生产者生成数据时,您可以使用循环、散列机制生成数据——这些是Kafka文档中阅读的默认策略。另一个选项是指定要向其生成数据的分区(如果您在逻辑上分隔数据)。
对于使用者,如果不手动“分配”分区,kafka会自动将所有分区“分配”给使用者的示例。
如果您有多个使用者,kafka会尝试平衡连接,即如果您有5个分区和2个使用者(具有相同的使用者组),则第一个使用者可能会从2个分区获取数据,而第二个使用者将从其余3个分区获取数据,或者相反。
分区的数量也决定了对于同一使用者组的单个主题可以达到的并行度。e、 g:50个分区主题数据最多可由50个使用者示例(每个示例1个连接)并行处理。
另一方面,复制明显依赖于可用代理的数量,因为在3个代理上有4个复制是不符合逻辑的,即一个代理最终将拥有相同数据的2个副本。
复制是指整个主题,即根据“复制因子”复制所有分区。
因此,如果您有5个分区,复制因子为3,那么实际上您有所有5个分区的3个副本。
阅读更多信息:https://kafka.apache.org/documentation/
希望这有帮助:)

相关问题