最佳实践:对eventhub数据进行分区&通过azure eventhubs到外部存储(azure blobs)实现高规模,低延迟和高吞吐量

时间:2018-01-20 10:34:51

标签: azure azure-eventhub azure-blob-storage data-partitioning

作为安全产品的一部分,我有高级云服务(天蓝色工作者角色),它从事件中心读取事件,将它们批量处理到~2000并存储在blob存储中。 每个事件都有一个MachineId(发送它的机器)。 事件以随机顺序来自事件中心,我将它们以随机顺序存储在blob存储中。 吞吐量高达125K事件/秒,每个事件大约2K,因此我们的流量高达250MB /秒。 我们有~100台机器......

稍后,另一个云服务下载blob并在事件上运行一些检测逻辑。他通过MachineId对事件进行分组,并尝试从机器时间线

中取消某些东西

问题是今天来自同一台机器的事件被填充到不同的blob中。如果我可以通过MachineId以某种方式对事件进行分组,并确保将机器的某个时间窗口填充到同一个blob中,这将增加我在云中可以执行的检测。

我们确实将事件写入另一个Map reduce系统,并且我们正在做很多复杂的检测,但那些当然具有高延迟。如果我能够在云中更好地对事件进行分组,我可以实时捕获更多信息

我有什么技术可以帮助我吗?

提前致谢

1 个答案:

答案 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 上对数据进行分区:

  1. 高度可用的摄取管道 - 不将事件与分区相关联 - 将使您的摄取管道保持高可用性。在幕后,我们会在EventHubs Partition上托管您的每个Container。当您在PartitionKey上提供EventData时,PartitionKey将被哈希到特定分区。现在,Send操作延迟将与单个Partition的可用性相关联 - 诸如Windows操作系统升级或我们的服务升级等事件可能会影响它们。相反,如果您坚持EventHubClient.send(without_PartitionKey) - 我们会尽快将EventData路由到可用分区 - 因此,您的提取管道将保证为Highly available
  2. 灵活的数据设计 - 在分布式系统中,您很快就会需要根据不同的密钥重新分区数据。请务必 - 测量系统中的概率:)。
  3. 使用 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