代码之家  ›  专栏  ›  技术社区  ›  Zorik

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

  •  5
  • Zorik  · 技术社区  · 8 年前

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

    稍后,另一个云服务下载blob并对事件运行一些检测逻辑。他按MachineId对事件进行分组,并试图从机器时间轴中取消理解某些内容

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

    我们确实会将事件写入另一个Map reduce系统,在那里我们会进行非常复杂的检测,但这些检测当然具有很高的延迟。如果我能在云中更好地分组事件,我就能实时捕获更多

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

    提前感谢

    1 回复  |  直到 7 年前
        1
  •  6
  •   Sreeram Garlapati    8 年前

    tl;博士: 在原始EventHub和blob存储之间引入另一个EventHub是最好的方式,它可以根据MachineID重新划分数据。

    一般来说,有一个INJESTING EVENTHUB,它只是监控系统的入口点。使用 EventHubClient.send(eventData_without_partitionKey) 发送到此的方法 INJESTING EVENTHUB . 这将允许您以极低的延迟和高可用性进行发送,因为它将发送到当前负载较少且可用的分区。。

     --------------                     -----------                 ----------
    |              |    =========      |           |    ====       |          |
    |  INJESTING   |    RE-PARTITION > |  INTERIM  |    BLOB \     |   BLOB   |
    |  EVENTHUB    |    =========      |  EVENTHUB |    PUMP /     |          |
    |              |                   |           |    ====        ----------
     --------------                     -----------
    

    最重要的是,不要直接在 摄取EventHub ,对于这些因素:

    1. 高可用摄取管道-不将事件关联到分区-将保持摄取管道的高可用性。在幕后,我们为您的 EventHubs Partition 在上 Container . 当您提供 PartitionKey 在您的 EventData -那个 分区键 将散列到特定分区。现在 Send 操作延迟将与单个 Partition 的可用性-windows操作系统升级或我们的服务升级等事件可能会影响它们。相反,如果你坚持 EventHubClient.send(without_PartitionKey) -我们将路由 事件数据 尽快到达可用分区-因此,保证您的摄取管道 Highly available .
    2. 灵活的数据设计—在分布式系统中,您很快就会需要基于不同的密钥重新划分数据。请确保-在您的系统中测量此的概率:)。

    使用 临时事件中心 作为对数据进行分区的一种方式。i、 e.,在 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"))
    }
    

    这确保了什么?就这些吗 事件数据 具有特定的 MachineID 在上可用 1 and 1 - EventHubs Partition . 您不需要创建1M EventHubs分区 . 每个分区可以容纳无限多个 分区键 s、 你可以使用 EventProcessorHost 托管此每个分区逻辑或 Azure Stream analytics Job .

    此外,这也是您筛选和生成最佳流的机会,这是下游处理管道可以使用的。

    在 BLOB泵 模块(您的下游处理管道)—当您使用特定 临时事件中心 的 隔断 -现在保证您拥有所有 Events 来自 具体的 machineid-在此分区上。按所需大小聚合事件- 2k -基于分区ID(machineId)-您不会连续拥有所有事件-您需要为此构建内存中的聚合逻辑(使用 事件处理器主机 或 AzureStreamAnalytics Job .