了解Kafka主题和分区


209

我开始学习用于企业解决方案目的的Kafka。

在阅读期间,我想到了一些问题:

  1. 生产者在生成消息时-将指定要将消息发送到的主题,对吗?它关心分区吗?
  2. 当订户运行时-是否指定其组ID,以便它可以成为同一主题或该组消费者感兴趣的多个主题的一组消费者的一部分?
  3. 每个消费者组在代理上都有对应的分区还是每个消费者都有一个分区?

  4. 分区是由代理创建的,因此对于消费者而言不是问题吗?

  5. 由于这是每个分区都有偏移量的队列,使用方是否有责任指定要读取的消息?是否需要保存其状态?

  6. 从队列中删除消息后会发生什么?-例如:保留时间为3小时,然后时间过去了,双方如何处理偏移量?

Answers:


193

这篇文章已经有答案了,但是我要添加一些观点,这些观点来自《卡夫卡权威指南》

在回答每个问题之前,让我们先概述一下生产者组件:

生产者组件概述

1.生产者在生成消息时-它将指定要将消息发送到的主题,对吗?它关心分区吗?

生产者将决定目标分区以放置任何消息,具体取决于:

  • 分区ID(如果在消息中指定)
  • 键%num个分区(如果未提及分区ID)
  • 如果消息中分区ID消息键均不可用,则循环,这意味着仅值可用

2.当订户正在运行时-是否指定其组ID,以便它可以成为同一主题或该组消费者感兴趣的多个主题的消费者集群的一部分?

除非使用简单的赋值API,并且不需要在Kafka中存储偏移量,否则应始终配置group.id。它不会成为任何组的一部分。资源

3.每个消费者组在经纪人上都有对应的分区吗?还是每个消费者都有一个分区?

在一个使用者组中,每个分区只能由一个使用者处理。这些是可能的情况

  • 使用者数量小于主题分区的数量,则可以将多个分区分配给组中的一个使用者 使用者数量少于主题分区
  • 使用者数量与主题分区的数量相同,则分区和使用者映射如下所示, 使用者数量与主题分区数量相同
  • 使用者数量大于主题分区的数量,则分区和使用者映射如下所示,无效,请检查使用者5 使用者数量大于主题分区数量

4.作为经纪人创建的分区,因此消费者不必担心吗?

消费者应了解问题3中讨论的分区数量。

5.由于这是每个分区都有偏移量的队列,使用者是否有责任指定要读取的消息?是否需要保存其状态?

Kafka(具体来说是Group Coordinator)通过产生内部__consumer_offsets主题的消息来处理偏移状态,也可以通过将其设置enable.auto.commit为来将其配置为手动行为false。在这种情况下consumer.commitSync()consumer.commitAsync()可能有助于管理偏移量。

有关组协调员的更多信息:

  1. 它是从Kafka服务器端群集中选出的经纪人之一。
  2. 消费者与组协调器进行交互以获取偏移量提交和获取请求。
  3. 消费者定期向组协调员发送心跳。

6.从队列中删除消息会怎样?-例如:保留时间为3小时,然后时间过去了,双方如何处理偏移量?

如果有任何使用者在保留期后开始使用,则会按照auto.offset.reset可能是的配置使用消息latest/earliest。从技术上讲,这是latest(开始处理新消息),因为到那时所有消息都已过期,并且保留是主题级别的配置。


7
嗨!我是公认答案的作者,但我认为您的观点也非常好,尤其是在第3点上,图表使事情更清晰了200%!您认为我们应该合并吗?
C4stor

我的意思是说我(或您)可以将您答案的要素纳入我的答案,以使其更具可见性并改善(当前)最重要的答案。但是没有你的同意我不会做的!
C4stor

为什么不能将多个使用者映射到分区?为了确保消息只处理一次?谢谢你的回答。
g10guang

1
@ g10guang:这是因为提交偏移量维护很困难。
mrsrinivas

2
另一种情况。您可以有一个分区,并且有多个使用者已订阅/分配给它。经纪人只会将记录传递给第一个注册的使用者。但是,让我们假设第一个使用者比轮询间隔花费更多的时间来处理任务。记录消费未提交给代理。经纪人知道消费者闲逛。在这种状态下,代理触发重新平衡,将新分配的分区发送给其所有使用者。即使C1仍在处理该消息,该消息也被另一个使用者再次使用。小心。
鲁本·达达里奥

134

让我们按顺序排列它们:)

1-当生产者正在生成消息时-它会指定要将消息发送到的主题,对吗?它关心分区吗?

默认情况下,生产者不关心分区。您可以选择使用自定义分区程序来获得更好的控制,但这是完全可选的。


2-订户正在运行时-是否指定其组ID,以便它可以成为同一主题或该组消费者感兴趣的多个主题的消费者集群的一部分?

是的,消费者加入(或创建,如果他们是一个人)消费者组来分担负载。同一组中的任何两个消费者都不会收到相同的消息。


3-每个消费者组在代理上都有对应的分区,还是每个消费者都有一个分区?

都不行 在两个条件下,为消费者组中的所有消费者分配了一组分区:同一组中没有两个消费者具有相同的任何分区-总体上为消费者组分配了每个现有分区。


4-代理创建的分区是否对消费者而言无关紧要?

它们不是,但是您可以从3中看到,拥有比现有分区更多的使用者完全是没有用的,因此这是您消耗的最大并行度。


5-由于这是每个分区都有偏移量的队列,使用者是否有责任指定要读取的消息?是否需要保存其状态?

是的,使用者可以为每个分区的每个主题节省偏移量。这完全由Kafka处理,不用担心。


6-从队列中删除消息会怎样?-例如:保留时间为3小时,然后时间过去了,双方如何处理偏移量?

如果使用者曾经请求代理程序上某个分区不可用的偏移量(例如,由于删除),它将进入错误模式,并最终将此分区自身重置为可用的最新消息或最早消息(取决于auto.offset.reset配置值),然后继续工作。


3
Sry :)用500个字符的盒子来解释整个kafka的过程有点困难,我建议阅读kafka.apache.org/documentation.html#theconsumer(可能还有第4节的其余部分,关于kafka的内部结构)。基本上:使用者请求保存偏移量,但是这些偏移量将保存在其他位置。
C4stor

我只是读了这篇,但这仍然不能解释它的存放位置:Kafka对此有不同的处理。我们的主题分为一组完全有序的分区,每个分区在一个给定的时间由一个使用者使用。这意味着使用者在每个分区中的位置只是一个整数,即下一个要使用的消息的偏移量。这使得消耗的状态很小,每个分区只有一个数字。可以定期检查该状态。这使得等同于消息确认的价格非常便宜。
Pinidbest

22

Kafka使用主题概念来将顺序带入消息流。

为了平衡负载,可以将主题划分为多个分区,并在代理之间进行复制。

分区是有序的,不可变的消息序列,这些消息被连续附加,即提交日志。

分区中的消息具有顺序的ID号,该ID唯一地标识分区中的每个消息。

分区允许主题的日志扩展到超出单个服务器(代理)的大小,并充当并行单元。

主题的分区分布在Kafka集群中的代理上,每个代理都在其中处理数据并请求共享分区。

每个分区都在可配置数量的代理中复制,以确保容错能力。

在这篇文章中有很好的解释:http : //codeflex.co/what-is-apache-kafka/


分区仅用于主题负载平衡吗?
g10guang

1
@ g10guang:分区也有助于并行处理消息。
mrsrinivas

如果我错了,请纠正我,当生产者发送的消息以及该消息出现在主题中时,它会根据配置将其复制到分区,然后消费者使用它。对?
Atul

1
@Atul根据当前的Partitioner配置,消息将被附加到该主题的一个分区中(默认情况下,消息键的哈希值决定消息进入的分区),是的,使用者将以以下方式接收消息:它使用来自该分区的消息
Kevin Hooke

@Kevin Hooke,感谢您的解释并清除我的理解。
Atul,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.