【发布时间】:2019-07-12 19:53:41
【问题描述】:
我正在尝试在 python 中设置数据流流式传输管道。我在批处理管道方面有相当多的经验。我们的基本架构如下所示:
第一步是进行一些基本处理,每条消息大约需要 2 秒才能到达窗口。我们正在使用 3 秒和 3 秒间隔的滑动窗口(稍后可能会更改,因此我们有重叠窗口)。作为最后一步,我们的 SOG 预测需要大约 15 秒来处理,这显然是我们的瓶颈转换。
所以,我们似乎面临的问题是,工作量在窗口化之前完全分布在我们的工作人员身上,但最重要的转换根本没有分布。所有窗口一次处理一个,似乎只有 1 个工作人员,而我们有 50 个可用。
日志向我们显示,sog 预测步骤每 15 秒输出一次,如果窗口将由更多工作人员处理,情况就不应该如此,因此随着时间的推移,这会产生巨大的延迟,这是我们不希望的。对于 1 分钟的消息,最后一个窗口有 5 分钟的延迟。当分发工作时,这应该只有大约 15 秒(SOG 预测时间)。所以在这一点上我们一无所知..
有没有人知道我们的代码是否有问题或者如何防止/规避这个问题? 这似乎是谷歌云数据流内部发生的事情。这是否也发生在 java 流管道中?
在批处理模式下,一切正常。在那里,可以尝试进行重新洗牌以确保不会发生融合等。但这在流式处理窗口后是不可能的。
args = parse_arguments(sys.argv if argv is None else argv)
pipeline_options = get_pipeline_options(project=args.project_id,
job_name='XX',
num_workers=args.workers,
max_num_workers=MAX_NUM_WORKERS,
disk_size_gb=DISK_SIZE_GB,
local=args.local,
streaming=args.streaming)
pipeline = beam.Pipeline(options=pipeline_options)
# Build pipeline
# pylint: disable=C0330
if args.streaming:
frames = (pipeline | 'ReadFromPubsub' >> beam.io.ReadFromPubSub(
subscription=SUBSCRIPTION_PATH,
with_attributes=True,
timestamp_attribute='timestamp'
))
frame_tpl = frames | 'CreateFrameTuples' >> beam.Map(
create_frame_tuples_fn)
crops = frame_tpl | 'MakeCrops' >> beam.Map(make_crops_fn, NR_CROPS)
bboxs = crops | 'bounding boxes tfserv' >> beam.Map(
pred_bbox_tfserv_fn, SERVER_URL)
sliding_windows = bboxs | 'Window' >> beam.WindowInto(
beam.window.SlidingWindows(
FEATURE_WINDOWS['goal']['window_size'],
FEATURE_WINDOWS['goal']['window_interval']),
trigger=AfterCount(30),
accumulation_mode=AccumulationMode.DISCARDING)
# GROUPBYKEY (per match)
group_per_match = sliding_windows | 'Group' >> beam.GroupByKey()
_ = group_per_match | 'LogPerMatch' >> beam.Map(lambda x: logging.info(
"window per match per timewindow: # %s, %s", str(len(x[1])), x[1][0][
'timestamp']))
sog = sliding_windows | 'Predict SOG' >> beam.Map(predict_sog_fn,
SERVER_URL_INCEPTION,
SERVER_URL_SOG )
pipeline.run().wait_until_finish()
【问题讨论】:
标签: google-cloud-dataflow apache-beam