Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google cloud dataflow 打开窗口后,Google dataflow streaming pipeline没有将工作负载分配给多个工作人员_Google Cloud Dataflow_Apache Beam - Fatal编程技术网

Google cloud dataflow 打开窗口后,Google dataflow streaming pipeline没有将工作负载分配给多个工作人员

Google cloud dataflow 打开窗口后,Google dataflow streaming pipeline没有将工作负载分配给多个工作人员,google-cloud-dataflow,apache-beam,Google Cloud Dataflow,Apache Beam,我正在尝试用python建立一个数据流管道。我在批处理管道方面有相当多的经验。我们的基本架构如下所示: 第一步是进行一些基本处理,每条消息大约需要2秒钟才能到达窗口。我们使用的滑动窗口为3秒,间隔为3秒(以后可能会更改,因此我们有重叠窗口)。作为最后一步,我们有一个SOG预测,需要大约15秒来处理,这显然是我们的瓶颈转换 因此,我们似乎面临的问题是,在窗口化之前,工作负载完全分布在我们的工作人员身上,但最重要的转换根本没有分布。所有窗口一次处理一个,似乎只有一个工人,而我们有50个可用窗口 日

我正在尝试用python建立一个数据流管道。我在批处理管道方面有相当多的经验。我们的基本架构如下所示:

第一步是进行一些基本处理,每条消息大约需要2秒钟才能到达窗口。我们使用的滑动窗口为3秒,间隔为3秒(以后可能会更改,因此我们有重叠窗口)。作为最后一步,我们有一个SOG预测,需要大约15秒来处理,这显然是我们的瓶颈转换

因此,我们似乎面临的问题是,在窗口化之前,工作负载完全分布在我们的工作人员身上,但最重要的转换根本没有分布。所有窗口一次处理一个,似乎只有一个工人,而我们有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()

在beam中,平行度的单位是键——给定键的所有窗口将在同一台机器上生成。但是,如果您有50多个密钥,则应将它们分发给所有工作人员


您提到无法在流媒体中添加改组。这应该是可能的;如果您遇到错误,请在上提交错误。在全局窗口中重新打开窗口是否会消除重新洗牌的问题?

看起来您不一定需要GroupByKey,因为您总是在同一个键上分组。相反,您可以使用CombineGlobaly来附加窗口中的所有元素,而不是GroupByKey(始终使用相同的键)


我不确定使用CombineGlobaly时负载分布是如何工作的,但由于它不处理键、值对,我希望使用另一种机制来进行负载分布。

对于重新洗牌,错误如下:org.apache.beam.sdk.transforms.windowing.IntervalWindow无法强制转换为org.apache.beam.sdk.transforms.windowing.GlobalWindowHi Robert,我发布了一个替代解决方案,使用CombineGlobaly,也许您可以就我的答案提供建议,如何在这个应用程序中优化多个工作人员之间的负载分布case@robertwb,根据你的回答,我们找到了一个非常肮脏的解决办法来让它工作。谢谢还有一个问题,为什么并行化不基于键和窗口?对于像我们这样的小延迟应用程序,不考虑窗口似乎是不合逻辑的。我们现在必须在进行窗口设置之前将窗口添加到键中(幸运的是,在这种情况下,我们知道元素将被放入哪个窗口),只有这样,我们才能在不增加延迟的情况下将其并行化。对于某些窗口功能(例如会话),在所有键并置之前,窗口是未知的。对于那些已知的情况(例如FixedWindows),这是可能的,只是对于任何跑步者来说,这还不是一个足够重要的优化。
combined = values | beam.CombineGlobally(append_fn).without_defaults()
combined | beam.ParDo(PostProcessFn())