流水查詢需求
- 需求第一期:
基于TB級的在線資料,支持繳費帳單明細在線查詢,大家都知道,像銀行帳單流水一樣,查幾年的流水是常有的事,
支持的維度查詢:帳期、欠費狀態、日期范圍、費用科目型別、房屋分類、房屋所屬專案、關聯合同資訊、統計列
什么是實時資料
實時可以分為:實時采集、實時計算、高性能,底延時的產出結果資料,實時資料指從源系統中實時采集的資料,以及對實時采集的資料進行實時計算直接產生的中間資料或結果資料,實時資料具有時間有效性,隨著時間的推移,實時資料會失效,
即時查詢系統
房屋租賃費用、水電費用、物業管理費用等資料的有效期,一般是不定的,比如辦公租賃可能預交費用5年、10年,那么這種資料,對于業務來說,仍然屬于線上資料,是不可歸檔的資料, 長時間無法歸檔資料,會造成資料越積越大,對于輕量級資料庫MySQL來說,是個很大的挑戰,就算做好分庫分表的準備,條件復雜的查詢在聚合的時候也一樣容易搞爆記憶體,何況系統在dal層設計得有所欠缺,為滿足流水查詢而重構,太得不償失,從需求來看,不涉及OLTP,只需實作OLAP的解決方案,為了不影響業務系統的改造、資料庫重構等方面,決定引入了即時查詢系統解決方案,

業務需求轉化技術需求:
- 帳單明細查詢可由七十多個條件的隨機組合,不能使用類似kylin這樣的預處理技術來解決,支持N年范圍的在線查詢
- 支持復雜條件查詢,如:聯合多表,嵌套多層left join
- 為減少業務側的sql改動量,需要盡可能的支持標準SQL
- 頻繁變更的業務資料需要實時同步更新
根據以上技術需求點和經過技術的篩選后,落地的架構是這樣:

架構實作
資料實時同步—Confluent Platform架構實作
debezuim:業務庫使用的是MySql,如果在即時查詢系統中查詢到的結果與業務系統查詢結果同等,需要實時同步業務資料,并實時提供查詢能力,debezium是一個低延遲的流式處理工具,能夠捕獲資料庫更改,并且利用Kafka和Kafka Connect記錄到kafka中,實作了自己的持久性、可靠性和容錯性,
Confluent Platform:Mysql到Kudu,需要穩定高效、可彈性伸縮、在異構資料源之間高速穩定同步能力的資料集成解決方案,基于紅火的kafka之上,Kafka Connect是首選,它使得能夠快速定義將大量資料集合移入和移出Kafka的連接器變得簡單,當在distributed的作業模式下,具有高擴展性,和自動容錯機制,confluent platform支持了很多Kafka connect的實作,為后續擴展資料集成服務提供了便利,debezium-connector就是其中之一,除此之外,confluent platform使用Kafka Schema Registry提供Avro序列化支持,為序列化提高了性能,但是Confluent平臺的社區版本提供的功能還是比較有限的,比如提供監控界面化管理的confluent center是屬于商業版的,為此,我們自研了含有監控運維功能的《資料集成服務》,后續文章將詳細介紹并提供在線體驗,
Kudu-connector:confluent platform中雖然提供了Kudu Connector (Source and Sink),但是需要依賴Impala和Hive,而從需求和架構上看,并不需要這些東西,為遵守輕量原則、為避免太多依賴,我們自己實作了輕量級的Kudu-connector(原始碼地址:https://github.com/dengbp/big-well),Kudu-Connector需要借助同步管理配置好需要同步的表、同步規則,并創建好目標表,最后創建連接器同步資料,Kudu-Connector暫時沒有自動創建目標表能力,下個版本實作,

(網路圖)
實時數倉—kudu
分布式列式存盤,支持行級更新,在OLAP場景下,能快速處理,跟其它大資料框架緊密集成(下文會與Hive Metastore集成,為上層開發訪問下層資料的提供統一入口),本身既具有高可用性,又是Cloudera家族的大資料生態圈成員,為系統自身擴展提供了極大空間,本次需求,主要是同步帳單表資料,和帳單查詢資訊用到的關聯表資料,如:租賃合同資料、專案資料、房屋資料、帳單型別等資料,從業務資料特點分析,需要對帳單表ID和帳單型別做哈希磁區,對帳單創建時間做范圍磁區來創建帳單目標表,這樣既可以實作資料分布均勻,又可以在每個分片中保留指定的資料,同時對時間磁區繼續擴展,其它關聯的資料表,根據查詢關聯特點,同樣使用哈希磁區和范圍磁區組合,

(網路圖)
查詢引擎—實作秒級回應—Presto
不依賴hive元資料服務,部署簡單,在sql語法方面,雖然存在小部分與標準相違背(如:分頁需要 ORDER BY、時間比較需要用TIMESTAMP先轉換等),但整體支持標準sql度極高,這對于當前業務系統改動成本小,業務接入時,除了部分sql在性能上需要做優化外,只需要配置多個JDBC資料源即可,這只是理想狀態,由于整個業務系統使用的是msyql資料庫,所以慢長的開發程序中,難免會用到mysql特有的語法,這就造成更麻煩的sql兼容問題,在這方面,我們選擇對官方提供的presto-jdbc做二開,使其盡可能多的支持mysql語法,如group by、時間大小比較等,

擴大業務覆寫率
由最初的帳單明細查詢,發展成整個平臺通用的即時查詢系統,所有涉及OLAP查詢,TB級以上的資料都接入了即時查詢系統,服務部署也由原來的十幾個節點,發展到了三十多個節點,
| 部署配置 | ||
| 服務名稱 | 節點數 | 配置 |
| Confluent Platform | 7 | 32核64g |
| Kudu | 11 | 32核64g |
| Presto | 15 | 32核64g |
| Zeppelin | 1 | 6核32g |
大資料需求
- 需求第二期:
在資產租賃管理服務中,除了要了解客戶投訴情況、滿意度調查、水電使用情況、設備故障等統計分析之外,還需要幫客戶做租賃業務的精準營銷,網路爬取同行公開資料,提供競品資料分析,指導客戶業務決策,
實時離線一體化系統之技術架構
實時離線一體化系統之資料流

實時離線一體化接入
大資料的來源主要分為三個:
- 第一個來源是內部系統的Mysql資料庫(業務分析)
- 第二個來源是應用App(用戶軌跡)
- 第三個來源是外部系統網路采集(同行資料,用于競品分析,行業分析)
- 日志檔案(業務訪問、列印在日志檔案上的業務資料)
有些實時資料,只需簡單的清洗就可以產出,比如:異構資料同步、上面講到的即時查詢系統等這類資料是不需要進入ODS層的,為了能跟即時查詢系統的接入統一化,所有來源資料統一由集成服務實時接入ODS層(hdfs)或APP層(Kudu),

資料倉庫分層規范化
資料分層大家都流行以四層劃分(關于數倉分層,不了解的同學需要自己去找文章補腦),這里也不例外,只是我們每層的存盤和訪問需要解決整合問題,原因跟我們用的技術架構有關系,接下來我們講下每種資料流進來以后和經過層層分析后怎么存盤,先上個直觀圖:

對于要求實時的資料,進入到kafka后,經過ETL直接輸出應用資料到Kudu或Mysql,提供給應用使用,相當于在先前的即時查詢系統中加入了ETL功能,不再是之前簡單的kafka Connector了,需要做離線分析、定制查詢或實時性要求不高的資料分析,通過資料集成通道后通過Hive進入到ODS,然后再由已開發好的程式經過預計算出的結果往資料上層上放(DW和APP層),我們的原則是:越往上層的資料,越往實時倉Kudu上放,對于離線計算,可以固化的查詢,如果隨著資料量和計算復雜度的增長,即使我們用了上面的即時查詢系統,在回應時間上也不能得到保證(就算可以增加計算節點,如果查詢樹無法再拆分的情況下),所以我們選擇預計算方案
預計算方案(Kylin+Kudu)
大家都知道,企業中的查詢一般分為即席查詢和定制查詢兩種,對于即時查詢需求我們用presto和Impala做為引擎(為什么會用到兩個?這個問題跟我們的需求演化和公司系統架構有關系,presto從支持標準的sql上看,可以減輕業務側對現有的功能sql改造,簡單來說就是為了兼容現狀,部署的環境依賴也比較簡單,方便部署;而Impala主要是用在大資料需求新功能上,又方便檢索冷熱資料的聚合),而定制查詢,它的場景多數是對用戶的操作或是對下線的業務資料做出實時分析,如果用Hive或SparkSQL作為查詢引擎,估計要花上數分鐘甚至數十分鐘的時間才能回應,顯然是不能滿足需求的,在很長一段時間里,企業只能對資料倉庫中的資料進行提前計算,再將算好后的結果存盤在APP層或DW層上,再提供給用戶進行查詢,但是上面我們也說了,當業務復雜度和資料量逐漸升高后,使用這套方案的開發成本和維護成本都顯著上升,因此,對于已經固化下來的查詢進行亞秒級回傳的解決辦法,我們使用了Apache Kylin,我們只需要提前定義好查詢維度,Kylin就能幫助我們進行計算,并將結果存盤到結果表中,這樣不僅很好地解決了海量資料快速查詢的問題,也減少了手動開發和維護提前計算程式的成本,
但是Kylin默認將計算結果放入到Hbase中,從上圖看,沒有看到Hbase,而是Kudu,因為我們自己實作了Kylin與Kudu的整合,
Kylin使用Kudu存盤引擎
存盤引擎,我們引入自研的storage-kudu模塊替代默認的storage-hbase,Kylin依賴的三大模塊:資料源、構建引擎、存盤引擎,資料源我們還是使用Hive, 至于在kudu中的資料,因為上面已經解決了Hive支持kudu的方案,所以Kylin通過Hive也可以加載到Kudu中的資料,構建引擎我們使用了Kylin支持的spark計算引擎,而spark同時也是支持與Kudu整合的,從原始碼上看,Kylin架構要求擴展存盤引擎需要實作IStorage介面,這介面有兩個函式一個是指定構建Cube引擎介面adaptToBuildEngine和能夠查詢Cube的createQuery介面,剩下的資料在Kudu的存取細節基本都直接使用spark支持Kudu的api,
實時離線開發統一訪問資料入口

部分分析資料,比如用戶的滿意度調查、水電費使用統計等,在即時查詢系統中已經存在,不就需要再同步一份資料到hdfs當中,為了減少存盤空間成本,避免資料多份存盤,那么就至少需要解決在Kudu中的資料能讓hive能訪問到,但是我們使用的hive版本中,hive并不支持Kudu表的操作,預告最新的hive4.0版本中,也未開發完成,
需要解決的問題:
- 即時系統中存在Kudu表資料,需要通過Hive能訪問,這點仿照Impala,創建外部表 ,將kudu的表映射到Hive上
- Hive能像Impala一樣,能創建表、查詢、更新、洗掉操作
- Kylin能使用Kudu表
- 保證資料結構和元資料資訊的一致性
Hive、Kudu元資料整合:
從Hive官網公布資訊和原始碼分析來看,核心類KuduStorageHandler、KuduSerDe、KuduInputFormat、KuduOutputFormat已經實作一分部功能,KuduMetaHook還沒有,保證 meta 的一致性需要必須實作HiveMetaHook,從原始碼上看KuduStorageHandler已經繼承了DefaultStorageHandler和實作了HiveStoragePredicateHandler,再實作與HMS的互動就可以對 Kudu meta 的相關操作和可以發現Kudu的表并進行操作了(與《CDH6.3.2升級Hive到4.0.0》文章中使用同個版本),

其中即時系統實時同步到Kudu的表資料,也需要創建Hive外部表,把kudu表映射到Hive來,也是在KuduStorageHandler中實作,包括資料的查詢、修改、洗掉,通過在資料集成服務的《同步管理》模塊中,每次創建資料同步任務時,都會去連接Hive并創建Kudu的外部映射表,
如此一來,不管上層使用的SparkSQL、Kylin還是HQL訪問hdfs或kudu的表,對開發者或對資料使用者來說都是統一的入口,
透明的資料分層存盤
整個系統架構里,有兩個地方可以存盤資料,一個是Kudu,另一個是HDFS,而Kudu存盤的資料大多是即時查詢系統資料和經過業務處理分析后的APP層、DWS層資料,實時資料當不在有變更時,就可以刷到HDFS上;APP層等這些資料隨著時間的推移,也是逐漸變成冷資料,那么等變冷的資料,就需要遷移到HDFS上,而資料遷移后將面臨查詢資料不完整性、如何實作資料的平滑遷移,又不影響查詢其完整性呢?
一部分資料在Kudu,一部分資料在HDFS,解決查詢的完整性,主要通過View實作,

每天把Kudu里的冷資料遷移到HDFS上,如何識別哪些是冷資料,由業務提供,根據業務情況,業務側自行為每個表提供一個冷熱資料的時間周期,當超過時間周期的資料將被程式遷移進HDFS,每次遷移完成后都需要創建或修改View,不然資料就查不到了,View需要定義好Kudu和HDFS上的查詢時間范圍,如:
create view tb_uhome_acct_item_view as SELECT COMMUNITY_ID,STAGE_ID,NAME,UNIT,HOUSE_NAME,BILL_AREA,PAY_USERID,BILLING_CYCLE,FEE_ITEM_TYPE_ID,RULE_NAME,RES_INST_NAME,HOUSE_STATUS_TYPE,HOUSE_STATUS,REAL_CYCLE,CONCAT( BILL_DATE_START, BILL_DATE_END ),LEASE_POSITION,OBJ_CODE FROM tb_uhome_acct_item WHERE create_date >= "2017-01-01" UNION ALL SELECT COMMUNITY_ID,STAGE_ID,NAME,UNIT,HOUSE_NAME,BILL_AREA,PAY_USERID,BILLING_CYCLE,FEE_ITEM_TYPE_ID,RULE_NAME,RES_INST_NAME,HOUSE_STATUS_TYPE,HOUSE_STATUS,REAL_CYCLE,CONCAT( BILL_DATE_START, BILL_DATE_END ),LEASE_POSITION,OBJ_CODE FROM tb_uhome_acct_item_hdfs WHERE create_date < "2017-01-01"
每一邊的資料都有表欄位create_date做了范圍限制,然后等遷移成功后再修改View,這樣無何什么時候查資料,都不會出現部分資料檢索不到,
再補充一點,先前的即時查詢系統中,通過連接器同步過來的Kudu表資料,在同步的時候,在資料集成系統中,要創建Impala的外部表,將kudu的表映射到impala上,這樣Impala才能查到,
展望未來
1、基于整合后的架構,未來我們可以提供更多的能力,讓更多的存盤引擎支持Hive Metastore,使HMS的元資料服務支持豐富化,
2、資料延遲監控,對kafka每個topic訊息的延遲、lag監控,做到整個資料鏈路的延遲監控,
3、Hive支持Kudu繼續優化,通過Hive查詢部分資料在Kudu和部分在hdfs中的資料view實作還未完善,還有部分ddl需要完善,
4、Kylin繼續二開,根據資料集成服務中采集到用戶的維度和度量需求,使用Spark 動態構建Cube,
【著作權宣告】
本文著作權歸作者和博客園共有,歡迎轉載,但未經作者同意必須在文章頁面給出原文鏈接,否則保留追究法律責任的權利,如您有任何商業合作或者授權方面的協商,請給我留言:[email protected]
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/180452.html
標籤:大數據
上一篇:對執行緒的簡單理解
