Samza在发送邮件时是否自动创建分区?

时间:2015-11-03 15:05:26

标签: hadoop apache-kafka apache-samza

如果您使用Samza的OutgoingMessageEnvelope使用以下格式发送消息:

public OutgoingMessageEnvelope(SystemStream systemStream,
                               java.lang.Object partitionKey,
                               java.lang.Object key,
                               java.lang.Object message)
Constructs a new OutgoingMessageEnvelope from specified components.
Parameters:
systemStream - Object representing the appropriate stream of which this envelope will be sent on.
partitionKey - A key representing which partition of the systemStream to send this envelope on.
key - A deserialized key to be used for the message.
message - A deserialized message to be sent in this envelope.

并且您在流任务的process()方法中调用此方法并想要将传入的消息路由到适当的分区,Samza会在您调用方法时为您创建分区吗?

E.g。

MessageA = {"id": "idA", "key": "keyA", "body":"some details"}
MessageB = {"id": "idB", "key": "keyB", "body":"some more details"}

如果我在流任务中调用process(),其中msg是一个消息实例:

public void process(IncomingMessageEnvelope envelope, MessageCollector collector, TaskCoordinator coordinator) {
    // ...
    String partition = msg["id"]
    String key = msg["key"]
    collector.send(new OutgoingMessageEnvelope(new SystemStream("kafka", "PartitionedMessages"), id, key, msg));
    // ...

这会自动为我创建分区idA和idB(即在向其发送消息之前是否需要创建这些分区)?我希望能够将消息路由到适当的分区,并且能够使用单独的消息密钥记录压缩。

1 个答案:

答案 0 :(得分:3)

创建主题时,必须指定分区数。您无法动态添加新分区(嗯,您可以但这并不容易,Samza不会自动执行此操作)。如果主题不存在但是具有默认的分区数,Samza应该为您创建新主题。这取决于设置。你可以测试一下。

但值msg["id"]未指定分区的名称。此值仅用于计算目标分区的数量。将此值散列为数字,然后使用模数进行修剪。像这样的东西(有更多的算法,这是基本的算法):

partitionID = hash(msg["id"]) % total_number_of_partitions

partitionID始终是非负整数。这意味着你实际拥有多少个分区并不重要。它总是在某些方面结束。主要思想是,如果您有两条具有相同msg["id"]的消息,则消息将以相同的分区结束。这通常是你想要的。

日志压缩将按预期工作 - 它将从特定分区中删除具有相同密钥的消息(但如果您有两条带有两个不同分区的相同密钥的消息,则不会删除它们)。

仅供参考,您可以使用kafkacat查找分区数量和其他有用的内容。