Azure 事件中心 - 每个事件的检查点?
Azure Event Hubs - Checkpoint per event?
鉴于我有 3 个消费者用于单个集线器,所有消费者都消费同一个消费者组,假设客户端 A 获得了事件 1,客户端 B 获得了事件 2,客户端 C 获得了事件 3。
机缘巧合,最后获得事件(事件3)的客户C居然是第一个完成任务的UpdatedCheckpointAsync.
这是否意味着即使客户端 A 和 B 未能完成他们的工作,并且不更新检查点,他们的事件也不再可用?
编辑 1:
我设置了以下实验:
- 创建了一个包含 10 个分区的 azure 事件中心
- 创建了一个消费者组
- 填充了 10k 条消息
- 创建了 2 个容器(在 AKS 上),它们基本上会使用这些事件(使用相同的消费者组)并将它们记录在 azure application insights
期望:
运行
traces
| where message == "Event received"
| summarize count() by bin(timestamp,1s), cloud_RoleInstance
| render timechart
然后看到类似的东西
(请注意pods如何同时发布日志,表明它们正在接收和处理事件)
但我看到的是:
这让我相信一台机器闲置而另一台机器正在做所有的工作!
编辑 2
这里有 3 个 10k 项 运行,间隔很小:
这里使用了一些可能令人困惑的术语,因此我将对场景做出我最好的猜测。如果我误解了,请纠正我:
您正在使用 EventProcessorClient
的 3 个实例,配置为从同一个事件中心读取并且属于同一个使用者组。
短语“3 个消费者”是指那些处理者;场景中没有 EventHubConsumerClient
个实例。
Client A
、Client B
和Client C
指的是那些EventProcessorClient
实例;这些不是处理器委托给的外部客户端。
假设我的解释是正确的,那么需要注意的重要一点是事件中心的每个分区将由一个且仅一个事件处理器拥有。
在正常操作期间,如果 Client A
读取事件 1,Client B
读取事件 2,并且 Client C
读取事件 3,那么这些事件中的每一个都来自不同的分区。检查点也限定在一个分区内,因此 A
、B
和 C
不会相互覆盖 - 每个检查点都针对该分区独有的检查点。
但是,有几点需要注意:
多个处理器为同一分区发出事件时,可能会出现短暂的重叠。当处理器数量扩展 up/down 和分区所有权转换时,就会发生这种情况。在此 window 期间(通常为 30 秒或更短时间),可以用较早的位置覆盖检查点 - 但回滚将限于您的应用程序在此期间处理的事件数。
如果处理器的事件处理程序不执行异常处理并抛出,则处理器不会倒回检查点;当分区处理任务重启时,它会依次读取下一个事件。 (这是为了避免中毒事件阻碍前进进程)
我强烈建议您查看
docs
对于处理器事件处理程序,如果您还没有这样做的话。
鉴于我有 3 个消费者用于单个集线器,所有消费者都消费同一个消费者组,假设客户端 A 获得了事件 1,客户端 B 获得了事件 2,客户端 C 获得了事件 3。
机缘巧合,最后获得事件(事件3)的客户C居然是第一个完成任务的UpdatedCheckpointAsync.
这是否意味着即使客户端 A 和 B 未能完成他们的工作,并且不更新检查点,他们的事件也不再可用?
编辑 1:
我设置了以下实验:
- 创建了一个包含 10 个分区的 azure 事件中心
- 创建了一个消费者组
- 填充了 10k 条消息
- 创建了 2 个容器(在 AKS 上),它们基本上会使用这些事件(使用相同的消费者组)并将它们记录在 azure application insights
期望:
运行
traces
| where message == "Event received"
| summarize count() by bin(timestamp,1s), cloud_RoleInstance
| render timechart
然后看到类似的东西
(请注意pods如何同时发布日志,表明它们正在接收和处理事件)
但我看到的是:
这让我相信一台机器闲置而另一台机器正在做所有的工作!
编辑 2
这里有 3 个 10k 项 运行,间隔很小:
这里使用了一些可能令人困惑的术语,因此我将对场景做出我最好的猜测。如果我误解了,请纠正我:
您正在使用
EventProcessorClient
的 3 个实例,配置为从同一个事件中心读取并且属于同一个使用者组。短语“3 个消费者”是指那些处理者;场景中没有
EventHubConsumerClient
个实例。Client A
、Client B
和Client C
指的是那些EventProcessorClient
实例;这些不是处理器委托给的外部客户端。
假设我的解释是正确的,那么需要注意的重要一点是事件中心的每个分区将由一个且仅一个事件处理器拥有。
在正常操作期间,如果 Client A
读取事件 1,Client B
读取事件 2,并且 Client C
读取事件 3,那么这些事件中的每一个都来自不同的分区。检查点也限定在一个分区内,因此 A
、B
和 C
不会相互覆盖 - 每个检查点都针对该分区独有的检查点。
但是,有几点需要注意:
多个处理器为同一分区发出事件时,可能会出现短暂的重叠。当处理器数量扩展 up/down 和分区所有权转换时,就会发生这种情况。在此 window 期间(通常为 30 秒或更短时间),可以用较早的位置覆盖检查点 - 但回滚将限于您的应用程序在此期间处理的事件数。
如果处理器的事件处理程序不执行异常处理并抛出,则处理器不会倒回检查点;当分区处理任务重启时,它会依次读取下一个事件。 (这是为了避免中毒事件阻碍前进进程)
我强烈建议您查看 docs 对于处理器事件处理程序,如果您还没有这样做的话。