胖哥的經(jīng)驗 | 一款普適的實時數(shù)倉架構(gòu)設(shè)計

什么?胖哥的經(jīng)驗,沒錯這是來自我們大數(shù)據(jù)成神之路小伙伴的經(jīng)驗。有什么問題,歡迎大家加群討論,公眾號回復(fù)【加群】。
一、實時數(shù)倉的架構(gòu)背景
首先我們來聊一聊實時數(shù)倉是怎么誕生的,在離線數(shù)倉的時候數(shù)據(jù)是T+1的也就是隔一天才能看到昨天的數(shù)據(jù),這種形式持續(xù)了很久的時間,但是有些場景真的只有實時的數(shù)據(jù)才有用武之地。例如推薦、風(fēng)控、考核等。那么這個時候?qū)崟r指標(biāo)也就應(yīng)運而生,在最開始的時候,采用flink\spark streaming來進(jìn)行數(shù)據(jù)的指標(biāo)統(tǒng)計。在這個時候,數(shù)據(jù)存在哪里又是一個問題。例如大屏計算結(jié)果可能存儲在redis中,可以參考如下圖所示的,實時大屏架構(gòu)圖。

那么這個時候問題來了,你有多少指標(biāo)?業(yè)務(wù)的需求是 無窮無盡 的,作為技術(shù)能做的是怎么能更好的服務(wù)他們,以數(shù)據(jù)驅(qū)動業(yè)務(wù)的成長,就像在一號線上,京東數(shù)科做的廣告,以AI驅(qū)動產(chǎn)業(yè)數(shù)字化。我一直堅信,技術(shù)是可以改變未來的。
那么通過以上的架構(gòu)圖,我們可以發(fā)現(xiàn),在上述的場景中,有一些問題,你的指標(biāo)可能是無窮無盡的,導(dǎo)致的也就是開發(fā)速度可能不盡人意??赡軆商觳庞幸粋€指標(biāo)的產(chǎn)出,復(fù)雜的可能一個星期乃至更長。那么我們有沒有可能在犧牲一些查詢速度的時候,來提升我們的開發(fā)速度,我們應(yīng)該都知道spark streaming 和flink都是支持sql開發(fā)的。那么flink 或者spark streaming 來進(jìn)行sql 開發(fā)真的好嗎?這是一個很值得思考的問題。那么我們?nèi)绾谓鉀Q這個問題呢,我們是不是可以嘗試將我們的binlog 數(shù)據(jù)以及埋點數(shù)據(jù)進(jìn)行拉寬,也就是寬表化的一些操作,那么這個時候就是實時數(shù)倉的誕生!
實時數(shù)倉在我理解中呢,可以對外進(jìn)行服務(wù),并且可以實時的進(jìn)行OLAP查詢,也就是在線化查詢 Ad-hoc化的查詢。
二、實時數(shù)倉的架構(gòu)演進(jìn)
2.1 初始
在我剛來我司的時候,并沒有實時數(shù)倉,只是一些批處理化的時候,這個時候?qū)τ陲L(fēng)控和指標(biāo)來講,是不是很好的。并且是一種煙囪式的開發(fā),數(shù)據(jù)流程是這樣的,我們采用的greenplum來做的實時數(shù)倉,每15分鐘去業(yè)務(wù)庫和神策系統(tǒng)拉取實時數(shù)據(jù)到greenplum中進(jìn)行計算,可以參考一下下面的圖。

我們這個時候肯定可以發(fā)現(xiàn),假如指標(biāo)多的時候,那么對于開發(fā)速度來講是一個十分緩慢的一個過程,并且會造成很多數(shù)據(jù)的冗余計算,有些指標(biāo)并不能復(fù)用。
2.1 實時數(shù)倉0.1
我剛來公司,領(lǐng)導(dǎo)讓開始做實時數(shù)倉,當(dāng)初我并不會flink,但是我知道flink是未來,我就花了1個星期的時間把flink學(xué)了學(xué)。學(xué)完之后我就堅定了實時要用flink。不得不說真的好強(qiáng)啊,不強(qiáng)的話,阿里也不會買了flink的母公司。然后熟悉了幾天業(yè)務(wù),之后就開干,然后給我了一個線上分析的需求,這個要求用我自己的想法來做,我當(dāng)時想的是我拿flink來算不是很好嘛,然后就擼起袖子加油干。寫了一段時間就寫完上線了,那個時候的數(shù)據(jù)流向是這樣的。

那個時候我還是很沾沾自喜的,我拿flink也能計算指標(biāo)了,然后效果還不錯。但是后來慢慢的需求多了起來,我天啊,我拿flink寫什么時候是個頭啊,然后我就想應(yīng)該怎么把這些數(shù)據(jù)解耦!也就是不要煙囪式的開發(fā)。
2.1 實時數(shù)倉1.0
然后我就開始想,我假如我的表都是寬表的話,那么我直接在寬表上進(jìn)行計算不就好了嗎。說到就做,然后就跟總監(jiān)申請了一下,要做實時數(shù)倉,也把我的困難說了一些,然后就開始設(shè)計和架構(gòu)。
我當(dāng)初想的是,我要拉寬這些數(shù)據(jù)表,我得有場景,我們公司是比較關(guān)心銷售的,那么假如我把離線的銷售寬表拿實時展現(xiàn)出來不就是很好的一個場景嗎,那么第一個要做的寬表就是銷售寬表。
那么我知道我的數(shù)據(jù)從業(yè)務(wù)庫來,但是我們的postgresql 比較老了。并不能有binlog這些的操作,我當(dāng)初就和研發(fā)的架構(gòu)探討了一下,他們那邊借助觸發(fā)器來進(jìn)行給我往kafka來打一些數(shù)據(jù),然后我對數(shù)據(jù)先進(jìn)行了校驗,也就是看看我要的字段都給我打過來了嗎。后來數(shù)據(jù)感覺字段都有了,就開始了一番嘗試拿flink接入kafka的數(shù)據(jù)。

這個時候我數(shù)據(jù)是拿到了,但是我需要拉寬,我應(yīng)該怎么拉寬。我把維度表放置到redis把,這樣比較快。這樣在flink的map方法中進(jìn)行查詢redis中的數(shù)據(jù)來進(jìn)行拉寬維度表。

這個時候就來問題了,我的維度表是會更新的啊。我也就問了我們組的業(yè)務(wù)大佬,咨詢了一下,發(fā)現(xiàn)維度表無非就是門店維表、品類維表(一級類、二級類、三級類等)、城市維表、商品維表、主推表等。這些維度表的更新都是很緩慢的,即使是更新,也會提前上線幾天進(jìn)行更新。并且我們在凌晨0點到2點是不進(jìn)行出庫操作的,我在這個時候進(jìn)行維度表更新操作不就好了嗎。那么也就有下面的思考了。

那么接下來我們就可以進(jìn)行銷售寬表的拉寬操作了,但是我這個時候又發(fā)現(xiàn)了一個問題,我拉寬之后存在哪里,這個時候我得思考的幾點是。第一單表查詢足夠快、最好支持join。那么我開始的調(diào)研過幾款 Tidb、Doris、Druid、Clickhouse。我在單機(jī)測試的表現(xiàn)上來看,clickhouse給我?guī)砹藷o與倫比的感覺。并且考慮到當(dāng)時的業(yè)務(wù)場景,也就毅然決然的采用了Clickhouse為基礎(chǔ)的實時數(shù)倉。

然后就這樣的一個架構(gòu)持續(xù)了大概兩個月的時間,業(yè)務(wù)也越來越復(fù)雜,當(dāng)初的架構(gòu)設(shè)計已經(jīng)不滿足當(dāng)時的業(yè)務(wù)了。我們要接入一些實時維度表,這個維度表就是用戶維度表。因為門店需要對導(dǎo)購拉新來做當(dāng)日的績效考核。那么我們總計有2000多萬的用戶,我全部都導(dǎo)入的redis話會有一些問題。而且還要求是實時的,例如要在用戶寬表中標(biāo)記出來這個用戶是不是新會員、是否是孕婦等。但是當(dāng)初我面臨的困難不是這個問題,是因為回溯分?jǐn)偟膯栴},例如一個用戶購買了一個A 贈了一個B那么這個時候,品類間的毛利就有了一些損失。例如買一件衣服送一罐奶粉,那么這個時候就有了問題。衣服的總監(jiān)愿意啊,買的人多了,但是奶粉的總監(jiān)不干了,我毛利沒了啊。所以就有了回溯分?jǐn)傔@一個事情。
我就寫了個flink程序,自定義了一個source實時的去庫里面拉取數(shù)據(jù),因為沒有binlog。但是不能實時的去啊,對庫的影響太大了。那么這個時候就想到了我每次間隔一分鐘去拉取一次放到redis當(dāng)中,然后flink join 的時候就寫入到clickhouse中。假如沒有join上的,就放到kafka的另一個topic中例如 dws_sold_detail_retry 然后再開一個flink 專門消費這個。假如還沒有join上 就繼續(xù)放到這個topic中,在日志中追加一個重試次數(shù),假如這個消息重試了超過5次則,認(rèn)為失敗。也就不管他了。但是會報警,每天的銷售額差異不能超過百分之3,就可以接受。

就這樣 慢慢的加入了其他的一些寬表。例如庫存、優(yōu)惠券、會員寬表、促銷寬表等。但是慢慢的問題也有了,那就是flink寫入clickhouse的時候假如表特別寬的話,代碼量是很大的。后來我就引入了waterdrop。

也就是以上的架構(gòu)圖。
三、總結(jié)
在以上的架構(gòu)中,我的思想就是,flink就是拉寬,計算交給olap引擎去做起到了解耦合的作用。
那么上面的架構(gòu)也有一些問題,例如維度表太大了怎么辦,后面我又引入了二級緩存。也就是引入的hbase,并且支持對外提供查詢?nèi)齻€月內(nèi)的數(shù)據(jù)實時查詢。
最終架構(gòu)圖:


Flink1.12集成Hive打造自己的批流一體數(shù)倉
你需要的不是實時數(shù)倉 | 你需要的是一款強(qiáng)大的OLAP數(shù)據(jù)庫(上)
你需要的不是實時數(shù)倉 | 你需要的是一款強(qiáng)大的OLAP數(shù)據(jù)庫(下)
文章不錯?點個【在看】吧!???
