一猜煮、系統(tǒng)架構(gòu)
1. 接入層
Canal、Flume叮趴、Kafka
針對(duì)業(yè)務(wù)系統(tǒng)數(shù)據(jù)割笙,Canal監(jiān)控Binlog日志,發(fā)送至kafka眯亦;
針對(duì)日志數(shù)據(jù)伤溉,由Flume來(lái)進(jìn)行統(tǒng)一收集,并發(fā)送至kafka妻率。
消息隊(duì)列的數(shù)據(jù)既是離線數(shù)倉(cāng)的原始數(shù)據(jù)乱顾,也是實(shí)時(shí)計(jì)算的原始數(shù)據(jù),這樣可以保證實(shí)時(shí)和離線的原始數(shù)據(jù)是統(tǒng)一的宫静。
2. 計(jì)算層
Flink
有了源數(shù)據(jù)走净,在計(jì)算層經(jīng)過(guò)Flink實(shí)時(shí)計(jì)算引擎做一些加工處理,然后落地到存儲(chǔ)層中不同存儲(chǔ)介質(zhì)當(dāng)中孤里。
3. 存儲(chǔ)層
HBase伏伯、Kafka、ES捌袜、Mysql说搅、Hive、Redis
不同的存儲(chǔ)介質(zhì)是通過(guò)不同的應(yīng)用場(chǎng)景來(lái)選擇虏等。
4. 數(shù)據(jù)應(yīng)用層
風(fēng)控弄唧、模型适肠、圖譜、大屏展示
通過(guò)存儲(chǔ)層應(yīng)用于不同的數(shù)據(jù)應(yīng)用候引,數(shù)據(jù)應(yīng)用可能是我們的正式產(chǎn)品或者直接的業(yè)務(wù)系統(tǒng)
二侯养、技術(shù)實(shí)現(xiàn)
1. 計(jì)算引擎
實(shí)時(shí)計(jì)算引擎的功能要求
提供高級(jí) API,支持常見(jiàn)的數(shù)據(jù)操作比如關(guān)聯(lián)聚合澄干,最好是能支持 SQL
具有狀態(tài)管理和自動(dòng)支持久化方案逛揩,減少對(duì)存儲(chǔ)的依賴
可靠的容錯(cuò)機(jī)制,低延時(shí)傻寂,最好能夠保證Exactly-once
Flink的優(yōu)勢(shì)
Flink的API息尺、容錯(cuò)機(jī)制與狀態(tài)管理都滿足實(shí)時(shí)數(shù)倉(cāng)計(jì)算引擎的需求
Flink高吞吐、低延時(shí)的特性
端到端的Exactly-once
WaterMark&Event Time的支持
Flink 不僅支持了大量常用的 SQL 語(yǔ)句疾掰,還有豐富的數(shù)據(jù)類型搂誉、內(nèi)置函數(shù)以及靈活的自定義函數(shù),基本覆蓋了我們的開(kāi)發(fā)場(chǎng)景
2. 存儲(chǔ)引擎
根據(jù)不同的業(yè)務(wù)場(chǎng)景静檬,使用最適合的存儲(chǔ)引擎:
Kafka主要用于中間數(shù)據(jù)表的存儲(chǔ)
ES主要針對(duì)日志數(shù)據(jù)的存儲(chǔ)和分析
HBase炭懊、Redis可用于維表存儲(chǔ)
Hive用于數(shù)據(jù)校驗(yàn)
Mysql可以用于指標(biāo)計(jì)算結(jié)果的存儲(chǔ)
三、數(shù)據(jù)分層
數(shù)據(jù)源:目前數(shù)據(jù)源主要是Binlog拂檩,通過(guò)Canal監(jiān)控各個(gè)業(yè)務(wù)系統(tǒng)的Mysql侮腹,將binlog發(fā)送至kafka。
ODS層:主要將Binlog數(shù)據(jù)存儲(chǔ)至Kafka稻励,這一層不對(duì)數(shù)據(jù)進(jìn)行任何操作父阻,存儲(chǔ)最原始的數(shù)據(jù),Binlog 日志在這一層為庫(kù)級(jí)別望抽,即:一個(gè)庫(kù)的變更數(shù)據(jù)存放在同一個(gè) Kafka Topic 中加矛。
DWD層:主要對(duì)數(shù)據(jù)進(jìn)行簡(jiǎn)單的清洗。拆分主題煤篙,將庫(kù)級(jí)別的主題拆分為表級(jí)別斟览;打平數(shù)據(jù),將data數(shù)組格式打平辑奈。
DWS層:主要根據(jù)不同的業(yè)務(wù)的需求苛茂,將該需求所涉及到的表進(jìn)行join所得。
APP層:根據(jù)指標(biāo)計(jì)算需求鸠窗,對(duì)數(shù)據(jù)進(jìn)行處理后妓羊,存儲(chǔ)HBase,為了方便模型查詢稍计,主要將表存儲(chǔ)為索引表和明細(xì)表躁绸,直接對(duì)數(shù)據(jù)進(jìn)行指標(biāo)計(jì)算后,將計(jì)算結(jié)果存儲(chǔ)到HBase。
四涨颜、數(shù)據(jù)監(jiān)控及校驗(yàn)
1. 數(shù)據(jù)監(jiān)控
目前數(shù)據(jù)的監(jiān)控的架構(gòu)是pushgateway + Prometheus + Grafana
數(shù)據(jù)監(jiān)控主要是接入Flink的Metric,通過(guò)Grafana對(duì)Flink系統(tǒng)指標(biāo)及自定義指標(biāo)進(jìn)行圖形化界面的展示茧球,對(duì)關(guān)鍵指標(biāo)進(jìn)行監(jiān)控報(bào)警
2. 數(shù)據(jù)校驗(yàn)
目前數(shù)據(jù)的監(jiān)控的架構(gòu)是Grafana + Mysql
Grafana用于監(jiān)控指標(biāo)的展示及相關(guān)閾值數(shù)據(jù)的報(bào)警庭瑰,Mysql主要用于監(jiān)控?cái)?shù)據(jù)的存儲(chǔ)
將每個(gè)服務(wù)的source收到的數(shù)據(jù)、sink發(fā)出的數(shù)據(jù)抢埋,根據(jù)表的不同將數(shù)據(jù)關(guān)鍵字段寫(xiě)入mysql中弹灭,通過(guò)統(tǒng)計(jì)各個(gè)階段各個(gè)表中的數(shù)據(jù)條數(shù),對(duì)數(shù)據(jù)完整性進(jìn)行監(jiān)控校驗(yàn)揪垄,若出現(xiàn)數(shù)據(jù)缺時(shí)穷吮,先查找原因,然后指定時(shí)間戳重啟服務(wù)
五饥努、系統(tǒng)管理
元數(shù)據(jù)管理
表捡鱼,字段元數(shù)據(jù)管理,實(shí)時(shí)感知元數(shù)據(jù)的變化酷愧,大幅度降低使用數(shù)據(jù)的成本驾诈。
系統(tǒng)配置
對(duì)應(yīng)用啟動(dòng)參數(shù)及相關(guān)配置參數(shù)的管理,對(duì)任務(wù)進(jìn)行靈活配置及管理溶浴。
血緣管理
主要是梳理實(shí)時(shí)計(jì)算平臺(tái)中數(shù)據(jù)依賴關(guān)系乍迄,以及實(shí)時(shí)任務(wù)的依賴關(guān)系,從底層ODS到DWD再到DWS士败,以及APP層用到哪些數(shù)據(jù)闯两,將整個(gè)鏈度串聯(lián)起來(lái)。
六谅将、問(wèn)題及解決方案
1. 數(shù)據(jù)傾斜
由于要拆分主題漾狼,要以table為key對(duì)數(shù)據(jù)進(jìn)行keyBy,但是由于每個(gè)表的數(shù)據(jù)量相差較大戏自,會(huì)出現(xiàn)數(shù)據(jù)傾斜
解決方案:
加鹽邦投,給key加前綴
前綴不能隨便加,為了保證同一id的數(shù)據(jù)在相同的分區(qū)中擅笔,所以根據(jù)id_table進(jìn)行keyBy
2. 數(shù)據(jù)重復(fù)
任務(wù)在進(jìn)行自動(dòng)或手動(dòng)重啟時(shí)志衣,為了保證數(shù)據(jù)不丟失,數(shù)據(jù)會(huì)出現(xiàn)重復(fù)計(jì)算的問(wèn)題猛们,如果下游只是對(duì)數(shù)據(jù)進(jìn)行HBase存儲(chǔ)的話念脯,由于冪等性,這種重復(fù)可以解弯淘。但是绿店,如果下游要對(duì)數(shù)據(jù)進(jìn)行聚合,這樣會(huì)導(dǎo)致數(shù)據(jù)被計(jì)算多次,影響計(jì)算結(jié)果的準(zhǔn)確性
解決方案:
上游在對(duì)數(shù)據(jù)進(jìn)行發(fā)送時(shí)假勿,對(duì)kafka producer 進(jìn)行 exactly once的設(shè)置
在對(duì)數(shù)據(jù)統(tǒng)計(jì)時(shí)進(jìn)行數(shù)據(jù)去重
3. 數(shù)據(jù)延時(shí)
由于所處理的數(shù)據(jù)表的大小不一樣借嗽,處理大表時(shí),會(huì)出現(xiàn)數(shù)據(jù)延時(shí)的問(wèn)題转培。
解決方案:
針對(duì)大表數(shù)據(jù)增加并行度
4.數(shù)據(jù)亂序
由于Flink kafka producer默認(rèn)是根據(jù)hash對(duì)數(shù)據(jù)進(jìn)行隨機(jī)分區(qū)恶导,kafka consumer在對(duì)數(shù)據(jù)進(jìn)行消費(fèi)時(shí),每個(gè)分區(qū)消費(fèi)速度不同浸须,這樣最終在存儲(chǔ)數(shù)據(jù)時(shí)惨寿,就會(huì)出現(xiàn)亂序即相同的id會(huì)出現(xiàn)老數(shù)據(jù)覆蓋新數(shù)據(jù)的問(wèn)題
解決方案:
對(duì)kafka每個(gè)階段進(jìn)行自定義分區(qū),將id相同的數(shù)據(jù)分到同一個(gè)分區(qū)删窒,保證同一id的數(shù)據(jù)的有序性
由于整個(gè)數(shù)據(jù)處理過(guò)程中可能會(huì)出現(xiàn)shuffle裂垦,導(dǎo)數(shù)數(shù)據(jù)重新亂序,所以在對(duì)數(shù)據(jù)存儲(chǔ)前對(duì)數(shù)據(jù)進(jìn)行排序
對(duì)數(shù)據(jù)進(jìn)行排序的關(guān)鍵點(diǎn)時(shí)要保證每條數(shù)據(jù)的唯一性肌索,即要有標(biāo)記數(shù)據(jù)先后順序的字段
5 . 數(shù)據(jù)唯一標(biāo)記(很重要)
由于要對(duì)數(shù)據(jù)進(jìn)行去重或者排序蕉拢,所以要保證數(shù)據(jù)的唯一性
解決辦法:
使用時(shí)間戳不可以,因?yàn)閿?shù)據(jù)量很大的情況下驶社,同一時(shí)間會(huì)處理上百條數(shù)據(jù)
在最初發(fā)出數(shù)據(jù)的時(shí)候企量,為數(shù)據(jù)打上標(biāo)記,使用 partition + offset + idx 的組合來(lái)確認(rèn)數(shù)據(jù)的唯一性及順序性
6. 數(shù)據(jù)可靠性
我們對(duì)服務(wù)重啟或?qū)Ψ?wù)升級(jí)時(shí)亡电,可能會(huì)出現(xiàn)數(shù)據(jù)的丟失
解決方案:
結(jié)合Flink 的checkpoint及savepoint機(jī)制保證數(shù)據(jù)的可靠性
開(kāi)啟Flink的checkpoint機(jī)制届巩,服務(wù)進(jìn)行自動(dòng)重啟時(shí),會(huì)自動(dòng)讀取上次保存在checkpoint中offset份乒,或者我們指定offset進(jìn)行數(shù)據(jù)消費(fèi)
對(duì)服務(wù)進(jìn)行升級(jí)時(shí)恕汇,先將服務(wù)的狀態(tài)保存至savepoint中,重啟時(shí)指定savepoint進(jìn)行服務(wù)啟動(dòng)或辖,保證數(shù)據(jù)不丟失
7. 無(wú)感升級(jí)
由于我們目前數(shù)據(jù)量比較龐大瘾英,且在對(duì)服務(wù)進(jìn)行升級(jí)時(shí),耗時(shí)較長(zhǎng)颂暇,會(huì)影響調(diào)用方的使用缺谴。
解決辦法:
在對(duì)服務(wù)進(jìn)行升級(jí)時(shí),將數(shù)據(jù)寫(xiě)入備用庫(kù)耳鸯,等數(shù)據(jù)追上且服務(wù)穩(wěn)定運(yùn)行后湿蛔,再將存儲(chǔ)庫(kù)進(jìn)行切換