我的管道:Kafka - >数据流流(Beam v2.3) - >大量查询
鉴于低延迟在我的情况下并不重要,我使用FILE_LOADS来降低成本,如下所示:
BigQueryIO.writeTableRows()
.withJsonSchema(schema)
.withWriteDisposition(WriteDisposition.WRITE_APPEND)
.withCreateDisposition(CreateDisposition.CREATE_IF_NEEDED)
.withMethod(Method.FILE_LOADS)
.withTriggeringFrequency(triggeringFrequency)
.withCustomGcsTempLocation(gcsTempLocation)
.withNumFileShards(numFileShards)
.withoutValidation()
.to(new SerializableFunction[ValueInSingleWindow[TableRow], TableDestination]() {
def apply(element: ValueInSingleWindow[TableRow]): TableDestination = {
...
}
}
此数据流步骤在管道中引入了一个总是更大的延迟,因此它无法跟上Kafka吞吐量(小于50k事件/秒),即使有40 n1-standard-s4
个工作人员也是如此。如下面的屏幕截图所示,此步骤的系统滞后非常大(接近管道正常运行时间),而Kafka系统滞后只有几秒钟。
如果我理解正确,Dataflow会将这些元素写入 gcsTempLocation 中的 numFileShards ,并且每个 triggeringFrequency 都会启动一个加载作业,将它们插入到BigQuery中。例如,如果我选择5分钟的 triggeringFrequency ,我可以看到(使用bq ls -a -j
)所有加载作业需要不到1分钟才能完成。但仍然是这一步骤引入了越来越多的延迟,导致Kafka消耗越来越少的元素(由于bcackpressure)。增加/减少 numFileShards 和 triggeringFrequency 并不能解决问题。
我没有手动指定任何窗口,我只是默认窗口。文件不会在 gcsTempLocation 中累积。
知道这里出了什么问题吗?
答案 0 :(得分:1)
您提到您没有明确指定一个窗口,这意味着默认情况下,Dataflow将使用"全局窗口"。 windowing documentation包含此警告:
警告:数据流的默认窗口行为是分配全部 PCollection的元素到单个全局窗口,甚至是 无界的PCollections。在使用分组转换之前,例如 GroupByKey在无界PCollection上,你必须设置一个非全局的 开窗功能。请参阅设置PCollection的窗口函数。
如果您没有为无界限设置非全局窗口功能 PCollection并随后使用分组变换,如 GroupByKey或Combine,您的管道将生成错误 构造和数据流作业将失败。
您也可以为PCollection设置非默认触发器 允许全局窗口早期发出"其他一些结果 条件。
您的管道似乎没有进行任何显式分组,但我想知道通过BigQuery写入内部分组是否会导致问题。
您是否可以在界面中看到您的下游DropInputs
是否收到了任何元素?如果没有,这表明数据在上游BigQuery步骤中被阻止。