C# 使用PartitionSender发送到EventHubs时,是否可以设置EventData.PartitionKey?
我目前在Azure中设置了一个EventHub实例。它有5个分区。我想知道的是C# 使用PartitionSender发送到EventHubs时,是否可以设置EventData.PartitionKey?,c#,azure,azure-eventhub,C#,Azure,Azure Eventhub,我目前在Azure中设置了一个EventHub实例。它有5个分区。我想知道的是PartitionKey是否必须始终是介于0和n-1之间的数字,其中n是分区的数量 我有以下代码: private static async Task SendMessagesToEventHub(int numMessagesToSend) { var sender = eventHubClient.CreatePartitionSender("test1"); fo
PartitionKey
是否必须始终是介于0
和n-1
之间的数字,其中n
是分区的数量
我有以下代码:
private static async Task SendMessagesToEventHub(int numMessagesToSend)
{
var sender = eventHubClient.CreatePartitionSender("test1");
for (var i = 0; i < numMessagesToSend; i++)
{
try
{
var message = $"Message {i}";
Console.WriteLine($"Sending message: {message}");
await sender.SendAsync(new EventData(Encoding.UTF8.GetBytes(message)));
}
catch (Exception exception)
{
Console.WriteLine($"{DateTime.Now} > Exception: {exception.Message}");
}
await Task.Delay(10);
}
Console.WriteLine($"{numMessagesToSend} messages sent.");
}
private静态异步任务SendMessagesToEventHub(int numMessagesToSend)
{
var sender=eventHubClient.CreatePartitionSender(“test1”);
对于(变量i=0;i异常:{Exception.Message}”);
}
等待任务。延迟(10);
}
WriteLine($“{numMessagesSend}已发送消息”);
}
这将抛出一个异常
指定的分区对于EventHub分区发送方或接收方无效。它应该介于0和4之间
在EventHub中,这是关于分区键的说法:
EventData类具有PartitionKey属性,该属性使发送方能够指定一个值,该值经过哈希处理以生成分区分配。使用分区键可确保将具有相同键的所有事件发送到事件中心中的相同分区公共分区密钥包括用户会话ID和唯一发送方IDs
对我来说,这意味着您不仅限于int
,而且可以使用任何字符串。我错过了什么?回答:
不能将PartitionKey
和PartitionSender
混用-它们是两个相互排斥的概念
不要使用PartitionSender
akaehClient.CreatePartitionSender()
-API,该API设计用于发送到特定分区(在这种情况下,EventHub服务无法再使用PartitionKey
散列到)。
相反,请在c#
中使用此代码段:
我们了解到,对于我们的客户来说,这是一个有点混乱的API,当我们开发Java
SDK时,我们纠正/简化了API,使其看起来像这样:
EventData myEvent = new EventData(message.getBytes(Charset.defaultCharset()))
eventHubClient.SendSync(myEvent, "test1");
事件中心公开的3种发送模式:
当我们开发EventHubs服务时,我们希望为用户提供对其事件流进行分区的多级控制。我们提出了以下3种模式(我们的c
clientapi):
-如果您不想控制数据的分区方式,请使用此选项。EventHubs服务将尝试在所有分区之间统一分发数据(尽最大努力,不提供任何保证)。正如您所做的那样,在对数据分区进行控制方面进行了权衡——您在这里获得的是高可用性。如果您有一个具有32个分区的事件中心,并且正在使用这种发送到事件中心的方法,那么您的事件将被传递到32个事件中心分区中的一个,该分区立即可用,并且数据最少
-当您的数据上有属性时使用此选项-您希望使用该属性对数据进行分区。EventHubs服务将确保所有具有相同分区键的EventData
都将降落在相同的EventHubs分区上。这里-用户通过指定一个提示来控制分区-使用该提示,我们的服务将运行哈希算法并将其传递给哈希分区。具有相同分区键的所有事件都保证落在相同的事件中心分区上
-EventHubPartitionSendername更适合于此-当您想要完全控制数据分区时使用此选项-当您需要控制时-哪个EventData
应该位于哪个EventHub分区上
。当客户拥有他们自己的专有哈希算法时,通常会使用这种算法,他们认为这种算法在他们的场景中性能更好—w.r.to.所有EventHubs分区的负载分配公平性
你需要的是(2)。
如果您不希望使用默认的循环逻辑,并且希望使用自定义逻辑将消息均匀地分发到所有分区,您可以使用类似的方式将消息发送到特定分区Id,在这种情况下,您不应该为eventData分配分区键
您必须找出一个逻辑来获取PartitionId,以便将消息分发到所有分区
String PartitionId = GetPartitionId(message)
EventData eventData = new EventData(Encoding.UTF8.GetBytes(message));
EventHubClient.CreatePartitionedSender(PartitionId).SendAsync(eventData)
private static int GetPartitionId(Message message)
{
// Your own custom logic
var svin = message.vin.Substring(12, 5);
int partKey;
if (int.TryParse(svin, out partKey))
{
partKey = Convert.ToInt32(svin) % NumberOfPartitions;
}
return partKey;
}
或者,您可以为EventData设置分区键,Eventhub会将其分发到不同的分区。但是具有相同分区键的Eventdata将转到相同的分区ID
string payLoadJson = convertToJson(record);
EventData eventData = new
EventData(Encoding.UTF8.GetBytes(payLoadJson));
eventData.PartitionKey = record.vin;
await eventHubClient.SendAsync(eventData);
谢谢你的澄清。我不喜欢它的设置方式,但至少我现在明白了。谢谢你承认@DavidPilkington。同意,理想情况下,我们应该使用像Shardie这样的差异术语,而不是分区。
string payLoadJson = convertToJson(record);
EventData eventData = new
EventData(Encoding.UTF8.GetBytes(payLoadJson));
eventData.PartitionKey = record.vin;
await eventHubClient.SendAsync(eventData);