高吞吐量发送到EventHubs导致MessagingException/TimeoutException/Server无法处理请求错误

Jos*_*rra 5 azure azureservicebus azure-eventhub

我们遇到了很多这些异常,在高峰流量期间向EventHubs发送事件:

"无法将事件发送到EventHub.例外:Microsoft.ServiceBus.Messaging.MessagingException:服务器无法处理请求;请重试该操作.如果问题仍然存在,请联系您的Service Bus管理员并提供跟踪ID." 或"无法将事件发送到EventHub.例外:System.TimeoutException:操作未在分配的时间内完成"

你可以在这里清楚地看到它:

Azure Portal EH

正如您所看到的,当传入的消息超过400K事件/小时(或~270 MB /小时)时,我们得到了许多内部错误,服务器忙错误,失败请求.这不仅仅是一个短暂的问题.这显然与吞吐量有关.

我们的EH有32个分区,7天的消息保留和5个吞吐量单位.OperationTimeout设置为5分钟,我们使用默认的RetryPolicy.

我们还需要在这里调整一下吗?我们真的很关心EH的可扩展性.

谢谢

Sre*_*ati 6

使用有效的分区分发策略可以实现发送吞吐量调整.没有任何一个旋钮可以做到这一点.以下是您为高吞吐量方案设计所需的基本信息.

1)让我们从命名空间开始:在命名空间级别配置吞吐量单位(也称为TU).PLS.请记住,应用已配置的TU - 该命名空间下所有EventHub的聚合.如果你的命名空间有5个TU,下面有5个eventhub,它将在所有5个eventhub中分配.

2)现在让我们看看EventHub级别:如果EventHub分配了5个TU并且它有32个分区 - 没有一个分区可以使用所有5个TU.对于前者 如果您尝试将5TU数据发送到1个分区,并将"零"发送到所有其他31个分区 - 这是不可能的.每个分区应该计划的最大值是1 TU.通常,您需要确保数据在所有分区中均匀分布.EventHubs支持3种类型的发送 - 这为用户提供了对分区分发的不同控制级别:

  1. EventHubClient.Send(EventDataWithoutPartitionKey) - >如果您使用此API发送 - eventhub将负责在所有分区之间均匀分布数据.EventHubs服务网关将数据循环到所有分区.当特定分区关闭时 - 网关会自动检测并确保客户端看不到任何影响.这是发送到EventHubs的最佳推荐方式.
  2. EventHubClient.Send(EventDataWithPartitionKey) - >如果您使用此API发送到EventHubs - partitionKey将确定您的数据分布.PartitionKey用于将EventData散列到适当的分区(算法,哈希是Microsoft专有而非共享).通常,需要关联一组消息的用户将使用此发送变体.
  3. EventHubSender.Send(EventData) - >在此变体中,发件人已附加到分区.因此 - 这可以完全控制跨分区到客户端的分配.

要测量您当前的数据分布 - 使用EventHubClient.GetPartitionRuntimeInfo Api估计哪个分区过载.差的B/W BeginSequenceNumberLastEnqueuedSequenceNumber应该得到比其他人的分区负载的估计.

3)最后但并非最不重要 - 您可以使用SendBatch API在发送操作级别调整性能(而不是吞吐量).1 TU可以购买1000 msgs/sec或1MBPS的最大值 - 您将受到限制,无论首先达到哪个限制 - 这都无法更改.如果您的消息很小 - 假设100个字节,您只能发送1000个消息/秒(根据TU限制) - 您将首先达到1000个事件/秒限制.但是,整体上使用SendBatch API - 您可以批量称为10个100byte msgs并以相同的速率推送 - 仅仅100个API调用,只需100个API调用,并改善系统的端到端延迟(因为它也有助于服务)有效地保持消息).请记住,这里唯一的限制是Max.可以发送的消息大小 - 256 kb(如果使用SendBatch API,此限制将适用于BatchSize).

鉴于背景,在您的情况下: - 有32个分区和5个TU - 我真的会仔细检查分区分发策略.

HTH!SREE