作为安全产品的一部分,我有高级云服务(天蓝色工作者角色),它从事件中心读取事件,将它们批量处理到~2000并存储在blob存储中。 每个事件都有一个MachineId(发送它的机器)。 事件以随机顺序来自事件中心,我将它们以随机顺序存储在blob存储中。 吞吐量高达125K事件/秒,每个事件大约2K,因此我们的流量高达250MB /秒。 我们有~100台机器......
稍后,另一个云服务下载blob并在事件上运行一些检测逻辑。他通过MachineId对事件进行分组,并尝试从机器时间线
中取消某些东西问题是今天来自同一台机器的事件被填充到不同的blob中。如果我可以通过MachineId以某种方式对事件进行分组,并确保将机器的某个时间窗口填充到同一个blob中,这将增加我在云中可以执行的检测。
我们确实将事件写入另一个Map reduce系统,并且我们正在做很多复杂的检测,但那些当然具有高延迟。如果我能够在云中更好地对事件进行分组,我可以实时捕获更多信息
我有什么技术可以帮助我吗?
提前致谢
答案 0 :(得分:1)
<强> TL; DR:强> 引入另一个EventHub - 在原始eventhub和blob存储之间 - 每个MachineID重新分区数据 - 是最好的方法。
一般来说,有一个INJESTING EVENTHUB - 这只是监控系统的入口点。使用EventHubClient.send(eventData_without_partitionKey)
方法发送至此INJESTING EVENTHUB
。这将允许您以非常低的延迟和高可用性发送 - 因为它将发送到当前正在减少负载且可用的分区。
-------------- ----------- ----------
| | ========= | | ==== | |
| INJESTING | RE-PARTITION > | INTERIM | BLOB \ | BLOB |
| EVENTHUB | ========= | EVENTHUB | PUMP / | |
| | | | ==== ----------
-------------- -----------
最重要的是,对于以下因素,请不要直接在 Ingesting EventHub 上对数据进行分区:
EventHubs Partition
上托管您的每个Container
。当您在PartitionKey
上提供EventData
时,PartitionKey
将被哈希到特定分区。现在,Send
操作延迟将与单个Partition
的可用性相关联 - 诸如Windows操作系统升级或我们的服务升级等事件可能会影响它们。相反,如果您坚持EventHubClient.send(without_PartitionKey)
- 我们会尽快将EventData
路由到可用分区 - 因此,您的提取管道将保证为Highly available
。
使用 Interim EventHubs 作为分区数据的方法。即,在RE-PARTITION
模块中 - 您只是将原始流重播为INTERIM EVENTHUB
,方法是将一个属性交换为EventData.PARTITION_KEY
- 原来是空的。
// pseudo-code RE-PARTITION EVENTS
foreach(eventData receivedFromIngestingEventHubs)
{
var newEventData = clone(eventData);
eventHubClient.send(newEventData, eventData.Properties.get("machineId"))
}
这确保了 - 所有EventData
具有特定MachineID
的{{1}}可用1 and 1 - EventHubs Partition
。 您无需创建1M EventHubs分区。每个分区可以容纳无限数量的PartitionKey
s。您可以使用EventProcessorHost
来托管每个分区逻辑或Azure Stream analytics Job
。
此外,这是您过滤和生成最佳流的机会 - 可由下游处理管道使用。
在 BLOB PUMP 模块(您的下游处理管道)中 - 当您使用来自特定 INTERIM EVENTHUB 的Partition
的事件时 - 您现在可以保证在此分区上拥有来自特定 machineid的所有Events
。根据您所需的大小聚合事件 - 2k
- 基于PartitionId(machineId) - 您将不会持续所有事件 - 您将需要为此构建内存中聚合逻辑(使用{{1} }或AzureStreamAnalytics Job
。