[英]How to convert PCollection<TableRow> to PCollection<Row> in Apache Beam?
[英]How combine & log PCollection correctly after GlobalWindow?
我正在運行一個流媒體管道,它應該將來自 PubSub 的網上商店點擊流攝取到 BigQuery 中。 Beam with Dataflow runner 應該可以幫助我匯總每個用戶的購買事件價值。 我想每 10 個傳入事件觸發一次聚合。
這應該很簡單,但我對 Beam 比較陌生,似乎誤解了一些關於窗口的基本概念。
在我的管道的聚合部分下方。
第一,我正在過濾正確的事件類型(工作。)。
第二,我正在應用具有重復觸發器的全局 window。
第三,我的復合轉換首先提取正確的字段並分配一個鍵。
第四,我的復合轉換結合了每個鍵和總和。
在此設置中,我期望收到每 10 個項目打印的分組總和。
實際上什么都沒有記錄,似乎我的ExtractAndSumValue
轉換甚至沒有被觸發,因為我的打印語句沒有被記錄。
我在這里錯過了什么?
管道設置:
fixed_windowed_items = (json_message
| 'Filter for purchase' >> beam.Filter(is_purchase)
| 'Global Window' >> beam.WindowInto(beam.window.GlobalWindows(),
trigger=trigger.Repeatedly(
trigger.AfterCount(10)),
accumulation_mode=trigger.AccumulationMode.ACCUMULATING)
| 'ExtractAndSumValue' >> ExtractAndSumValue()
| 'Print PColl' >> beam.Map(print)
)
復合變換:
class ExtractAndSumValue(beam.PTransform):
def __init__(self):
beam.PTransform.__init__(self)
def expand(self, pcoll):
print('expanding!')
return(
pcoll
| beam.Map(lambda elem: (elem['client_id'], elem['ecommerce']['purchase']['value']))
| beam.CombinePerKey(sum))
如果我在全局 window 之后立即應用beam.ParDo(print)
,我會在日志中看到完整的 json 消息,如預期的那樣,每批 10 條。
就在今天,我一直在為GroupByKey
的類似問題而苦苦掙扎,我相信它也適用於CombinePerKey
。
根據文檔(但是,不在“正確的”position,即 GroupByKey 部分)
然后我們為該 PCollection 設置一個窗口 function。 GroupByKey 轉換根據窗口 function通過鍵和window對 PCollection 的元素進行分組。
trigger.AfterCount(..)
具有誤導性。 這並不意味着每 10 個輸入元素,您的CombinePerKey
中就會發生一些事情。 相反,Beam 根據密鑰和window 對您的 PCollection 進行分組/組合。在您的情況下,這意味着它會等到每個client_id
收到 10 條消息,然后再對其進行匯總。 顯然,您的輸入數據不包含屬於一個客戶端的足夠消息。
我已經使用GroupByKey
對此進行了測試,我向 PubSub 發布了屬於同一密鑰的 9 條消息。 從未執行打印。 然而,一旦我發布了第 10 條消息,它立即打印出預期的結果。
長話短說,您需要添加額外的觸發器,例如事件/處理時間。 或者,您可以設置trigger.AfterCount(1)
,但是您的CombinePerKey
將不再有意義。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.