【问题标题】:Can I set EventData.PartitionKey while sending to EventHubs using a PartitionSender?我可以在使用 PartitionSender 发送到 EventHubs 时设置 EventData.PartitionKey 吗?
【发布时间】:2017-02-27 19:14:57
【问题描述】:

我目前在 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。我错过了什么?

【问题讨论】:

    标签: c# azure azure-eventhub


    【解决方案1】:

    回答

    您不能混合使用 PartitionKeyPartitionSender - 它们是 2 个互斥概念。

    不要使用 PartitionSender aka ehClient.CreatePartitionSender() - API,它旨在发送到特定分区(在这种情况下,EventHub 服务不能再使用 PartitionKey to-hash-to)。

    c# 中使用此代码sn-p:

    EventData myEvent = new EventData(Encoding.UTF8.GetBytes(message));
    myEvent.PartitionKey = "test1";
    await eventHubClient.SendAsync(myEvent);
    

    我们了解到,对于我们的客户来说,这有点令人困惑,然后当我们开发 Java SDK 时,我们更正/简化了我们的 API,使其看起来像这样:

    EventData myEvent = new EventData(message.getBytes(Charset.defaultCharset()))
    eventHubClient.SendSync(myEvent, "test1");
    

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

    当我们开发 EventHubs 服务时——我们希望为我们的用户提供对事件流进行分区的多层次控制。我们提出了以下 3 种模式(我们的 c# 客户端 API):

    1. EventHubClient.Send(eventData_Without_PartitionKey) - 当您不想控制数据的分区方式时使用此选项。 EventHubs 服务将尝试在所有分区中均匀分布数据(尽力而为,不保证)。因为,您权衡拥有对数据分区的控制权 - 您在这里获得的是高可用性。如果您有一个包含 32 个分区的事件中心 - 并且正在使用这种发送到事件中心的方法 - 您的事件将被传送到 32 个事件中心分区之一,该分区立即可用且数据最少。

    2. EventHubClient.Send(eventData_With_PartitionKey) - 当您的数据具有属性时使用此属性 - 您希望使用该属性对数据进行分区。 EventHubs 服务将确保所有具有相同PartitionKeyEventDatas 将登陆相同的EventHubs partition。在这里 - 用户通过指定一个提示来控制分区 - 我们的服务将使用它来运行哈希算法并传递到哈希分区。具有相同PartitionKey 的所有事件都保证登陆相同的Event Hubs partition

    3. EventHubSender.Send(eventData_Without_PartitionKey) - EventHubPartitionSender 这个名字更适合这个 - 当你想要完全控制数据分区时使用这个 - 当你需要控制时on - EventData 应该落在哪个 EventHubs partition 上。这通常用于 - 当客户拥有自己的专有哈希算法时 - 他们认为在他们的场景中表现更好 - w.r.to.所有EventHubs partitions 的负载分配的公平性。

    你需要的是(2)。

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

    【讨论】:

    • 感谢您的澄清。我不喜欢它的设置方式,但至少我现在明白了。
    • 感谢您对@DavidPilkington 的认可。同意,理想情况下我们应该使用差异。像 shardId 而不是 partitionId 之类的术语。
    【解决方案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 设置 Partition key,Eventhub 会将其分发到不同的 Partition。但是具有相同Parition key的Eventdata会去相同的Partition ID

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-03
      • 2018-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多