数据流可拆分ReadFn不使用多个工作程序

时间:2018-09-23 17:32:50

标签: google-cloud-dataflow apache-beam

我有一个特别简单的数据流管道,我想在其中读取文件并将其解析的记录输出到Avro。在大多数情况下,这是可行的,除非源文件特别大(超过20 GB),即使使用特别大的内存计算机,这也会导致我进行OOM。我很确定会发生这种情况,因为Beam会完整读取不可拆分的源,因此我实现了可拆分的DoFn

功能性的工作方式是:管道现在成功了,这似乎证实了我的假设,即不可拆分文件中的单个大批处理是原因。但是,这似乎并未将工作分散到多个工作人员中。我尝试了以下方法:

  1. 禁用自动缩放(autoscalingAlgorithm = NONE)并将numWorkers设置为10。这具有与numWorkers 1相同的吞吐量。
  2. 具有最高maxWorkers的左侧自动缩放功能。暂时上升到2,然后又下降到1
  3. 在DoFn之后但在Avro写入之前添加了一个shuffle(Reshuffle.viaRandomKey)

有什么想法吗?由于公司政策的原因,确切的代码很难共享,但是总体来说很简单。我实现了以下内容:

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);
    }
}

0 个答案:

没有答案