如何为 Kafka 生产者选择密钥和偏移量
How to choose a Key and Offset for a Kafka Producer
我正在关注 here。同时关注代码。我提出了两个问题
- Key 和 offset 是否相同?
根据Google,
Offset: A Kafka topic receives messages across a distributed set of
partitions where they are stored. Each partition maintains the
messages it has received in a sequential order where they are
identified by an offset, also known as a position.
对我来说两者似乎非常相似。由于偏移量在分区中维护唯一消息:生产者根据记录的键
将记录发送到分区
- 为制作人选择 Key/Offset 的最佳方式是什么?
例如我上面提供的示例,他们选择了时间戳作为键和偏移量。
这总是最好的推荐吗?
class IRCMessageListener extends IRCEventAdapter {
@Override
public void onPrivmsg(String channel, IRCUser u, String msg) {
IRCMessage event = new IRCMessage(channel, u, msg);
//FIXME kafka round robin default partitioner seems to always publish to partition 0 only (?)
long ts = event.getInt64("timestamp");
Map<String, ?> srcOffset = Collections.singletonMap(TIMESTAMP_FIELD, ts);
Map<String, ?> srcPartition = Collections.singletonMap(CHANNEL_FIELD, channel);
SourceRecord record = new SourceRecord(srcPartition, srcOffset, topic, KEY_SCHEMA, ts, IRCMessage.SCHEMA, event);
queue.offer(record);
}
因为我实际上是在尝试创建自定义 Kafka 连接器以从第 3 方 WebSocket API 获取数据。 API 发送给定Key值的实时数据流消息。所以我想到了将那个键用于我的 PartitionKey 以及 Offset。但需要确保我的想法是正确的。
Key 是一个可选的元数据,可以与 Kafka 消息一起发送,默认情况下,它用于将消息路由到特定分区。例如。如果您要发送消息 m,密钥为 k,主题 mytopic 具有 p个分区,然后m去分区Hash(k) %p 在 mytopic 中。它与分区的偏移量没有任何关系。消费者使用偏移量来跟踪分区中最后读取消息的位置。在你的情况下,如果时间戳是相当随机分布的,那很好,否则你可能在使用它作为键时导致分区不平衡。
这些是一些基本的区别:
Offset:由kafka维护,用于跟踪消费的记录,避免消费时丢失记录和重复记录。
Key :它特定于输入事件,如果它不可用则默认为空,这在使用 kafka connect.every 消息将记录写入具有默认分区的 HDFS 时很有用有一个密钥或许多消息可以有相似的密钥。
我正在关注 here。同时关注代码。我提出了两个问题
- Key 和 offset 是否相同?
根据Google,
Offset: A Kafka topic receives messages across a distributed set of partitions where they are stored. Each partition maintains the messages it has received in a sequential order where they are identified by an offset, also known as a position.
对我来说两者似乎非常相似。由于偏移量在分区中维护唯一消息:生产者根据记录的键
将记录发送到分区- 为制作人选择 Key/Offset 的最佳方式是什么?
例如我上面提供的示例,他们选择了时间戳作为键和偏移量。 这总是最好的推荐吗?
class IRCMessageListener extends IRCEventAdapter {
@Override
public void onPrivmsg(String channel, IRCUser u, String msg) {
IRCMessage event = new IRCMessage(channel, u, msg);
//FIXME kafka round robin default partitioner seems to always publish to partition 0 only (?)
long ts = event.getInt64("timestamp");
Map<String, ?> srcOffset = Collections.singletonMap(TIMESTAMP_FIELD, ts);
Map<String, ?> srcPartition = Collections.singletonMap(CHANNEL_FIELD, channel);
SourceRecord record = new SourceRecord(srcPartition, srcOffset, topic, KEY_SCHEMA, ts, IRCMessage.SCHEMA, event);
queue.offer(record);
}
因为我实际上是在尝试创建自定义 Kafka 连接器以从第 3 方 WebSocket API 获取数据。 API 发送给定Key值的实时数据流消息。所以我想到了将那个键用于我的 PartitionKey 以及 Offset。但需要确保我的想法是正确的。
Key 是一个可选的元数据,可以与 Kafka 消息一起发送,默认情况下,它用于将消息路由到特定分区。例如。如果您要发送消息 m,密钥为 k,主题 mytopic 具有 p个分区,然后m去分区Hash(k) %p 在 mytopic 中。它与分区的偏移量没有任何关系。消费者使用偏移量来跟踪分区中最后读取消息的位置。在你的情况下,如果时间戳是相当随机分布的,那很好,否则你可能在使用它作为键时导致分区不平衡。
这些是一些基本的区别:
Offset:由kafka维护,用于跟踪消费的记录,避免消费时丢失记录和重复记录。
Key :它特定于输入事件,如果它不可用则默认为空,这在使用 kafka connect.every 消息将记录写入具有默认分区的 HDFS 时很有用有一个密钥或许多消息可以有相似的密钥。