Apache Kylin是怎樣在百度地圖實(shí)踐的,相信很多沒有經(jīng)驗(yàn)的人對(duì)此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個(gè)問題。
臨朐網(wǎng)站建設(shè)公司成都創(chuàng)新互聯(lián)公司,臨朐網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為臨朐千余家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站建設(shè)要多少錢,請(qǐng)找那個(gè)售后服務(wù)好的臨朐做網(wǎng)站的公司定做!
百度地圖開放平臺(tái)業(yè)務(wù)部數(shù)據(jù)智能組主要負(fù)責(zé)百度地圖內(nèi)部相關(guān)業(yè)務(wù)的大數(shù)據(jù)計(jì)算分析,處理日常百億級(jí)規(guī)模數(shù)據(jù),為不同業(yè)務(wù)提供單條SQL毫秒級(jí)響應(yīng)的OLAP多維分析查詢服務(wù)。
對(duì)于Apache Kylin在實(shí)際生產(chǎn)環(huán)境中的應(yīng)用,在國內(nèi),百度地圖數(shù)據(jù)智能組是最早的一批實(shí)踐者之一。Apache Kylin在2014年11月開源,當(dāng)時(shí),我們團(tuán)隊(duì)正需要搭建一套完整的大數(shù)據(jù)OLAP分析計(jì)算平臺(tái),用來提供百億行級(jí)數(shù)據(jù)單條SQL毫秒到秒級(jí)的多維分析查詢服務(wù),在技術(shù)選型過程中,我們參考了Apache Drill、Presto、Impala、Spark SQL、Apache Kylin等。對(duì)于Apache Drill和Presto因生產(chǎn)環(huán)境案例較少,考慮到后期遇到問題難以交互討論,且Apache Drill整體發(fā)展不夠成熟。對(duì)于Impala和Spark SQL,主要基于內(nèi)存計(jì)算,對(duì)機(jī)器資源要求較高,單條SQL能夠滿足秒級(jí)動(dòng)態(tài)查詢響應(yīng),但交互頁面通常含有多條SQL查詢請(qǐng)求,在超大規(guī)模數(shù)據(jù)規(guī)模下,動(dòng)態(tài)計(jì)算亦難以滿足要求。后來,我們關(guān)注到了基于MapReduce預(yù)計(jì)算生成Cube并提供低延遲查詢的Apache Kylin解決方案,并于2015年2月左右在生產(chǎn)環(huán)境完成了Apache Kylin的首次完整部署。
Apache Kylin是一個(gè)開源的分布式分析引擎,提供Hadoop之上的SQL查詢接口及多維分析(OLAP)能力以支持超大規(guī)模數(shù)據(jù),最初由eBay Inc. 開發(fā)并貢獻(xiàn)至開源社區(qū),并于2015年11月正式畢業(yè)成為Apache頂級(jí)項(xiàng)目。
我們在Apache Kylin集群上跑了多個(gè)Cube測試,結(jié)果表明它能夠有效解決大數(shù)據(jù)計(jì)算分析的3大痛點(diǎn)問題。
痛點(diǎn)一:百億級(jí)海量數(shù)據(jù)多維指標(biāo)動(dòng)態(tài)計(jì)算耗時(shí)問題,Apache Kylin通過預(yù)計(jì)算生成Cube結(jié)果數(shù)據(jù)集并存儲(chǔ)到HBase的方式解決。
痛點(diǎn)二:復(fù)雜條件篩選問題,用戶查詢時(shí),Apache Kylin利用router查找算法及優(yōu)化的HBase Coprocessor解決;
痛點(diǎn)三:跨月、季度、年等大時(shí)間區(qū)間查詢問題,對(duì)于預(yù)計(jì)算結(jié)果的存儲(chǔ),Apache Kylin利用Cube的Data Segment分區(qū)存儲(chǔ)管理解決。
這3個(gè)痛點(diǎn)的解決,使我們能夠在百億級(jí)大數(shù)據(jù)規(guī)模下,且數(shù)據(jù)模型確定的具體多維分析產(chǎn)品中,達(dá)到單條SQL毫秒級(jí)響應(yīng)。因此,我們對(duì)Apache Kylin產(chǎn)生了較高的興趣,大數(shù)據(jù)計(jì)算查詢分析的應(yīng)用中,一個(gè)頁面通常需要多條SQL查詢,假設(shè)單條SQL查詢需要2秒響應(yīng),頁面共有5個(gè)SQL請(qǐng)求,總共就需要10秒左右,這是不可接受的。而此時(shí),Apache Kylin對(duì)于一個(gè)頁面多條SQL查詢響應(yīng)的優(yōu)勢就尤為突出。
在實(shí)踐過程中,根據(jù)公司不同業(yè)務(wù)的需求,我們數(shù)據(jù)智能團(tuán)隊(duì)的大數(shù)據(jù)OLAP平臺(tái)后臺(tái)存儲(chǔ)與查詢引擎采用了由Apache Kylin、Impala及Spark SQL組成,在中小數(shù)據(jù)規(guī)模且分析維度指標(biāo)較為隨機(jī)的情況下,平臺(tái)可提供Impala或Spark SQL服務(wù);在超大規(guī)模百億級(jí)行數(shù)據(jù)的具體產(chǎn)品案例上,因查詢性能需求較高,同時(shí)具體產(chǎn)品對(duì)其需要分析的維度和指標(biāo)較為明確,我們使用Apache Kylin解決方案。下文將主要介紹Apache Kylin在百度地圖內(nèi)部的實(shí)踐使用。
(點(diǎn)擊放大圖像)
數(shù)據(jù)接入:主要負(fù)責(zé)從數(shù)據(jù)倉庫端獲取業(yè)務(wù)所需的最細(xì)粒度的事實(shí)表數(shù)據(jù)。
任務(wù)管理:主要負(fù)責(zé)Cube的相關(guān)任務(wù)的執(zhí)行、管理等。
任務(wù)監(jiān)控:主要負(fù)責(zé)Cube任務(wù)在執(zhí)行過程中的狀態(tài)及相應(yīng)的操作管理。
集群監(jiān)控:主要包括Hadoop生態(tài)進(jìn)程的監(jiān)控及Kylin進(jìn)程的監(jiān)控。
因業(yè)務(wù)特殊性,我們并未采用公司內(nèi)部的Hadoop集群進(jìn)行計(jì)算、存儲(chǔ)和查詢,而是獨(dú)立部署一臺(tái)完整的集群,并獨(dú)立維護(hù)。
集群機(jī)器:共4臺(tái),1臺(tái)master(100G內(nèi)存) + 3臺(tái)slaves(30G內(nèi)存)。
軟件環(huán)境:CDH + Hive + HBase + Kylin 0.71
對(duì)于任何一個(gè)數(shù)據(jù)計(jì)算處理平臺(tái),數(shù)據(jù)的接入十分關(guān)鍵,就像熟知的Spark,對(duì)數(shù)據(jù)接入也是十分重視。目前,我們的大數(shù)據(jù)OLAP平臺(tái)可以支持2種數(shù)據(jù)源的引入: MySQL數(shù)據(jù)源及HDFS數(shù)據(jù)源。在實(shí)踐中,我們遇到一個(gè)問題,假設(shè)MySQL及HDFS數(shù)據(jù)源沒有標(biāo)識(shí)表示T-1天的數(shù)據(jù)已經(jīng)計(jì)算完成的情況下,如何確定T-1天的數(shù)據(jù)已經(jīng)準(zhǔn)備就緒。對(duì)于Hive數(shù)據(jù)源,查詢數(shù)據(jù)所在Hive Meta的partition是否就緒;對(duì)于MySQL,我們目前想到的辦法是間隔一定時(shí)間循環(huán)探測當(dāng)天數(shù)據(jù)行數(shù)是否變化,如果沒有變化,我們基本能夠簡單認(rèn)為第T-1天的數(shù)據(jù)已經(jīng)由數(shù)據(jù)倉庫計(jì)算完畢,接下來就可以觸發(fā)數(shù)據(jù)拉取模塊邏輯將數(shù)據(jù)拉取到Master節(jié)點(diǎn)的本地文件系統(tǒng)中,根據(jù)業(yè)務(wù)判斷是否需要對(duì)這些數(shù)據(jù)細(xì)加工,然后,導(dǎo)入到Master的Hive中,觸發(fā)事實(shí)表對(duì)應(yīng)任務(wù)涉及到的所有cube,啟動(dòng)MapReduce計(jì)算,計(jì)算結(jié)束后,前端可以刷新訪問最新數(shù)據(jù)。另外,如果到了指定時(shí)間,發(fā)現(xiàn)數(shù)據(jù)倉庫端的數(shù)據(jù)仍舊沒有準(zhǔn)備好,數(shù)據(jù)接入模塊會(huì)短信報(bào)警給倉庫端,并繼續(xù)循環(huán)檢測直至指定時(shí)刻退出。
(點(diǎn)擊放大圖像)
數(shù)據(jù)引入模塊
任務(wù)管理對(duì)于計(jì)算型平臺(tái)服務(wù)十分重要,也是我們大數(shù)據(jù)OLAP多維分析平臺(tái)的核心擴(kuò)展工作之一。對(duì)于用戶而言,Apache Kylin對(duì)于Cube的最小存儲(chǔ)單位為data segment,類似于Hive的partition,data segment采用左閉右開區(qū)間表示,如[2015-11-01,2015-11-02)表示含有2015-11-01這一天的數(shù)據(jù)。對(duì)于Cube數(shù)據(jù)的管理主要基于data segment粒度,大致分為3種操作: 計(jì)算(build)、更新(refresh)、合并(merge)。對(duì)于一個(gè)具體產(chǎn)品來說,它的數(shù)據(jù)是需要每天例行計(jì)算到cube中,正常例行下,每天會(huì)生成1個(gè)data segment,但可能會(huì)因?yàn)閿?shù)據(jù)倉庫的任務(wù)延遲,2天或多天生成1個(gè)segment。隨著時(shí)間推移,一方面,大量的data segment嚴(yán)重影響了性能,另一方面,這也給管理帶來了困難和麻煩。因此,對(duì)于1個(gè)cube,我們按照1個(gè)自然月為1個(gè)data segment,清晰且易管理。
假設(shè)我們有1個(gè)月30天的數(shù)據(jù),共23個(gè)data segment數(shù)據(jù)片段,如:[2015-11-01,2015-11-02), [2015-11-02,2015-11-04), [2015-11-04,2015-11-11), [2015-11-11,2015-11-12), [2015-11-12,2015-11-13), 。。。[2015-11-30,2015-12-01)
問題1: 假設(shè)因?yàn)閿?shù)據(jù)有問題,需要回溯2015-11-01的數(shù)據(jù),因?yàn)槲覀兡軌蛟赾ube中找到[2015-11-01,2015-11-02)這樣一個(gè)data segment,滿足這個(gè)時(shí)間區(qū)間,于是,我們可以直接界面操作或者Rest API啟動(dòng)這個(gè)data segment的refresh更新操作。
問題2: 假設(shè)我們需要回溯2015-11-02到2015-11-03的數(shù)據(jù),同理,可以找到一個(gè)符合條件的data segment [2015-11-02,2015-11-04),然后refresh更新這個(gè)data segment。
問題3: 假設(shè)我們需要回溯2015-11-01到2015-11-02的數(shù)據(jù),我們找不到直接滿足時(shí)間區(qū)間的data segment。于是我們有2種解決方案,第1種方案是分別依次refresh更新 [2015-11-01,2015-11-02), [2015-11-02,2015-11-04)這2個(gè)data segment實(shí)現(xiàn);第2種方案是先合并(merge)[2015-11-01,2015-11-02), (2015-11-02,2015-11-04)這兩個(gè)data segment,合并后得到[2015-11-01,2015-11-04)這樣1個(gè)data segment,然后我們再拉取新數(shù)據(jù)后執(zhí)行更新操作,即可滿足需求。
問題4: 假設(shè)我們需要刷新2015-11-01~2015-11-30這1個(gè)月的數(shù)據(jù),我們在另1套集群上基于Kylin 1.1.1對(duì)同一個(gè)cube進(jìn)行測試,如果采用問題3中的第1種方案,我們需要逐步刷新cube的23個(gè)data segment,大約耗時(shí)17.93min X 30=537分鐘; 如果我們采用問題3中的第2種方案, 那么我們只需要將23個(gè)data segment合并成[2015-11-01,2015-12-01)這1個(gè)data segment,計(jì)1次操作。然后再執(zhí)行1次更新操作,共2次操作即可完成需求,總體上,耗時(shí)約83.78分鐘,較第1種方法性能上提高很多。
基于上面的問題,目前我們平臺(tái)對(duì)Apache Kylin進(jìn)行了二次開發(fā),擴(kuò)展出了任務(wù)管理模塊。
對(duì)于cube的計(jì)算(build)操作,假設(shè)數(shù)據(jù)倉庫2015-11-29~2015-12-02的數(shù)據(jù)因故延遲,在2015年12-03天產(chǎn)出了(T-1天的數(shù)據(jù)),如果不判斷處理,就會(huì)例行計(jì)算生成一個(gè)時(shí)間區(qū)間為[2015-11-29,2015-12-03)的data segment。所以,在每個(gè)cube計(jì)算前,我們的邏輯會(huì)自動(dòng)檢測跨自然月問題,并生成[2015-11-29,2015-12-01)和[2015-12-01,2015-12-03)兩個(gè)data segment.
對(duì)于cube的更新(refresh)操作,我們會(huì)采用問題3、問題4中提到的第2種方案,自動(dòng)合并(merge)data segment后再執(zhí)行更新refresh操作。因?yàn)樯厦嬉呀?jīng)保證了不會(huì)有跨月data segment的生成,這里的自動(dòng)合并也不會(huì)遇到生成跨自然月的情況。
對(duì)于cube的合并(merge)操作,如果每天都自動(dòng)合并該自然月內(nèi)前面日期已有的所有data segment,假設(shè)我們想回溯更新2015-11-11這一天的數(shù)據(jù),那么就需要回溯(2015-11-01,2015-11-12)(因?yàn)檫@個(gè)時(shí)間區(qū)間的data segment每天都被自動(dòng)合并了),其實(shí),我們沒有必要回溯2015-11-01~2015-11-10這10天的數(shù)據(jù)。所以,對(duì)于1個(gè)自然月內(nèi)的cube的數(shù)據(jù),在當(dāng)月,我們先保留了1天1個(gè)data segment的碎片狀態(tài),因?yàn)樵诋?dāng)月發(fā)現(xiàn)前面某幾天數(shù)據(jù)有問題的概率大,回溯某個(gè)data segment小碎片就更加合理及性能更優(yōu)。對(duì)于上個(gè)月整個(gè)月的數(shù)據(jù),在下個(gè)月的中上旬時(shí)數(shù)據(jù)已經(jīng)比較穩(wěn)定,回溯的概率較小,通常要回溯也是上個(gè)月整月的數(shù)據(jù)。因此,在中上旬整體合并上1個(gè)月的數(shù)據(jù)而不是每天合并更合理。
(點(diǎn)擊放大圖像)
任務(wù)管理模塊
通常,1個(gè)產(chǎn)品對(duì)應(yīng)多個(gè)頁面,1頁面對(duì)應(yīng)1個(gè)事實(shí)表,1個(gè)事實(shí)表對(duì)應(yīng)多個(gè)cube,那么一個(gè)產(chǎn)品通常會(huì)包含多個(gè)cube,上面提到的cube基于data segment的3種任務(wù)狀態(tài),很難人為去核查,所以對(duì)于任務(wù)執(zhí)行的監(jiān)控是非常必要的,當(dāng)任務(wù)提交后,每隔一段時(shí)間檢測一次任務(wù)的狀態(tài),任務(wù)狀態(tài)中間失敗或者最后成功后,則會(huì)發(fā)送郵件或者短信報(bào)警通知用戶。
由于我們的服務(wù)器是團(tuán)隊(duì)內(nèi)部獨(dú)自部署維護(hù),為了高效監(jiān)控整套Hadoop集群、Hive,HBase、Kylin的進(jìn)程狀態(tài),以及處理海量臨時(shí)文件的問題,我們單獨(dú)開發(fā)了監(jiān)控邏輯模塊。一旦集群出現(xiàn)問題,能夠第一時(shí)間收到報(bào)警短信或者郵件。
平臺(tái)監(jiān)控模塊
由于我們以平臺(tái)方式提供給各個(gè)業(yè)務(wù)線使用,當(dāng)某個(gè)業(yè)務(wù)線的業(yè)務(wù)數(shù)據(jù)計(jì)算規(guī)模較大,會(huì)造成平臺(tái)現(xiàn)有資源緊張時(shí),我們會(huì)根據(jù)實(shí)際情況,要求業(yè)務(wù)方提供機(jī)器資源,隨之而來的就是如何根據(jù)業(yè)務(wù)方提供的機(jī)器資源分配對(duì)應(yīng)的計(jì)算隊(duì)列的資源隔離問題。目前,官方的Apache Kylin版本對(duì)于整個(gè)集群只能使用1個(gè)kylin_job_conf.xml, 平臺(tái)上所有項(xiàng)目的所有Cube的3種操作只能使用同一個(gè)隊(duì)列。于是,我們基于kylin-1.1.1-incubating這個(gè)tag的源碼做了相關(guān)修改,支持了以項(xiàng)目為粒度的資源隔離功能,并提交issue到https://issues.apache.org/jira/browse/KYLIN-1241,方案對(duì)于我們平臺(tái)管理員自身也參與項(xiàng)目開發(fā)的應(yīng)用場景下非常適用。對(duì)于某個(gè)項(xiàng)目,如果不需要指定特定計(jì)算隊(duì)列,無需在$KYLIN_HOME下指定該項(xiàng)目的kylin_job_conf.xml文件,系統(tǒng)會(huì)自動(dòng)調(diào)用官方原有的邏輯,使用默認(rèn)的Hadoop隊(duì)列計(jì)算。
資源隔離
因獨(dú)立部署的Hadoop集群硬件配置不高,內(nèi)存十分有限,所以,在項(xiàng)目實(shí)踐過程中也遇到不少問題。
調(diào)整MapReduce分配資源參數(shù):在cube計(jì)算過程中,會(huì)出現(xiàn)mr任務(wù)失敗,根據(jù)日志排查,主要因mr的內(nèi)存分配不足導(dǎo)致,于是,我們根據(jù)任務(wù)實(shí)際情況整體調(diào)整了yarn.nodemanager.resource.memory-mb,mapreduce.map.memory.mb, mapreduce.map.java.opts, mapreduce.reduce.memory.mb及mapreduce.reduce.java.opts等參數(shù)。
由于機(jī)器整體資源限制,我們給HBase配置的HBASE_HEAPSIZE值較小,隨著時(shí)間推移,平臺(tái)承載的項(xiàng)目越來越多,對(duì)內(nèi)存及計(jì)算資源要求也逐步提高。后來平臺(tái)在運(yùn)行過程中,HBase的RegionServer在不同節(jié)點(diǎn)上出現(xiàn)隨機(jī)down掉的現(xiàn)象,導(dǎo)致HBase不可用,影響了Kylin的查詢服務(wù),這個(gè)問題困擾了團(tuán)隊(duì)較長時(shí)間,通過網(wǎng)上資料及自身的一些經(jīng)驗(yàn),我們對(duì)HBase和Hadoop相關(guān)參數(shù)做了較多優(yōu)化。
A. HBase的JVM GC相關(guān)參數(shù)調(diào)優(yōu),開啟了HBase的mslab參數(shù):可以通過GC調(diào)優(yōu)獲得更好的GC性能,減少單次GC的時(shí)間和FULL GC頻率;
B. HBase的ZK連接超時(shí)相關(guān)參數(shù)調(diào)優(yōu):默認(rèn)的ZK超時(shí)設(shè)置太短,一旦發(fā)生FULL GC,極其容易導(dǎo)致ZK連接超時(shí);
C. ZK Server調(diào)優(yōu),提高maxSessionTimeout:ZK客戶端(比如Hbase的客戶端)的ZK超時(shí)參數(shù)必須在服務(wù)端超時(shí)參數(shù)的范圍內(nèi),否則ZK客戶端設(shè)置的超時(shí)參數(shù)起不到效果;
D. HBASE_OPTS參數(shù)調(diào)優(yōu):開啟CMS垃圾回收期,增大了PermSize和MaxPermSize的值;
Hadoop及HBase優(yōu)化
Hadoop及HBase優(yōu)化
對(duì)于Cube的設(shè)計(jì),官方有專門的相關(guān)文檔說明,里面有較多的指導(dǎo)經(jīng)驗(yàn),比如: cube的維度最好不要超過15個(gè), 對(duì)于cardinality較大的維度放在前面,維度的值不要過大,維度Hierarchy的設(shè)置等等。
實(shí)踐中,我們會(huì)將某個(gè)產(chǎn)品需求分為多個(gè)頁面進(jìn)行開發(fā),每個(gè)頁面查詢主要基于事實(shí)表建的cube,每個(gè)頁面對(duì)應(yīng)多張維度表和1張事實(shí)表,維度表放在MySQL端,由數(shù)據(jù)倉庫端統(tǒng)一管理,事實(shí)表計(jì)算后存放在HDFS中,事實(shí)表中不存儲(chǔ)維度的名稱,僅存儲(chǔ)維度的id,主要基于3方面考慮,第一:減少事實(shí)表體積;第二:由于我們的Hadoop集群是自己單獨(dú)部署的小集群,MapReduce計(jì)算能力有限,join操作希望在倉庫端完成,避免給Kylin集群帶來的Hive join等計(jì)算壓力;第三:減少回溯代價(jià)。 假設(shè)我們把維度名稱也存在Cube中,如果維度名稱變化必然導(dǎo)致整個(gè)cube的回溯,代價(jià)很大。這里可能有人會(huì)問,事實(shí)表中只有維度id沒有維度name,假設(shè)我們需要join得到查詢結(jié)果中含有維度name的記錄,怎么辦呢?對(duì)于某個(gè)產(chǎn)品的1個(gè)頁面,我們查詢時(shí)傳到后臺(tái)的是維度id,維度id對(duì)應(yīng)的維度name來自MySQL中的維度表,可以將維度name查詢出來并和維度id保存為1個(gè)維度map待后續(xù)使用。同時(shí),一個(gè)頁面的可視范圍有限,查詢結(jié)果雖然總量很多,但是每一頁返回的滿足條件的事實(shí)表記錄結(jié)果有限,那么,我們可以通過之前保存的維度map來映射每列id對(duì)應(yīng)的名稱,相當(dāng)于在前端邏輯中完成了傳統(tǒng)的id和name的join操作。
比如我們的事實(shí)表有個(gè)detail分區(qū)數(shù)據(jù),detail分區(qū)包含最細(xì)粒度os和appversion兩個(gè)維度的數(shù)據(jù)(注意: cuid維度的計(jì)算在倉庫端處理),我們的cube設(shè)計(jì)也選擇os和appversion,hierarchy層次結(jié)構(gòu)上,os是appversion的父親節(jié)點(diǎn),從os+appversion(group by os, appversion)組合維度來看,統(tǒng)計(jì)的用戶量沒有問題,但是按照os(group by os)單維度統(tǒng)計(jì)用戶量時(shí),會(huì)從基于這個(gè)detail分區(qū)建立的cube向上匯總計(jì)算,設(shè)上午用戶使用的是android 8.0版本,下午大量用戶升級(jí)到android 8.1版本,android 8.0組合維度 + android 8.1組合維度向上計(jì)算匯總得到os=android(group by os, where os=android)單維度用戶,數(shù)據(jù)會(huì)膨脹且數(shù)據(jù)不準(zhǔn)確。因此我們?yōu)槭聦?shí)表增加一個(gè)agg分區(qū),agg分區(qū)包含已經(jīng)從cuid粒度group by去重后計(jì)算好的os單維度結(jié)果。這樣,當(dāng)用戶請(qǐng)求os維度匯總的情況下,Apache Kylin會(huì)根據(jù)router算法,計(jì)算出符合條件的候選cube集合,并按照權(quán)重進(jìn)行優(yōu)選級(jí)排序(熟悉MicroStrategy等BI產(chǎn)品的同學(xué)應(yīng)該知道這類案例),選擇器會(huì)選中基于agg分區(qū)建立的os單維度agg cube,而不從detail這個(gè)分區(qū)建立的cube來自底向上從最細(xì)粒度往高匯總,從而保證了數(shù)據(jù)的正確性。
對(duì)應(yīng)小規(guī)模集群,計(jì)算資源是非常寶貴的,假設(shè)我們對(duì)于某個(gè)項(xiàng)目的留存分析到了日對(duì)1日到日對(duì)30日,日對(duì)1周到日對(duì)4周,日對(duì)1月到日對(duì)4月,周對(duì)1周到周對(duì)4周,月對(duì)1月到月對(duì)4月。那么對(duì)于傳統(tǒng)的存儲(chǔ)方案,我們將遇到問題。
假如今天是2015-12-02,我們計(jì)算實(shí)際得到的是2015-12-01的數(shù)據(jù)
(點(diǎn)擊放大圖像)
上面數(shù)據(jù)存儲(chǔ)方案的思路是,當(dāng)今天是2015-12-02,那么2015-12-01可以計(jì)算活躍用戶了,于是,我們會(huì)將2015-11-30的日對(duì)第1日留存, 2015-11-29的日對(duì)第2日, 2015-11-28的日對(duì)第3日等的這些列指標(biāo)數(shù)據(jù)進(jìn)行更新(如上紅色對(duì)角線部分),這是因?yàn)槊刻鞌?shù)據(jù)的每1列都是以當(dāng)天為基準(zhǔn),等今后第n天到了,再回填這1天的這些第x日留存,如此,對(duì)于1個(gè)任務(wù)會(huì)級(jí)聯(lián)更新之前的多天歷史數(shù)據(jù),如上紅色對(duì)角線的數(shù)據(jù)。
此方案的優(yōu)勢:
a, 如果要查看某個(gè)時(shí)間范圍內(nèi)的某一個(gè)或者多個(gè)指標(biāo),可以直接根據(jù)時(shí)間區(qū)間,選擇需要的列指標(biāo)即可。
b, 如果要查看某1天的多個(gè)指標(biāo),也可以直接選擇那1天的多個(gè)指標(biāo)即可
此方案的缺點(diǎn):
a, 每天都需要更新歷史數(shù)據(jù),如上紅色對(duì)角線的數(shù)據(jù),造成大量MapReduce任務(wù)預(yù)計(jì)算cube,需要較多的機(jī)器計(jì)算資源支持。
b, 如果今后增加新的留存,比如半年留存,年留存,那么對(duì)角線長度就更長,每天就需要回溯更新更多天數(shù)的歷史數(shù)據(jù),需要更多時(shí)間跑任務(wù)。
c, 對(duì)于級(jí)聯(lián)更新的大量的歷史數(shù)據(jù)任務(wù),其實(shí)依賴性很強(qiáng),如何保證留存項(xiàng)目多個(gè)cube每一天的多個(gè)data segment級(jí)聯(lián)更新正確,非常復(fù)雜,難以維護(hù)和監(jiān)控,對(duì)于數(shù)據(jù)倉庫端也易遇到如此問題。
d, 對(duì)于需要批量回溯一個(gè)較大時(shí)間區(qū)間的歷史數(shù)據(jù)時(shí),問題3中涉及的任務(wù)計(jì)算難點(diǎn)和困難尤為突出。
假如今天是2015-12-02,我們計(jì)算實(shí)際得到的是2015-12-01的數(shù)據(jù)(可和上面的結(jié)構(gòu)對(duì)比)
(點(diǎn)擊放大圖像)
此方案的思路是,當(dāng)今天是2015-12-02,實(shí)際是2015-12-01的數(shù)據(jù),如上示例存儲(chǔ),但日對(duì)第n日的留存表示的是n日前對(duì)應(yīng)的那個(gè)日期的留存量,相當(dāng)于旋轉(zhuǎn)了紅色對(duì)角線。
此方案的優(yōu)勢:
a, 如果要查看某個(gè)時(shí)間范圍內(nèi)的某1個(gè)指標(biāo),直接選擇該范圍的該列指標(biāo)即可
b, 如果今后增加新的留存,比如半年留存,年留存等指標(biāo),不需要級(jí)聯(lián)更新歷史天數(shù)的數(shù)據(jù),只需要更新2015-12-01這1天的數(shù)據(jù),時(shí)間復(fù)雜度O(1)不變,對(duì)物理機(jī)器資源要求不高。
此方案的缺點(diǎn):
a, 如果涉及到某1天或者某個(gè)時(shí)間范圍的多列指標(biāo)查詢,需要前端開發(fā)留存分析特殊處理邏輯,根據(jù)相應(yīng)的時(shí)間窗口滑動(dòng),從不同的行,選擇不同的列,然后渲染到前端頁面。
目前,我們在項(xiàng)目中采用變通的存儲(chǔ)方案。
看完上述內(nèi)容,你們掌握Apache Kylin是怎樣在百度地圖實(shí)踐的的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!