我可以在使用PartitionSender发送到EventHubs时设置EventData.PartitionKey吗?

时间:2017-02-27 19:14:57

标签: c# azure azure-eventhub

我目前在Azure中设置了一个EventHub实例。它有5个分区。如果PartitionKey始终必须是0n-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.");
    }

这会引发异常

  

指定的分区对于EventHub分区发送方或接收方无效。它应该在0到4之间。

在EventHub的documentation中,这就是他们对PartitionKey的看法:

  

EventData类具有PartitionKey属性,该属性使发件人能够指定经过哈希处理的值以生成分区分配。使用分区键可确保将具有相同密钥的所有事件发送到事件中心中的同一分区。 通用分区键包括用户会话ID和唯一发件人ID

对我而言,这意味着您不仅限于int,还可以使用任何string。我错过了什么?

2 个答案:

答案 0 :(得分:3)

<强>答案

您不能混用PartitionSenderPartitionSender - 它们是2个 互斥的 概念。

不要使用ehClient.CreatePartitionSender()又名PartitionKey - API,它旨在发送到特定分区(在这种情况下,EventHub服务无法使用c# to-hash-to了)。

相反,请在EventData myEvent = new EventData(Encoding.UTF8.GetBytes(message)); myEvent.PartitionKey = "test1"; await eventHubClient.SendAsync(myEvent); 中使用此代码段:

Java

我们了解到这对我们的客户来说有点令人困惑的API,然后当我们执行EventData myEvent = new EventData(message.getBytes(Charset.defaultCharset())) eventHubClient.SendSync(myEvent, "test1"); SDK时,我们更正/简化了我们的API,如下所示:

c#

事件中心公开的3种发送模式:

当我们开发EventHubs服务时 - 我们希望对我们的用户分配他们的事件流提供多级控制。我们提出了以下3种模式(我们的EventData客户端API):

  1. EventHubClient.Send(eventData_Without_PartitionKey) - 当您不希望对数据的分区方式进行任何控制时,请使用此选项。 EventHubs服务将尝试在所有分区上统一分发数据(尽力而为,无保证)。因为,您交易 控制数据分区 - 您获得的是高可用性。如果您有一个具有32个分区的事件中心 - 并且正在使用这种发送到事件中心的方法 - 您的事件将被传递到32个事件中心分区中的一个,该分区可立即使用&amp;关于它的数据最少。

  2. EventHubClient.Send(eventData_With_PartitionKey) - 当您拥有数据属性时使用此功能 - 使用您想要对数据进行分区。 EventHubs服务将确保具有相同PartitionKey的所有EventHubs partition将落在同一PartitionKey上。这里 - 用户通过指定提示来控制分区 - 使用该提示我们的服务将运行哈希算法并传递给哈希分区。所有具有相同Event Hubs partition的活动都保证在同一EventData上着陆。

  3. EventHubSender.Send(eventData_Without_PartitionKey) - EventHubPartitionSender 名称对此更为贴切 - 当您希望完全控制分区数据时使用此名称 - 当您需要控制 - EventHubs partition应该登陆EventHubs partitions。这通常被使用 - 当客户拥有他们自己的专有散列算法时 - 他们认为这些算法在他们的场景中表现更好 - w.r.to.所有$ sudo apt-get install python-pip的负载分配公平性。

  4. 你需要的是(2)。

    here's some general reading on Event Hubs concepts...

答案 1 :(得分:0)

如果您不希望使用默认的循环逻辑,并且希望使用自定义逻辑将消息均匀地分布到所有分区,则可以使用类似的方式将消息发送到特定的分区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会将其分配给不同的分区。但是具有相同分区键的事件数据将进入相同的分区ID

      string payLoadJson = convertToJson(record);
      EventData eventData = new 
      EventData(Encoding.UTF8.GetBytes(payLoadJson));
      eventData.PartitionKey = record.vin;
      
      await eventHubClient.SendAsync(eventData);