Flink如何處理update數據

問題

Flink實時統計GMV,如果訂單金額下午變了該怎麼處理

具體描述

  • 實時統計每天的GMV,但是訂單金額是會修改的。
  • 訂單存儲在mysql,通過binlog解析工具實時同步到kafka.然後從kafka實時統計當日訂單總額。
  • 假設訂單009 上午10點生成,金額爲1000. 生成一條json數據到kafka ,GMV實時統計爲1000。
  • 然後下午15點,009訂單金額被修改爲500。數據生成json也會進入kafka. 這時如果不減去上午已經統計的金額。那麼總金額就是錯的。

根據 update /delete 要寫這個減去的邏輯。

按日去重是不行了,因爲是增量處理, 上午的數據已經被處理了不能再獲取了。

解決思路

  1. 首先版本是1.11+, 可以直接用binlog
    format,這樣數據的修改其實會自動對應到update_before和update_after的數據,這樣Flink
    內部的算子都可以處理好這種數據,包括聚合算子。比如你是select sum(xxx) from T group by
    yyy這種,那這個sum指標會自動做好這件事。

  2. 如果不用binlog模式,只是取最新的數據來做聚合計算,也可以用去重算子[1] 將append數據流轉成retract數據流,這樣下游再用同樣的
    聚合邏輯,效果也是一樣的。

去重語法:

SELECT [column_list]
FROM (
   SELECT [column_list],
     ROW_NUMBER() OVER ([PARTITION BY col1[, col2...]]
       ORDER BY time_attr [asc|desc]) AS rownum
   FROM table_name)
WHERE rownum = 1
  • ROW_NUMBER(): 每一行分配一個唯一的,序列數字,從1開始

  • PARTITION BY col1[, col2...]: 指定分區列 i.e. 去重key.

  • ORDER BY time_attr [asc|desc]: 指定排序字段, 必須是一個時間屬性. Currently Flink 支持 processing time 和 event time 屬性. Ordering by ASC 意爲保留第一行, ordering by DESC 意爲 保留最後一行.

  • WHERE rownum = 1: The rownum = 1 是必須的,對於Flink識別這個是去重的查詢語句

只要source端產生了changelog數據,後面的算子是可以自動處理update消息的,簡單理解,你可以認爲:

  1. append / update_after 消息會累加到聚合指標上
  2. delete / update_before 消息會從聚合指標上進行retract

Reference

  1. https://nightlies.apache.org/flink/flink-docs-master/zh/docs/dev/table/sql/queries/deduplication/

  2. https://developer.aliyun.com/article/782653

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章