我正在尝试将IngestionTime(_PARTITIONTIME)迁移到BQ中的TIMESTAMP分区表。为此,我还需要添加一些必填列。但是,当我翻转开关并将数据流重定向到新的TIMESTAMP分区表时,它中断了。注意事项:
我已经调查了几天,并试图将过渡过程分解为最小的步骤。似乎导致该错误的步骤是引入了REQUIRED变量(当相同的变量为NULLABLE时,它工作正常)。为了避免任何可能的解析错误,我为所有必需的变量设置了默认值。
目前,我收到以下错误组合,但不确定如何解决其中的任何错误:
第一个错误很少重复出现,但通常以组的形式重复出现:
找不到配置文件代理。个人资料将不可用 工人
发生很多且成群结队:
无法验证BoundedSource类型的序列化元素是否具有定义良好的equals方法。这可能会在某些PipelineRunner上产生不正确的结果
似乎是其中一个很大的群体:
中止操作。 java.lang.RuntimeException:无法从状态读取值
最后,此错误每5分钟出现一次,仅在下面所述的轻微解析错误周围。
处理停留在步骤BigQueryIO.Write / BatchLoads / SinglePartitionWriteTables / ParMultiDo(WriteTables)至少20m00,而没有在状态完成时输出或完成
由于我的项目解析的数据量巨大,因此存在一些解析错误,例如意外字符。它们很少见,但不应破坏数据插入。如果是这样,我会遇到更大的问题,因为我收集的数据经常更改,并且只有在看到错误之后才能调整解析器,因此,请参见新的数据格式。此外,这不会导致摄取时间表中断(或其他时间戳分区表中断)。话虽如此,这是一个解析错误的示例:
错误:意外字符(','(代码44)):期望双引号开头字段名称
编辑: 一些相关的示例代码:
public PipelineResult streamData() {
try {
GenericSection generic = new GenericSection(options.getBQProject(), options.getBQDataset(), options.getBQTable());
Pipeline pipeline = Pipeline.create(options);
pipeline.apply("Read PubSub Events", PubsubIO.readMessagesWithAttributes().fromSubscription(options.getInputSubscription()))
.apply(options.getWindowDuration() + " Windowing", generic.getWindowDuration(options.getWindowDuration()))
.apply(generic.getPubsubToString())
.apply(ParDo.of(new CrowdStrikeFunctions.RowBuilder()))
.apply(new BigQueryBuilder().setBQDest(generic.getBQDest())
.setStreaming(options.getStreamingUpload())
.setTriggeringFrequency(options.getTriggeringFrequency())
.build());
return pipeline.run();
}
catch (Exception e) {
LOG.error(e.getMessage(), e);
return null;
}
写信给BQ。我确实尝试直接在此处设置partitoning字段,但它似乎没有任何影响:
BigQueryIO.writeTableRows()
.to(BQDest)
.withMethod(Method.FILE_LOADS)
.withNumFileShards(1000)
.withTriggeringFrequency(this.triggeringFrequency)
.withTimePartitioning(new TimePartitioning().setType("DAY"))
.withWriteDisposition(BigQueryIO.Write.WriteDisposition.WRITE_APPEND)
.withCreateDisposition(BigQueryIO.Write.CreateDisposition.CREATE_NEVER);
}
答案 0 :(得分:0)
经过大量挖掘,我发现了错误。我有一个解析逻辑(一个try / catch),在发生解析错误的情况下不返回任何内容(本质上是一个空行)。这将破坏BigQuery,因为我的架构有多个REQUIRED行。
由于我的作业是成批运行的,因此即使是空行也将导致整个批处理作业失败并且不插入任何内容。这也解释了为什么插入流就可以了。令我感到惊讶的是,BigQuery没有抛出错误,声称我正在尝试将null插入必填字段。
在得出这个结论时,我还意识到,与在模式中相反,在代码中设置分区字段也是必要的。可以使用
.setField(partitionField)