Могу ли я установить EventData.PartitionKey при отправке в EventHubs с помощью PartitionSender?

В настоящее время у меня настроен экземпляр EventHub в Azure. Имеет 5 перегородок. Что я хочу знать, если 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.");
    }

Это вызывает исключение

Указанный раздел недействителен для отправителя или получателя раздела EventHub. Оно должно быть от 0 до 4.

В документации EventHub, вот что они говорят о PartitionKey:

Класс EventData имеет свойство PartitionKey, которое позволяет отправителю указать значение, которое хешируется для создания назначения раздела. Использование ключа раздела гарантирует, что все события с одним и тем же ключом будут отправлены в один и тот же раздел в концентраторе событий. Общие ключи разделов включают идентификаторы сеанса пользователя и уникальный идентификатор отправителя.

Для меня это означает, что вы не ограничены int, но можете использовать любой string. Что мне не хватает?


person David Pilkington    schedule 27.02.2017    source источник


Ответы (2)


Если вам не нужна логика циклического перебора по умолчанию и вы хотите равномерно распределить сообщение по всем разделам, используя собственную логику, вы можете использовать аналогичный способ отправки сообщения на конкретный идентификатор раздела, вы не должны назначать ключ раздела для 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 распределяет его по разным разделам. Но данные о событиях с тем же ключом раздела перейдут к тому же идентификатору раздела.

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

person    schedule
comment
Спасибо за разъяснения. Мне не нравится, как это устроено, но, по крайней мере, теперь я понимаю. - person David Pilkington; 04.03.2017
comment
Спасибо за благодарность @DavidPilkington. Согласен, в идеале мы должны были использовать diff. термин вроде shardId вместо partitionId. - person Sreeram Garlapati; 06.03.2017