一个简单的问题:
假设我有一个包含3个分区的主题: 主题:StateEvents P1,P2和P3。
我们还假设生产者生成20条消息:
1,2,3,.......... 20
我的问题是:
生产者产生以下消息时:
1)每个消息都将仅在一个分区中吗?也就是说,P1中为1,P2中为2,P3中为3,P1中为4,P2中为5,P3中为6等,依此类推?
2)如果#1为true,那么当消费者订阅时,它将订阅所有分区,以便获取所有消息吗?
谢谢
答案 0 :(得分:0)
是的,每条消息仅写入一个分区中。
当单个使用者订阅kafka主题(具有多个分区)时,它将从所有分区读取消息。但是,如果您使用同一个使用者group.id运行多个使用者,则每个使用者将从不同的分区中读取。
比方说,kafka主题有3个分区,您有3个使用相同group.id的使用者。每个使用者将读取1-1个分区。但是,如果只有一个使用者,它将从所有3个分区中读取。
答案 1 :(得分:0)
1)目标分区由生产者确定。使用默认的分区程序算法(可以自定义),目标分区是:hash(message-key)%num_partitions。这意味着所有具有相同密钥的消息都将进入同一分区。因此,如果您使用密钥,并且所有消息都具有相同的密钥,那么它们将进入相同的分区。如果未指定密钥,则使用轮询。无论如何,一条消息总是只到达一个分区。
2)如果使用者是使用者组中唯一的使用者,它将获得所有分区。您可以在同一使用者组中添加更多使用者以共享负载(在您的情况下,最多3个使用者,这是您在主题中拥有的分区数,以便一个使用者获得一个分区)。
让不同的消费者从不同的分区获取消息是Kafka如何很好地扩展的方式。这不是缺点,因为您必须考虑使用应用程序(由多个使用者组成)的情况。应用程序标识符可以是其所有使用者使用的组ID:您让应用程序从该主题获取所有消息,但负载分散在其使用者上。
答案 2 :(得分:0)
每条消息将仅发送到一个分区
如果key不为null,则根据配置中实现的分区方法执行分区ID计算。 这是源代码
class DefaultPartitioner(props: VerifiableProperties = null) extends Partitioner {
private val random = new java.util.Random
def partition(key: Any, numPartitions: Int): Int = {
Utils.abs(key.hashCode) % numPartitions
}
}
为确保相同类型的消息顺序(FIFO),一个分区只能由同一组的一个使用者使用,而不同组的使用者可以将同一分区绑定以重复使用。 但是消费者可以使用多个分区。