我有一个特别简单的数据流管道,我想在其中读取文件并将其解析的记录输出到Avro。在大多数情况下,这是可行的,除非源文件特别大(超过20 GB),即使使用特别大的内存计算机,这也会导致我进行OOM。我很确定会发生这种情况,因为Beam会完整读取不可拆分的源,因此我实现了可拆分的DoFn
此功能性的工作方式是:管道现在成功了,这似乎证实了我的假设,即不可拆分文件中的单个大批处理是原因。但是,这似乎并未将工作分散到多个工作人员中。我尝试了以下方法:
有什么想法吗?由于公司政策的原因,确切的代码很难共享,但是总体来说很简单。我实现了以下内容:
public class SplittableReadFn extends DoFn<FileIO.ReadableFile, GenericRecord> {
// ...
@ProcessElement
public void process(final ProcessContext c, final OffsetRangeTracker tracker) {
final FileIO.ReadableFile file = c.element();
// Followed by something like
ReadableByteStream in = file.open()
in.seek(tracker.from())
Parser parser = new Parser(in)
while (parser.next()) {
if (parser.getOffset() > tracker.to()) {
break
}
tracker.tryClaim(parser.getOffset())
c.output(parser.item())
}
tracker.markDone()
}
@GetInitialRestriction
public OffsetRange getInitialRestriction(final FileIO.ReadableFile file) {
return new Offset(0, getSize(file) - 1);
}
@SplitRestriction
public void splitRestriction(final FileIO.ReadableFile file, final OffsetRange restriction, final DoFn.OutputReceiver<OffsetRange> receiver) {
// chunkRange for test purposes just breaks into at most 500MB chunks
for (final OffsetRange chunk: chunkRange(restriction)) {
receiver.output(chunk);
}
}