[英]Beam: CombinePerKey(max) hang in dataflow job
我嘗試通過pub\\sub
方式從GCS
加載數據,並通過userid
獲取用戶最高級別。 以下代碼在DirectRunner
運行良好,但作業在數據流中的CombinePerKey(max)
中掛起。
這是代碼
class ParseAndFilterFn(beam.DoFn):
def process(self, element):
text_line = element.strip()
data = {}
try:
data = json.loads(text_line.decode('utf-8'))
if 'user_id' in data and data['user_id'] and 'level' in data and data['level']:
yield {
'user': data['user_id'],
'level': data['level'],
'ts': data['ts']
}
def str2timestamp(t, fmt="%Y-%m-%dT%H:%M:%S.%fZ"):
return time.mktime(datetime.strptime(t, fmt).timetuple())
class FormatFieldValueFn(beam.DoFn):
def process(self, element):
yield {
"field": element[0],
"value": element[1]
}
...
raw_event = (
p
| "Read Sub Message" >> beam.io.ReadFromPubSub(topic=args.topic)
| "Convert Message to JSON" >> beam.Map(lambda message: json.loads(message))
| "Extract File Name" >> beam.ParDo(ExtractFileNameFn())
| "Read File from GCS" >> beam.io.ReadAllFromText()
)
filtered_events = (
raw_event
| "ParseAndFilterFn" >> beam.ParDo(ParseAndFilterFn())
)
raw_events = (
filtered_events
| "AddEventTimestamps" >> beam.Map(lambda elem: beam.window.TimestampedValue(elem, str2timestamp(elem['ts'])))
)
window_events = (
raw_events
| "UseFixedWindow" >> beam.WindowInto(beam.window.FixedWindows(5 * 60))
)
user_max_level = (
window_events
| 'Group By User ID' >> beam.Map(lambda elem: (elem['user'], elem['level']))
| 'Compute Max Level Per User' >> beam.CombinePerKey(max)
)
(user_max_level
| "FormatFieldValueFn" >> beam.ParDo(FormatFieldValueFn())
)
p.run().wait_until_finish()
然后,我將一個新的zip文件放入GCS
,然后數據流的管道正在運行,但掛在Compute Max Level Per User
我有什么想念的嗎?
問題的根源可能與Combine轉換中的水印和延遲有關(您可以在此處閱讀該概念的摘要)。 水印可能是一個問題的原因是因為您使用beam.Map
手動設置了元素的時間戳,即使從PubSub源讀取時已經設置了水印,因為它是一個無界的資源,可以設置自己的時間戳。
ReadFromPubSub
轉換具有一個標記為timestamp_attribute
的參數,這是將屬性時間戳與PubSub一起使用的預期方式。 如果將此參數設置為ts
則ReadFromPubSub
應該發出時間戳已設置為ts
元素,並且水印也應適當設置。
如果那不起作用,您還可以查看其他內容。 仔細檢查時間戳記是否正確設置是一個很好的初始步驟(將ReadFromPubSub
生成的元素的時間戳記與ts
的值進行比較)。 另一種可能性是在Windows上設置觸發器可能會有所幫助。 例如, 處理時間觸發器可能能夠阻止窗口永遠等待水印趕上來,盡管根據管道的需求可能不適合。 需要特別注意的是,上面截屏的指標有時對於python流而言可能並不可靠,因此,如果您需要進行細粒度的調試,則可以通過轉換輸出日志來更好地了解運氣。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.