我已经用9个分区在Kafka中创建了一个主题,将其恰当地命名为“测试”,并使用Confluent.Kafka
客户端库在C#(.NET Core)中组合了两个简单的应用程序:生产者和使用者。我所做的只是调整examples from the documentation。
我正在运行两个使用者应用程序实例和一个生产者实例。我在这里没有将消费者代码粘贴到什么地方,这是一个琐碎的“获取消息,在屏幕上打印”应用程序,但是,它也可以打印消息来源的分区号。
这是生产者应用程序:
static async Task Main(string[] args)
{
var random = new Random();
var config = new ProducerConfig {
BootstrapServers = "10.0.0.5:9092",
Partitioner = Partitioner.ConsistentRandom
};
int counter = 0;
while (true)
{
using (var p = new ProducerBuilder<string, string>(config).Build())
{
try
{
p.BeginProduce(
"test",
new Message<string, string>
{
//Key = random.Next().ToString(),
Value = $"test {++counter}"
});
if (counter % 10 == 0)
p.Flush();
}
catch (ProduceException<Null, string> e)
{
Console.WriteLine($"Delivery failed: {e.Error.Reason}");
}
}
}
}
问题::如果未设置消息的Key
属性,则所有消息都将发送到分区号7,这意味着我的使用者实例之一处于空闲状态。我必须手动将密钥随机化,以便在分区之间分配它们(请参见注释行)。 (从文档复制过来的原始代码使用Null
作为密钥的类型,这也将所有消息发送到第7个分区。)
那是为什么?根据{{1}}属性的文档,如果未指定密钥,则ProducerConfig.Partitioner
选项应确保随机分配。我尝试使用consistent_random
选项,该选项应该使用随机分布而不管密钥如何,但这无济于事。
这是预期的行为吗,是我做错了事还是遇到错误?
我正在使用Confluent.Kafka NuGet的1.0.0-RC2版本。
Partitioner配置的完整文档:
Partioner.Random
答案 0 :(得分:1)
我遇到了同样的问题。 似乎在启动客户端时,第一条消息将始终位于同一个分区。 如果您对所有消息使用相同的客户端,则 Partioner.Random 将起作用