簡體   English   中英

梁:CombinePerKey(max)掛在數據流作業中

[英]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一起使用的預期方式。 如果將此參數設置為tsReadFromPubSub應該發出時間戳已設置為ts元素,並且水印也應適當設置。

如果那不起作用,您還可以查看其他內容。 仔細檢查時間戳記是否正確設置是一個很好的初始步驟(將ReadFromPubSub生成的元素的時間戳記與ts的值進行比較)。 另一種可能性是在Windows上設置觸發器可能會有所幫助。 例如, 處理時間觸發器可能能夠阻止窗口永遠等待水印趕上來,盡管根據管道的需求可能不適合。 需要特別注意的是,上面截屏的指標有時對於python流而言可能並不可靠,因此,如果您需要進行細粒度的調試,則可以通過轉換輸出日志來更好地了解運氣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM