我正在Apache Beam中编写一个程序,使用Python SDK从Pub / Sub读取JSON文件的内容,并对接收到的字符串进行一些处理。这是程序中我从Pub / Sub中提取内容并进行处理的部分:
with beam.Pipeline(options=PipelineOptions()) as pipeline:
lines = pipeline | beam.io.gcp.pubsub.ReadStringsFromPubSub(subscription=known_args.subscription)
lines_decoded = lines | beam.Map(lambda x: x.decode("base64"))
lines_split = lines_decoded | (beam.FlatMap(lambda x: x.split('\n')))
def json_to_tuple(jsonStr):
res = json.loads(jsonStr)
##printing retutn value
print (res['id'], res['messageSize'])
##
return (res['id'], res['messageSize'])
tupled = lines_split | beam.Map(json_to_tuple)
def printlines(line):
print line
result = tupled | beam.CombinePerKey(sum)
result | beam.Map(printlines)
在运行程序时,代码在创建PCollection tupled
后被卡住(之后没有执行任何代码行)。奇怪的是,当我将源文件从Pub / Sub更改为包含完全相同内容的本地文件(使用ReadFromText()
)时,程序运行正常。
这种行为可能是什么原因?
答案 0 :(得分:1)
根据Pub / Sub I / O文档(Apache Beam docs和Dataflow Pub/Sub I/O docs),默认情况下,PubsubIO转换使用无界PCollections。
PCollections可以是bounded or unbounded:
在操作无界PCollection之前,必须使用以下策略之一:
CombinePerKey
),因此您应首先set a non-global windowing function。这可以解释您所看到的行为,即当从本地文件(有界数据源)读取时相同的管道工作但在从Pub / Sub读取时不工作订阅(这是无界数据源)。
因此,为了使用Pub / Sub订阅,您应该应用窗口或触发策略,以便可以在以下转换中正确处理PCollections中的数据。
编辑: 此外,正如@Arjun所发现的那样,可能需要通过使用以下选项设置相应的arg参数来启用管道中的Streaming命令:
pipeline_options.view_as(StandardOptions).streaming = True