用于非时间序列数据的德鲁伊

Druid for non time-series data

对于数据在生成后立即发送到 Druid 的情况,一切都很好(如在 IoT 中)。喜欢。

但现在我有不同的情况,源于延迟数据输入。

最终用户可以离线(失去互联网连接),数据存储在她的手机中 phone,并且只有在她重新在线后才会发送给 Druid。

这意味着,当她恢复网络时,发送给 Druid 的数据(例如通过 Tranquility 服务器)将被 Druid 拒绝(因为 Druid 实时不接受过去的数据)。

当然我可以将时间戳设置为数据发送到服务器的时间。但这会扭曲报告...,除非...,如果我添加另一个字段(比方说:generated_ts),并将其声明为另一个维度。

但是我不会从你在 Druid (?) 中免费获得的基于时间的自动汇总中受益。我将不得不使用 groupBy(将 generated_ts 作为维度之一),如下所示:

{
  "queryType": "groupBy",
  "dataSource": "my_datasource",
  "granularity": "none",
  "dimensions": [
    "city",
    {
      "type" : "extraction",
      "dimension" : "generated_ts",
      "outputName" :  "dayOfWeek",
      "extractionFn" : {
        "type" : "timeFormat",
        "format" : "EEEE"
      }
    }
  ],
  ...
}

我的问题是:

  1. 该方法有效吗?
  2. 如果是:惩罚是什么? (我想这会是性能,但有多糟糕?)

谢谢, 拉卡

--

回应下面 Ramkumar 的回复,后续问题:

我还是不太明白这个批量摄取:

假设事件 A。它在时间戳 3 生成,直到时间戳 15 才发送到服务器。

当它在时间戳 15 发送时,它具有以下值:{ts: 15, generated_ts: 3, metric1: 12, dimension1: 'a'}

他们的时间戳键是 "ts"。

不准确,理想情况是 {ts: 3, generated_ts: 3, metric1: 12, dimension1: 'a'},但我必须将 15 指定为 inserted_ts 只是为了让宁静接受它。

现在,在批量摄取期间,我想修复它,现在它有正确的 ts {ts: 3, generated_ts: 3, metric1: 12, dimension1: 'a'}.

问题:那我会有重复事件吗?

或者...(我怀疑):指定时间间隔的批量摄取基本上会替换该时间间隔内的所有数据? (我希望是这样,这样我就可以不用担心数据重复了)

补充说明(刚刚):我遇到了这个:https://github.com/druid-io/tranquility/blob/master/docs/overview.md#segment-granularity-and-window-period

表示:

Our approach at Metamarkets is to send all of our data through Tranquility in real-time, but to also mitigate these risks by storing a copy in S3 and following up with a nightly Hadoop batch indexing job to re-ingest the data. This allow us to guarantee that in the end, every event is represented exactly once in Druid.

所以...这是一个重新摄取,其含义(我猜)是一个完整的替换,对吧?

我们遇到了类似的问题,我们使用 lambda 架构解决了它。我们的设置中有 2 个管道:

  1. 我们的实时流水线从 Kafka+Spark 获取数据并输入到德鲁伊中。这将是实时数据。比德鲁伊期望的粒度更旧的数据将被拒绝。因此,对于延迟数据到达,这会丢失数据。
  2. 我们的批处理管道每小时都会将数据摄取到 Hadoop 中,然后我们触发一个批处理摄取作业到 Druid 中。这将为密钥中提到的时间戳创建段,进行聚合并用相同的时间戳替换旧段。在实践中,druid 的存储原则是基于不变性、MVCC 和日志结构存储。因此,随着新版本的段出现相同的时间戳,旧的段将被垃圾收集。

有关批量摄取的更多详细信息: 我们的批处理作业操作来自 HDFS 的数据,这些数据按小时组织到文件夹中。我们得到的任何迟到事件都会被放入正确的每小时桶中。我们有 XXX 小时延迟数据的 SLA(如果您已阅读 great article,则称为水印)。因此,我们将当前小时减去 XXX 并获取相应的每小时文件夹文件,并在该特定小时触发 druid 上的批量摄取作业。请注意,如果事件在水印之前到达,这仍然​​会导致数据丢失,但我们需要做出妥协,因为德鲁伊不支持在特定小时内对段进行就地更新,而且我们也不能有任意长的水印,因为我们的HDFS 端的存储非常有限。