京東OLAP實(shí)踐之路
導(dǎo)讀:本文主要介紹京東在構(gòu)建OLAP從無到有各環(huán)節(jié)考慮的重點(diǎn),由需求場(chǎng)景出發(fā),剖析當(dāng)前存在的問題,并提供解決方案,最后介紹OLAP的發(fā)展過程。
▌需求場(chǎng)景
1. 京東數(shù)據(jù)入口

① 業(yè)務(wù)數(shù)據(jù):訂單
京東作為一家電商企業(yè),擁有自營商品銷售平臺(tái)和全鏈路物流通道。首先第一數(shù)據(jù)入口就是訂單,針對(duì)不同訂單進(jìn)行多維度分析,比如:對(duì)訂單分析、對(duì)店鋪分析、對(duì)商品品類分析等等。
展開對(duì)訂單維度來說,因?yàn)槲覀冏鳛殡娚蹋唵问欠浅V匾囊粋€(gè)維度分析和數(shù)據(jù)支撐,所以常結(jié)合訂單SKU,計(jì)算品類下單轉(zhuǎn)化率。
② 行為數(shù)據(jù):點(diǎn)擊和搜索
用戶在京東商城的操作,比如點(diǎn)擊和搜索,我們會(huì)將用戶的這些行為結(jié)合訂單信息,來做一些分析,比如分析商品的熱銷和滯銷程度,以及轉(zhuǎn)化情況,最常見的就是漏斗分析,來計(jì)算轉(zhuǎn)化率。
③ 廣告和推薦
基于用戶下單情況,我們會(huì)推送廣告和推薦給到用戶,然后進(jìn)行計(jì)算,分析廣告觸達(dá)相關(guān)情況。
④ 監(jiān)控指標(biāo)
對(duì)于監(jiān)控指標(biāo),是我們一個(gè)巨大的場(chǎng)景,因?yàn)樵谖覀冞@里,除了用戶行為數(shù)據(jù),還有很多運(yùn)維的數(shù)據(jù)也需要管理起來。
2. 京東數(shù)據(jù)出口

京東的數(shù)據(jù)出口,主要分類兩大類:離線和實(shí)時(shí)
① 離線
月報(bào)和周報(bào)
典型離線場(chǎng)景:財(cái)務(wù)報(bào)表經(jīng)常需要月報(bào)周報(bào)。
機(jī)器學(xué)習(xí)
會(huì)用到大量的一些訓(xùn)練數(shù)據(jù),這些數(shù)據(jù)的生成也會(huì)用到OLAP的一些特性來把數(shù)據(jù)進(jìn)行分析,產(chǎn)生一些訓(xùn)練的數(shù)據(jù)。
② 實(shí)時(shí)
交互式查詢
非研發(fā)同事,比如營運(yùn)分析人員,經(jīng)常需要臨時(shí)查詢業(yè)務(wù)數(shù)據(jù),比如查詢最近一周訂單的匯總以及明細(xì)數(shù)據(jù),對(duì)這些數(shù)據(jù)進(jìn)行分析,輔助決策。
實(shí)時(shí)大屏展示
平臺(tái)做大促或者實(shí)時(shí)監(jiān)控運(yùn)營情況,會(huì)依照大屏的指標(biāo),實(shí)時(shí)動(dòng)態(tài)調(diào)整資源。比如營銷策略、廣告費(fèi)投入、供應(yīng)鏈庫存。尤其重要的是,在大促銷的時(shí)候,可以進(jìn)行動(dòng)態(tài)資源的調(diào)整,比如車輛資源調(diào)度、根據(jù)促銷效果決策活動(dòng)是否需要進(jìn)行調(diào)整等。
▌問題與解決方案
以上是京東的部分業(yè)務(wù)場(chǎng)景,和大多數(shù)闡述數(shù)據(jù)架構(gòu)不同,我們本次將數(shù)據(jù)搭建的過程分為4個(gè)方面:數(shù)據(jù)怎么寫進(jìn)來;寫進(jìn)來以后怎么進(jìn)行存儲(chǔ);存儲(chǔ)以后又怎么進(jìn)行取用;最后是如何管理前3個(gè)環(huán)節(jié)。
1. 寫

① 數(shù)據(jù)源及數(shù)據(jù)結(jié)構(gòu)多樣性
現(xiàn)狀:
數(shù)據(jù)源來源多樣化:文件系統(tǒng)(本地文件&分布式系統(tǒng)文件)& MQ
本地文件,比如說服務(wù)器本地的數(shù)據(jù),直接導(dǎo)入進(jìn)來
數(shù)據(jù)量比較大時(shí),在用戶本地存不了這么大的數(shù)據(jù)量,會(huì)將數(shù)據(jù)存儲(chǔ)在HDFS上
Kafka或者M(jìn)Q數(shù)據(jù),上游將產(chǎn)生的數(shù)據(jù)直接存儲(chǔ)到消息隊(duì)列中,在京東內(nèi)部,這種MQ的系統(tǒng)有多個(gè),但是我們需要統(tǒng)一進(jìn)行接入
數(shù)據(jù)結(jié)構(gòu)的多樣化,最常見:CSV、TSV、JSON、AVRO、PARQUET、BINLOG等
問題:
多種數(shù)據(jù)源及數(shù)據(jù)類型,對(duì)于開發(fā)人員來說,進(jìn)行數(shù)據(jù)分析的成本相對(duì)比較高,我們希望分析人員,只需要專注于業(yè)務(wù)邏輯本身,直接進(jìn)行SQL查詢,而無需關(guān)心數(shù)據(jù)來源。
解決方案:
建立統(tǒng)一導(dǎo)入數(shù)據(jù)服務(wù),將多樣化的數(shù)據(jù)源和數(shù)據(jù)類型進(jìn)行封裝,通過給用戶配置權(quán)限,用戶只需要在可視化界面直接進(jìn)行操作,即可完成數(shù)據(jù)的導(dǎo)入操作,具體的操作也是比較簡(jiǎn)單,以MQ數(shù)據(jù)源舉例:
選擇數(shù)據(jù)源的topic
指定導(dǎo)入的目標(biāo)源
選擇數(shù)據(jù)格式
選擇對(duì)應(yīng)的數(shù)據(jù)字段類型等等
② 數(shù)據(jù)的時(shí)效性
現(xiàn)狀:
實(shí)時(shí)的數(shù)據(jù)需要實(shí)時(shí)進(jìn)行計(jì)算和展示;離線的數(shù)據(jù),可以定時(shí)的推送并計(jì)算一次,對(duì)時(shí)效的要求比較低。
問題:
如何保證實(shí)時(shí)和離線數(shù)據(jù)的時(shí)效性,且不會(huì)相互影響?
解決方案:
對(duì)實(shí)時(shí)集群和離線集群進(jìn)行物理隔離,防止互相干擾,這樣做的好處有:
實(shí)時(shí)和離線對(duì)于資源的需求不同,實(shí)時(shí)數(shù)據(jù)寫入非常頻繁,而離線的數(shù)據(jù)只是在指定運(yùn)行的時(shí)間點(diǎn)比較多,區(qū)分開便于管理。
③ 數(shù)據(jù)的更新和刪除
問題:
對(duì)于OLAP的架構(gòu)來說,如何做到既要查詢搜索又要更新呢?
解決方案:
數(shù)據(jù)更新,采用覆蓋寫的方案。以訂單為例,用戶下了一個(gè)訂單1,此時(shí)下單狀態(tài)為1,后面用戶進(jìn)行了支付操作,訂單狀態(tài)為2,那么我們會(huì)重新推送一條全量的數(shù)據(jù),只是狀態(tài)的字段值發(fā)生看變化。
數(shù)據(jù)刪除,采用刪除分區(qū)然后重新導(dǎo)入這個(gè)分區(qū)數(shù)據(jù),或者采用版本管理方式,因?yàn)橥ㄟ^新版本的數(shù)據(jù)會(huì)覆蓋原來的版本,起到刪除的作用。
③ 高吞吐
問題:
以京東現(xiàn)在的體量,每天的數(shù)據(jù)是很大的,如何解決高吞吐問題呢?
解決方案:
機(jī)房配置萬兆網(wǎng)絡(luò),另外對(duì)于實(shí)時(shí)場(chǎng)景,配備SSD;離線場(chǎng)景,配備HDD。
2. 存

① 海量數(shù)據(jù)
問題:
京東的數(shù)據(jù),TB數(shù)據(jù)量是非常常見的,有些時(shí)候會(huì)達(dá)到PB級(jí)別,那么采用單機(jī)的方式肯定是行不通的,那么如何解決數(shù)據(jù)存儲(chǔ)的問題呢?
解決方案:
采用分布式解決大規(guī)模數(shù)據(jù)的問題。
為了提高效率,采用了列式存儲(chǔ),對(duì)后續(xù)指標(biāo)的計(jì)算效率也有提升,其實(shí)在OLAP的架構(gòu)中,大多數(shù)都是列式存儲(chǔ)。
采用不同類別的壓縮方式,比如snappy等。
② 容錯(cuò)性
問題:
數(shù)據(jù)現(xiàn)在是科技類企業(yè)非常重要的資產(chǎn),那么如何保障數(shù)據(jù)的安全性性呢?
解決方案:
其一:多副本的容錯(cuò)方式,我們的OLAP采用三副本的方式,所以其中1個(gè)或2個(gè)副本損壞或遷移時(shí)做擴(kuò)容都比較容易處理。
其二:RAID獨(dú)立磁盤冗余陣列(RAID,redundant array of independent disks),因?yàn)榇疟P金屬機(jī)器經(jīng)常會(huì)壞,加上有一些機(jī)器過保存在損壞的風(fēng)險(xiǎn),所以我們也通過raid解決一部分?jǐn)?shù)據(jù)容錯(cuò)性的問題,防止磁盤壞掉之后整個(gè)機(jī)器不能提供服務(wù)的情況。
③ 一致性
解決方案:
解決數(shù)據(jù)的一致性的問題,需要使用到分布式協(xié)調(diào)和本地事務(wù)機(jī)制。
分布式協(xié)調(diào),比如zookeeper
本地事務(wù)機(jī)制:對(duì)于本地的提交,是否通過事務(wù)來保證數(shù)據(jù)的一致性
通過兩者的結(jié)合,來實(shí)現(xiàn)數(shù)據(jù)的一致性。
3. 讀

① 查詢速度
問題:
數(shù)據(jù)存儲(chǔ)到系統(tǒng)中以后,如何高效的進(jìn)行取用呢?
解決方案:
通用方式,數(shù)據(jù)進(jìn)行分區(qū)分片,在很多場(chǎng)景,對(duì)數(shù)據(jù)的分析都是按照時(shí)間進(jìn)行分區(qū),分區(qū)以后,再進(jìn)行分片或者分桶。
比如:訂單信息,我們可能按天查詢,那么就可以按照實(shí)際日期進(jìn)行分區(qū);比如,存儲(chǔ)10年的數(shù)據(jù),不可能全部查詢,我們按照統(tǒng)計(jì)則按月進(jìn)行分區(qū)。
預(yù)聚合,提前進(jìn)行預(yù)計(jì)算,減少一次性計(jì)算的數(shù)據(jù)量,提高性能。
索引,大部分場(chǎng)景下會(huì)使用索引,比如做明細(xì)查詢,可能會(huì)到hash索引、betree、范圍查詢或者倒排。
物化視圖,其實(shí)和預(yù)聚合的功能類似,數(shù)據(jù)進(jìn)入到物化視圖中時(shí),提前進(jìn)行一些預(yù)計(jì)算。
② 易用性
問題:
如何實(shí)現(xiàn)系統(tǒng)的易用性?
解決方案:
需要OLAP系統(tǒng)兼容JDBC和ODBC,同時(shí)支持標(biāo)準(zhǔn)的SQL。
提供界面化的操作,這種方式可以避免所有的運(yùn)營分析人員都具備Mysql等數(shù)據(jù)庫的環(huán)境,可以直接登入圖形化界面進(jìn)行查詢的操作。
③ QPS
問題:
如何提高QPS?
解決方案:
緩存,使用doris時(shí),增加比如partitioncache,或者結(jié)果級(jí)緩存,或者分區(qū)緩存機(jī)制來提升查詢效率。
多副本,設(shè)置多副本的方式,通過犧牲部分存儲(chǔ)空間,來提升QPS,但是這個(gè)效果有限。
提升機(jī)器的規(guī)模。
4. 管理

現(xiàn)狀:
早期我們碰到磁盤壞了,搞得手忙腳亂,替換磁盤或者是下機(jī)器操作時(shí)間很長(zhǎng),而且這個(gè)操作完成之后還涉及重新平衡數(shù)據(jù)或者數(shù)據(jù)遷移,這個(gè)過程非常麻煩。
問題:
如何降低運(yùn)維成本?
解決方案:
建設(shè)監(jiān)控和報(bào)警機(jī)制,進(jìn)行提前預(yù)防。
優(yōu)化節(jié)點(diǎn)的下線,在京東系統(tǒng)中,有兩種方式:
方式1:通過黑名單的方式,如果監(jiān)控到某個(gè)節(jié)點(diǎn)經(jīng)常不健康,我們會(huì)把它納入黑名單,并將他踢下線了。
方式2:通過腳本操作,但是從最開始我們需要替換一個(gè)節(jié)點(diǎn),估計(jì)從發(fā)現(xiàn)到替換完成得三小時(shí),現(xiàn)在通過一些比較自動(dòng)化的東西,現(xiàn)在大概十分鐘左右能做到一個(gè)節(jié)點(diǎn)的替換。
▌發(fā)展歷程
1.0時(shí)代

1.0時(shí)代的場(chǎng)景比較少,數(shù)據(jù)量也比較少,主要是訂單相關(guān)的一些數(shù)據(jù),分析通過關(guān)系型數(shù)據(jù)庫就能搞定,比如說oracle或者mysql。
可通過數(shù)據(jù)儲(chǔ)備同步到備庫做分析,或者mysql一個(gè)是slave庫,主庫做一些利用線上業(yè)務(wù),然后備庫對(duì)存貨的一些分析和查詢。
2.0時(shí)代

到了2.0場(chǎng)景,不再是簡(jiǎn)單處理訂單問題,還要處理物流、供應(yīng)鏈、客服、支付等等場(chǎng)景。
場(chǎng)景大增,數(shù)據(jù)量也爆發(fā)式增長(zhǎng),從原來的G到現(xiàn)在的TB甚至PB級(jí)別。傳統(tǒng)關(guān)系性數(shù)據(jù)庫,已經(jīng)不能滿足需求了。
這個(gè)時(shí)候我們開始搭建了離線數(shù)倉,在數(shù)倉中進(jìn)行分析,主要用Hive和Spark進(jìn)行計(jì)算,數(shù)據(jù)都是T-1,臨時(shí)查詢數(shù)據(jù)的體驗(yàn)非常差,需要耗時(shí)分鐘級(jí)別且還是昨天的數(shù)據(jù)。
3.0時(shí)代

為提升查詢數(shù)據(jù)的速度和數(shù)據(jù)的時(shí)效性,開始做實(shí)時(shí)查詢。我們現(xiàn)在使用統(tǒng)一OLAP服務(wù),從最開始使用Kylin處理一些離線的業(yè)務(wù),到現(xiàn)在我們用了doris和clickhouse結(jié)合起來,同時(shí)處理實(shí)時(shí)和離線,統(tǒng)一服務(wù)接口,對(duì)用戶和開發(fā)人員開放。
同時(shí)針對(duì)不同的業(yè)務(wù),提供不同的計(jì)算引擎,我們現(xiàn)在提供一個(gè)整體打包解決方案,業(yè)務(wù)只需要在OLAP的服務(wù)上,進(jìn)行統(tǒng)一部署到數(shù)據(jù)技術(shù)平臺(tái)即可,大大減少了開發(fā)成本。
未來規(guī)劃

① 管理平臺(tái)優(yōu)化
ClickHouse的動(dòng)態(tài)伸縮。
智能化運(yùn)維。智能優(yōu)化節(jié)點(diǎn)上下線或者數(shù)據(jù)均衡這些方面的工作。主要想要通過減少人工干預(yù)操作,降低時(shí)間的浪費(fèi)。在京東的系統(tǒng)中,現(xiàn)在擁有上千臺(tái)的服務(wù)器,如果一直由人工來處理的話,那么成本非常高。
② 優(yōu)化查詢速度
優(yōu)化實(shí)時(shí)計(jì)算緩存。在doris中,使用partitioncacahe或者sqlcache在離線場(chǎng)景中比較有效,后續(xù)將考慮在實(shí)時(shí)計(jì)算中引入緩存進(jìn)行優(yōu)化。
索引智能化管理。索引的引擎有非常多種,如果需要開發(fā)人員了解所有的引擎,學(xué)習(xí)成本是比較高的,我們能不能做成智能化的索引引擎呢?這樣的話用戶不需要再去關(guān)心類似的一個(gè)索引怎么建的問題,而是我們?cè)谕ㄟ^用戶的一些查詢行為分析,自動(dòng)的來給他做索引的創(chuàng)建,這樣簡(jiǎn)化工作成本,讓開發(fā)人員有更多的心思去做好運(yùn)營和分析。
▌問答環(huán)節(jié)
Q1:請(qǐng)問老師貴司有用過druid引擎嗎?
A1:沒有,我們調(diào)研發(fā)現(xiàn),第一,druid對(duì)sql的支持不是很友好;第二,druid擅長(zhǎng)于持續(xù)性的數(shù)據(jù)場(chǎng)景,但是京東訂單是一個(gè)頻繁發(fā)生狀態(tài)變化的一個(gè)場(chǎng)景,它是不太好處理的,所以當(dāng)時(shí)我們也沒有選druid。
Q2:clickhouse和doris如何根據(jù)業(yè)務(wù)場(chǎng)景選型,有哪些坑?
A2:
第一,查詢性能:在查詢表不多即沒有太多表關(guān)聯(lián)情況下,clickhouse查詢速度比較快,但是在做大表關(guān)聯(lián)查詢時(shí),doris的性能會(huì)好于clickhouse。
第二,QPS:clickhouse是在極限使用CPU的性能,但是doris的QPS性能在某些場(chǎng)景下會(huì)比clickhouse好。
第三,運(yùn)維成本:doris的運(yùn)維成本會(huì)小于clickhouse,至少現(xiàn)在對(duì)我們來看,因?yàn)樗鼤?huì)有節(jié)點(diǎn)自動(dòng)上下線擴(kuò)容收容會(huì)很方便,但是clickhouse做這個(gè)方面比較麻煩。
第四,數(shù)據(jù)更新:clickhouse數(shù)據(jù)更新的引擎有三種,用戶在使用的時(shí)候比較麻煩,但是doris,它直接進(jìn)行數(shù)據(jù)覆蓋,就能做到一個(gè)更新,操作更方便。
Q3:doris和clickhouse是自動(dòng)選擇,還是需要用戶自己去選,如果是自動(dòng)選的話,識(shí)別機(jī)制是什么樣的?
A3:目前還沒有做到自動(dòng)選。當(dāng)前先整體提供解決方案,我們?yōu)橛脩籼峁┘夹g(shù)支撐,未來可能會(huì)想著如何去打通統(tǒng)一化,因?yàn)樗哪P蛣?chuàng)建不太一樣,它的sql是有差異的。
Q4:數(shù)據(jù)接入CK方面,京東目前是什么樣的方案?
A4:目前有兩條路線。
一個(gè)是用戶自己業(yè)務(wù)側(cè)接入,因?yàn)橛行v史原因,用戶他已經(jīng)用了很久的clickhouse,他自己有比較成熟的一套接入系統(tǒng)。
一個(gè)是使用clickhouse來接入,不管是從離線還是從kafka中,這種方式是我們?cè)谄脚_(tái)側(cè),在平臺(tái)側(cè)開發(fā)了統(tǒng)一的OLAP服務(wù),用戶可以上面操作。就如前面所說,用戶選擇數(shù)據(jù)源,再選一個(gè)目標(biāo)源,點(diǎn)擊它執(zhí)行導(dǎo)入,就可以完成。
