問題:多個不同流根據(jù)一定規(guī)則join的問題(例如:網(wǎng)約車中訂單發(fā)單流與接單流join問題)
問題
描述:多個不同流根據(jù)一定規(guī)則join的問題(例如:網(wǎng)約車中訂單發(fā)單流與接單流join問題)
特點:
不同流需要join的數(shù)據(jù)時間跨度較長(例如:發(fā)單與接單時間跨度最長一周之久)
數(shù)據(jù)源格式不定 (例如:binlog數(shù)據(jù)和業(yè)務(wù)日志的join)
join規(guī)則多樣化
系統(tǒng)要求吞吐量大(訂單表流量是5M/s) 、延遲低(秒級)
分析
顯然根據(jù)窗口實現(xiàn)是不可取的,首先多流之間跨度較大,窗口無法支持時間跨度這么大的延遲。為此,我們需要一個高效的,具有持久化功能的Cache服務(wù),來緩存先到的流。
并且針對特殊業(yè)務(wù),我們需要支持流的保序性。流的保序性是我定義的一個說法(或名詞),它指的是如果數(shù)據(jù)流中存在多張表的數(shù)據(jù),而這些表依照一個次序由業(yè)務(wù)發(fā)過來。(如業(yè)務(wù)數(shù)據(jù)落到MySQL Binlog,然后可以按照訂單id partition到Kafka Topic)我們在下游處理過程和Join的過程中,需要對流中的分表保序。保序要注意的幾點是可以按照主鍵id(訂單id)取哈希作為partition key,確保同樣主鍵的數(shù)據(jù)落到下游同partition的topic,值得注意的一點是,如果Executor端使用了Producer池的話,要確保采用同一個Producer發(fā)送??刹扇≈麈Iid的哈希值對池大小取模的方式來做。
這里保序主要為了確保多流Join時如果有非對等流,即某一個流到達后需要輸出它的相關(guān)字段,即使沒有Join上。(如成單的數(shù)據(jù),業(yè)務(wù)確保了成單狀態(tài)一定出現(xiàn)在創(chuàng)建訂單之前)。
方案
為了解決上述的多流Join問題,進行了如下的方案實現(xiàn)。
