从 Azure 事件中心获取事件后,是不是应该将它们放入队列中?

Posted

技术标签:

【中文标题】从 Azure 事件中心获取事件后,是不是应该将它们放入队列中?【英文标题】:Should I put my events inside a queue after getting them from Azure Event Hub?从 Azure 事件中心获取事件后,是否应该将它们放入队列中? 【发布时间】:2015-07-07 16:21:35 【问题描述】:

我目前正在开发一个托管在 Azure 上的应用程序,该应用程序使用 Azure 事件中心。基本上我是从 Web API 向事件中心发送消息(或者应该说是事件),并且我有两个侦听器:

用于实时分析的流分析任务 一个标准工作角色,它根据收到的事件计算一些内容,然后将它们存储到 Azure SQL 数据库(这是一个 lambda 架构)。

我目前正在使用EventProcessorHost 库从我的辅助角色内的事件中心检索我的事件。

我正在尝试找到一些关于如何使用事件中心的最佳实践(使用事件中心比使用服务总线队列要困难一些,即流式传输与消息消耗),我发现有些人说 从我的事件中心检索EventData 事件后,我不应该进行大量处理

具体来说:

http://blogs.msdn.com/b/servicebus/archive/2015/01/16/event-processor-host-best-practices-part-1.aspx

请记住,您希望相对保留您正在做的任何事情 快速 - 即不要尝试从这里做很多流程 - 就是这样 消费群体。

http://blogs.msdn.com/b/musings_on_alm_and_software_development_processes/archive/2014/09/03/azure-event-hubs-queues-and-workers.aspx

本文作者在 Event Hub 和 工人角色(从 cmets 不清楚是否真的需要 与否)。

所以问题是:我应该在事件中心之后直接进行所有处理工作(即在我的IEventProcessor 实现的ProcessEventsAsnyc 方法中),还是应该使用事件中心和处理对象之间的队列

任何有关如何正确使用事件中心的事件的建议都将不胜感激,文档目前有点......缺失。

【问题讨论】:

【参考方案1】:

这属于问题类别,一旦 EventProcessorHost 的源可用,其答案将更加明显,我被告知这将会发生。

简短的回答是您不需要使用队列;但是,我会保持 ProcessEventsAsync 返回 Task 的时间相对较短。

虽然这个建议听起来很像first article 的建议,但关键区别在于它是返回任务的时间而不是任务完成的时间。我的假设是 ProcessEventsAsync 在用于 EventProcessorHost 的线程上被调用以用于其他目的。在这种情况下,您需要快速返回,以便其他工作可以继续;这项工作可能正在为另一个分区调用 ProcessEventsAsync(但如果不进行调试,我们不会知道我没有发现有必要这样做或在可用时阅读代码)。

我通过从 ProcessEventsAsync 传递整个 IEnumerable,在每个分区的单独线程上进行处理。这与从 IEnumerable 中取出所有项目并将它们放入队列以供处理线程使用形成对比。另一个线程在完成消息处理后完成由 ProcessEventsAsync 返回的任务。 (实际上,我为我的处理线程提供了一个 IEnumerable,它通过将块链接在一起并在需要时在调用 MoveNext 时完成任务来隐藏 ProcessEventsAsync 的详细信息。

简而言之:在 ProcessEventsAsync 中,将工作移交给另一个线程,无论是你已经在周围的那个你知道如何与 TPL 通信或启动一个新任务的线程。

将所有消息放入 ProcessEventsAsync 内的队列中并不是糟糕,这不是将事件块传递给另一个线程的最有效方式。

如果您决定将事件放入队列中(或在处理代码中有一个下游队列)并完成批处理任务,则应确保限制代码/队列中未完成的项目数以避免在 EventHub 为您提供项目的速度快于您的代码由于流量高峰而无法处理它们的情况下内存不足。

Java EventHub 用户注意事项 2016-10-27: 由于这引起了我的注意,this description 描述了 onEvents 的调用方式,而onEvents 缓慢不会是悲剧,因为它在每个分区的线程上,它的速度似乎会影响速度接收下一批。因此,取决于您对延迟的关心程度,这里的延迟可能对您的方案相对重要。

【讨论】:

谢谢,非常有帮助的答案。作为旁注,我实际上的印象是EventProcessorHost还没有准备好进行生产开发。可用的文档很少或没有,我最近在调用UnregisterEventProcessorAsync 时遇到了NullReferenceException 异常(在多年的.Net 开发过程中,我从未从BCL 得到那种异常(这意味着异常在内部没有得到正确处理)) .无论如何,非常感谢。 这绝对看起来并不完美,公平地说,Kinesis 和 Kafka 高级客户端也不是太完美。

以上是关于从 Azure 事件中心获取事件后,是不是应该将它们放入队列中?的主要内容,如果未能解决你的问题,请参考以下文章

如何捕获来自事件中心的错误 json 记录到 azure 流分析

如何有效地将压缩的 json 数据推送到 azure 事件中心并在 azure 流分析中处理?

Azure 事件中心偏移

Azure Monitor ActivityLogs 未到达事件中心

Azure 事件中心 - 特定分区上的 EventProcessorClient

是否可以将Azure信息保护活动日志流式传输到事件中心?