我假设您正在阅读这样的大查询:
count = (p | 'read' >> beam.io.Read(beam.io.BigQuerySource(known_args.input_table))
我对 apache_beam 源代码进行了一些研究,看起来他们的 Source 转换忽略了输入 pcollection,这就是他们并行设置的原因。
查看def expand(self, pbegin):的最后一行:
class Read(ptransform.PTransform):
"""A transform that reads a PCollection."""
def __init__(self, source):
"""Initializes a Read transform.
Args:
source: Data source to read from.
"""
super(Read, self).__init__()
self.source = source
def expand(self, pbegin):
from apache_beam.options.pipeline_options import DebugOptions
from apache_beam.transforms import util
assert isinstance(pbegin, pvalue.PBegin)
self.pipeline = pbegin.pipeline
debug_options = self.pipeline._options.view_as(DebugOptions)
if debug_options.experiments and 'beam_fn_api' in debug_options.experiments:
source = self.source
def split_source(unused_impulse):
total_size = source.estimate_size()
if total_size:
# 1MB = 1 shard, 1GB = 32 shards, 1TB = 1000 shards, 1PB = 32k shards
chunk_size = max(1 << 20, 1000 * int(math.sqrt(total_size)))
else:
chunk_size = 64 << 20 # 64mb
return source.split(chunk_size)
return (
pbegin
| core.Impulse()
| 'Split' >> core.FlatMap(split_source)
| util.Reshuffle()
| 'ReadSplits' >> core.FlatMap(lambda split: split.source.read(
split.source.get_range_tracker(
split.start_position, split.stop_position))))
else:
# Treat Read itself as a primitive.
return pvalue.PCollection(self.pipeline)
# ... other methods
看起来如果你设置这个实验性的beam_fn_api pipeline debug_option 那么pbegin 实际上会被使用,但我不确定该选项的其他效果是什么。
为什么需要它们按顺序发生?您似乎是在写一个表,然后从另一个表读取?
如果你真的需要这个顺序发生,也许像这样子类化 Read 就可以了
class SequentialRead(Read):
def expand(self, pbegin):
return pbegin