同步来自多个数据源的数据

Synchronize Data From Multiple Data Sources

我们的团队正在尝试构建一个预测性维护系统,其任务是查看一组事件并预测这些事件是否描述了一组已知异常。

我们正处于设计阶段,目前系统设计如下:

问题:

为了将一组事件归类为异常,这些事件必须同时发生 window。例如假设有3个数据源将各自的事件推送到kafka topic中,但是由于某些原因,数据不同步。 因此,其中一个推理引擎从每个 kafka 主题中提取最新条目,但提取数据中的相应事件不属于同一时间 window(比如 1 小时)。由于数据不同步,这将导致无效预测。

问题

我们需要弄清楚如何才能确保按顺序推送所有三个来源的数据,以便当推理引擎从多个 kakfa 主题请求条目(比如最后 100 个条目)时,相应的条目每个主题属于同一时间 window?

一些建议 -

  1. 生产者端处理延迟 - 使用 batch.sizelinger.ms 确保所有三个生产者始终将数据同步发送到 Kafka 主题。 例如。如果 linger.ms 设置为 1000,所有消息将在 1 秒内发送到 Kafka。

  2. 消费端处理延迟- 考虑到消费者端的任何流媒体引擎(Kafka-stream、spark-stream、Flink),提供 windows 功能以 join/aggregate 基于键的流数据,同时考虑延迟 window函数。

检查这个 - Flink windows 参考如何选择正确的 window 类型 link

要处理这种情况,数据源必须提供某种机制让消费者意识到所有相关数据都已到达。最简单的解决方案是使用某种形式的批次 ID (Guid) 从数据源发布批次。然后,消费者可以等到下一个批次 ID 出现,标志着上一个批次的结束。这种方法假定来源不会跳过批次,否则它们将永久获得 mis-aligned。没有算法可以检测到这一点,但您可能在数据中有一些字段显示不连续性并允许您重新对齐数据。

此方法的较弱版本是等待 x-seconds 并假设所有源在这么长的时间内都成功,或者查看某种形式的时间戳(逻辑或挂钟)以检测源已继续下一次 window 隐式显示最后一次 window 的完成。

我建议 KSQL,它是一个流式 SQL 引擎,可以针对 Apache Kafka 启用 real-time 数据处理。它还为 Windowed Aggregation 等提供了很好的功能。

在KSQL中定义Windows有3种方式:

hopping windows, tumbling windows, and session windows. Hopping and tumbling windows are time windows, because they're defined by fixed durations they you specify. Session windows are dynamically sized based on incoming data and defined by periods of activity separated by gaps of inactivity.

在您的上下文中,您可以使用 KSQL 来查询和聚合使用 Windowed Joins 的感兴趣的主题。例如,

SELECT t1.id, ...
  FROM topic_1 t1
  INNER JOIN topic_2 t2
    WITHIN 1 HOURS
    ON t1.id = t2.id;

以下建议应最大限度地提高事件同步的成功率,以解决使用时间序列数据的异常检测问题。

  1. 在所有 producer/consumer 个节点上使用网络时间同步器
  2. 每 x 个时间单位使用来自生产者的心跳消息,并具有固定的开始时间。例如:消息每两分钟在一分钟开始发送。
  3. 为生产者消息延迟构建预测器。使用心跳消息来计算。

有了这些原语,我们应该能够对齐时间序列事件,解决由于网络延迟引起的时间漂移​​。

在推理引擎端,在每个生产者级别扩展您的 windows 以在生产者之间同步事件。