美團各業務線存在大量的OLAP分析場景,需要基于Hadoop數十億級別的數據進行分析,直接響應分析師和城市BD等數千人的交互式訪問請求,對OLAP服務的擴展性、穩定性、數據精確性和性能均有很高要求。本文主要介紹美團的具體OLAP需求,如何將Kylin應用到實際場景中,以及目前的使用方式和現狀。同時也將Kylin和其它系統(如Presto、Druid等)進行了對比,闡述了Kylin的獨特優勢。
作爲公司的平台部門,需要給各個業務線提供平台的服務,那麽如何建設一個滿足各種需求的公司平台級OLAP分析服務呢。首先,一個開源項目在公司真正落地會遇到很多障礙,這主要是由各個業務線不同的數據特點和業務特點決定的,所以本文會介紹一下美團的數據場景有什麽特點;其次,針對這些數據特點,尤其是和Kylin設計初衷不太相符的部分,有什麽樣的解決方案;第三,目前OLAP領域還沒有所謂事實上的標准,很多引擎都可以做類似事情,比如普通的MPP,Kylin,或者ES等。這些系統之間的對比情況如何,應該如何選擇,我們也有部分測試數據可以分享;最後,簡單討論一下未來准備在Kylin上做的工作。
1、美團的數據場景特點
第一個特點是數據規模和模型特點。一方面從數據規模上來講,事實表一般在1億到10億量級,同時還有千萬量級的維表,也就是超高基數的維表。另一方面,數據模型是一開始遇到的最大困難。因爲Kylin最初的設計是基于一個星形模型的,但很不幸由于各種原因,很多數據都是雪花的模型,還有其它的模型,比如所謂“星座”模型,也就是中間是兩張或者三張事實表,周圍關聯了其它很多維表。業務邏輯決定了這些數據的關聯方式非常複雜,根本無法用經典標准的理論來解釋。
第二個是維度。維度最理想的情況是固定的,每天變化的只是事實表。但實際上維度經常會變,這可能和行業特點有關,比如組織架構,相關的維度數據可能每天都會變化。除此之外還可能要用今天的維度去關聯所有的曆史數據,因此要重刷曆史數據,相應的開銷也比較大。
第三個是數據回溯的問題。比如發現數據生成有問題,或者上遊出錯了,此時就需要重跑數據。這也是和經典理論模型有區別的。
從維度的角度來看,一般維度的個數在5-20個之間,相對來說還是比較適合用Kylin的。另一個特點是一般都會有一個日期維度,有可能是當天,也有可能是一個星期,一個月,或者任意一個時間段。另外也會有較多的層次維度,比如組織架構從最上面的大區一直到下面的蜂窩,就是一個典型的層次維度。
從指標的角度來講,一般情況下指標個數在50個以內,相對來說Kylin在指標上的限制並沒有那麽嚴格,都能滿足需求。其中有比較多的表達式指標,在Kylin裏面聚合函數的參數只能是單獨的一列,像sum(if…)這種就不能支持,因此需要一些特別的解決方法。另外一個非常重要的問題是數據的精確性,目前在OLAP領域,各個系統都是用hyperloglog等近似算法做去重計數,這主要是出于開銷上的考慮,但我們的業務場景要求數據必須是精確的。因此這也是要重點解決的問題。
在查詢上也有比較高的要求。因爲平台的查詢服務可能直接向城市BD開放,每次會有幾十、上百萬次的訪問,所以穩定性是首先要保證的。第二要求有很高的性能。因爲用Kylin主要是爲了實現交互式的分析,讓使用者能夠很快拿到結果,所以需要秒級響應。
另外經常會有人問到,Kylin有沒有可視化的前端,在我們內部更多是由業務方來做,因爲原來本身就有這樣的系統,以前接的是MySQL等其它的數據源,現在可以直接使用Kylin的JDBC driver對接起來。
以上是美團在OLAP查詢方面的一些特點。在用Kylin之前,實際上有一些方案,但效果並不理想。比如用Hive直接去查,這種情況下,第一個是慢,第二會消耗計算集群的資源。尤其每個月第一天,大家都要出月報,跑的SQL非常多,全提到集群上去,並發度限制導致跑的比平時更慢。我們原來也做過預聚合的嘗試,這個思路跟Kylin很像,只不過是自己做這個事,用Hive先把所有的維度算出來,然後導入MySQL或者HBase。但是這個方案並沒有像Kylin這麽好的模型定義抽象,也沒有從配置到執行,預計算,查詢這樣整體的框架。現在通過使用Kylin實現了低成本的解決這些問題。
2、接入Apache Kylin的解決方案
針對上述的問題,經過大量的嘗試和驗證,目前主要的解決方案有以下幾點。
最重要的第一點,就是采用寬表。所有非標准星型的數據模型,都可以通過預處理先拉平,做成一個寬表來解決。只要能根據業務邏輯把這些表關聯起來,生成一張寬表,然後再基于這張表在Kylin裏做數據的聚合就可以了。寬表不只能解決數據模型的問題,還能解決維度變化、或者超高基數的維度等問題。
第二點是表達式指標的問題,也可以通過提前處理解決。把表達式單獨轉成一列,再基于這列做聚合就可以了。實際上寬表和表達式變換的處理可以用hive的view,也可以生成物理表。
第三個是精確去重的問題,目前的方案是基于Bitmap。由于數據類型的限制,目前只支持int類型,其它包括long、string等類型還不支持。因爲需要把每個值都能映射到Bitmap裏,如果是long的話開銷太大。如果用哈希的話就會沖突,造成結果不准確。另外Bitmap本身開銷也是比較大的,尤其跑預計算的時候,如果算出來的基數很大,對應的數據結構就是幾十兆,內存會有OOM的風險。這些問題後面我們也會想一些辦法解決,也歡迎在社區裏一起討論。(補充說明:目前已在1.5.3版本中實現了全類型精確去重計數的支持。)
從整個系統的部署方式上來說,目前Server采用了分離部署的方式。Kylin Server本質上就是一個客戶端,並不需要太多資源,一般情況下使用虛擬機就能夠滿足需求。
實際的部署情況可以看這張圖,左下角的是hadoop主集群,用于執行每天所有hadoop作業。中間最重要的是Kylin01和02這兩個server,是用于線上環境的serve。其中kylin01是生産環境,這個環境一方面要負責從主機群上跑計算,把數據導到HBase,另外也要響應前端的請求,從HBase裏讀數據。如果想新增一個Cube的話,需要在kylin02上操作,也就是預上線環境。所有業務方人員的cube數據模型定義都是在kylin02上做,沒有問題後由管理員切到kylin01上。
這樣做的一個好處是kylin01作爲一個線上服務能保證穩定性,甚至權限控制能更嚴格一些;第二,預上線環境下開發完成後,管理員可以在投入生産前進行一次review,保證cube的效率。
右上角是另外的調度系統。整個數據倉庫的數據生産都是通過這個調度系統來調度的,其中的任務類型很多,Kylin的cube build任務也是作爲其中的一種類型。在上遊的數據就緒以後,根據配置的依賴關系,自動觸發Cube建立的過程。
左上角這邊還有一個完全獨立的線下測試集群,這個集群是完全開放的,主要是給用戶做一些最開始的可行性調研或者評估的工作,但同時也不保證穩定性。
一個開源的系統從社區拿回來,到真正的落地,再到上生産,這個過程相對還是比較長的,這裏並沒有太多的技術問題,更多的是一些流程上的經驗。就是如何在各個階段給業務方提供更好的服務,使得接入Kylin的過程更順暢,溝通成本更低。整個過程主要分爲四個階段。
第一個階段是方案選型,業務方根據業務需求,選擇一些方案進行調研。我們在這個階段提供了需求的Checklist,從數據模型,維度各個方面列出來比較詳細的點,可以讓業務方自己對照,確定需求是不是能夠被滿足。
在確定Kylin能滿足需求的基礎上,接下來是第二步,線下探查,也就是線下評估或者測試。我們提供了非常詳細的接入文檔,以及線下測試的環境。第三步是線上開發,我們也有一些文檔支持,基于抽象出來的場景,每個場景怎麽配置Cube,或者做哪些預處理,如何優化等,能夠給業務方一個指導性的意見。
最後是開發完成後的切表上線。這個過程目前還是由管理員來操作,一方面是爲了避免誤操作或者濫操作,另一方面也會對cube進行review,幫助進行優化。
3、主流OLAP系統對比分析
通過和其它同學交流,有一個感覺就是大家都覺得Kylin還不錯,但並不是特別有信心,或者不知道非要用它的理由是什麽,或者它和其它系統的對比是什麽樣的?這裏也有部分測試結果可以和大家分享。
整個測試基于SSB的數據集,也是完全開源的,實際上是專門用于星型模型OLAP場景下的測試。整個測試數據集是非常標准的五張表,可以配置一些參數決定生成的數據集規模,然後在不同的規模下做不同查詢場景的測試。現在已經完成的測試的系統包括:Presto,Kylin1.3,Kylin1.5和Druid。數據規模包含千萬、億、十億三種規模;維度個數爲30個;指標個數爲50個。典型的測試場景包括:上卷、下鑽,和常用的聚合函數。
這裏挑選了典型的五個查詢場景:一個事實表的過濾和聚合;五張表全關聯之後的查詢;兩個Count Dstinct指標和兩個Sum指標;後面兩個查詢包含8~10個的維度過濾。
這張圖是千萬規模下的一個測試結果,包括了四個系統。我們在用Kylin或者其它系統之前沒有專門用于OLAP分析的引擎,只能用通用的。Presto是其中表現非常好的引擎,但是在OLAP這種特定的場景下,可以看到不管跟Kylin還是Druid相比差的都比較多,所以前兩個測試包含了Presto結果,後面就沒有包含了。
這裏比較有趣的現象是在第三個查詢,Kylin1.5反而比Kylin1.3要慢一些。這個地方我們還沒有搞清楚是什麽原因,後面會詳細的看一下。當然這個也可以證明數據沒有修改過,是真實的測試數據。
從後面的兩個查詢上可以看到,在千萬規模的級別,和Druid還是有比較大的差距。這主要和它們的實現模式相關,因爲Druid會把所有的數據預處理完以後都加載到內存裏,在做一些小數據量聚合的時候,可以達到非常快的速度;但是Kylin要到HBase上讀,相對來說它的性能要差一些,但也完全能滿足需求。
在億級的規模上情況又有了變化,還是看後面兩個查詢,Kylin1.3基本上是一個線性的增長,這個數據已經變得比較難看了,這是由于Kylin1.3在掃描HBase的時候是串行方式,但是Kylin1.5反而會有更好的表現,這是因爲Kylin1.5引入了HBase並行Scan,大大降低了掃描的時間。Kylin1.5的數據會shard到不同的region上,在千萬量級上數據量還比較小,沒有明顯的體現,但是上億以後,隨著數據量上升,region也變多了,反而能把並發度提上去。所以在這裏可以看到Kylin1.5表現會更好。這裏也可以看出,在數據量成數量級上升後,Kylin表現的更加穩定,在不同規模數據集上依然可以保持不錯的查詢性能。而Druid隨著數據量的增長性能損失也成倍增長。
剛才是在性能方面做的一些分析,其實對于一個系統來說,性能只是一個方面,除此之外,我們也會去考量其它方面的情況,主要有以下四點。
第一,功能的完備性。剛才提到我們所有的數據必須是精確的,但是現在基本上沒有哪個系統能完全覆蓋我們這個需求。比如Druid性能表現確實更好,但是它去重計數沒有辦法做到精確。
第二,系統的易用性。作爲一個平台服務,不僅要把系統用起來,還要維護它,因此要考慮部署和監控的成本。這方面Kylin相對來說也是比較好的。Druid一個集群的角色是非常多的,如果要把這個系統用起來的話,可能光搭這個環境,起這些服務都要很長的時間。這個對于我們做平台來講,實際上是一個比較痛的事。不管是在部署,還是加監控的時候,成本都是相對比較高的。另外一個查詢接口方面,我們最熟悉或者最標准,最好用的當然是標准SQL的接口。ES、Druid這些系統原來都不支持SQL,當然現在也有一些插件,但是在功能的完備性和數據的效率上都不如原生的支持。
第三,數據成本。剛才提到了有些數據需要做一些預處理,比如表的拉平或者表達式列的變換,除此之外還有一些格式的轉化,比如有的系統只能讀TEXT格式,這樣都會帶來數據准備的成本。另一方面是數據導入的效率。從數據進入數據倉庫到真正能夠被查詢,這個時間中間有多長。數據存儲和服務的時候需要多少機器資源,這個都可以歸爲數據成本,就是使用這個數據需要付出的成本。
第四,查詢靈活性。經常有業務方問到,如果Cube沒定義的話怎麽辦?現在當然查詢只能失敗。這個說明有的查詢模式不是那麽固定的,可能突然要查一個數,但以後都不會再查了。實際上在需要預定義的OLAP引擎上,這種需求普遍來講支持都不是太好。
這張圖是各個系統全方位的一個對比。
從查詢效率上看,這裏表現最不好的就是Presto,表現最好的應該是Druid和Kylin1.5,兩者不相上下。從功能完備性上來講,確實Presto語法和UDF等等是很完備的,Kylin會稍微差一些,但比Druid好一點。
系統易用性上區別不是太大,這裏主要考慮有沒有標准的SQL接口或者部署成本高不高,用戶上手能不能更快,目前來看Druid接口上確實不夠友好,需要去翻它的文檔才知道怎麽去寫查詢的語法。
在查詢成本上,Presto是最好的,因爲幾乎不需要做什麽特殊的處理,基本上Hive能讀的數據Presto也都能讀,所以這個成本非常低。Druid和Kylin的成本相對較高,因爲都需要提前的預計算,尤其是Kylin如果維度數特別多,而且不做特別優化的話,數據量還是很可觀的。
最後從靈活性上來講, Presto只要SQL寫出來怎麽查都可以,Druid和Kylin都要做一些預先模型定義的工作。這方面也可以作爲大家選型時候的參考。
剛才比較客觀的對比了幾個系統,接下來再總結一下Kylin的優勢。
第一,性能非常穩定。因爲Kylin依賴的所有服務,比如Hive、HBase都是非常成熟的,Kylin本身的邏輯並不複雜,所以穩定性有一個很好的保證。目前在我們的生産環境中,穩定性可以保證在99.99%以上。同時查詢時延也比較理想。我們現在有一個業務線需求,每天查詢量在兩萬次以上,95%的時延低于1秒,99%在3秒以內。基本上能滿足我們交互式分析的需求。
第二,對我們特別重要的一點,就是數據的精確性要求。其實現在能做到的只有Kylin,所以說我們也沒有什麽太多其他的選擇。
第三,從易用性上來講,Kylin也有非常多的特點。首先是外圍的服務,不管是Hive還是HBase,只要大家用Hadoop系統的話基本都有了,不需要額外工作。在部署運維和使用成本上來講,都是比較低的。其次,有一個公共的Web頁面來做模型的配置。相比之下Druid現在還是基于配置文件來做。這裏就有一個問題,配置文件一般都是平台方或者管理員來管理的,沒辦法把這個配置系統開放出去,這樣在溝通成本和響應效率上都不夠理想。Kylin有一個通用的Web Server開放出來,所有用戶都可以去測試和定義,只有上線的時候需要管理員再review一下,這樣體驗就會好很多。
第四,最後一點就是活躍開放的社區和熱心的核心開發者團隊,社區裏討論非常開放,大家可以提自己的意見及patch,修複bug以及提交新的功能等,包括我們美團團隊也貢獻了很多特性,比如寫入不同的HBase集群等。這裏特別要指出的是核心團隊都是中國人,這是Apache所有項目裏唯一中國人爲主的頂級項目,社區非常活躍和熱心,有非常多的中國工程師。特別是當你貢獻越來越多的時候,社區會邀請成爲committer等,包括我自己及團隊成員也已經是Apache Kylin的committer。同時也非常高興看到以韓卿爲首的Apache Kylin核心團隊在今年初成立的創業公司Kyligence,相信可以爲整個項目及社區的發展帶來更大的空間和未來。
4、未來工作
在未來工作方面,我們認爲Kylin還有一些不理想的方面,我們也會著力去做優化和改進。
第一,精確去重計數。剛才提到只支持Int,接下來有一個方案會支持所有的數據類型,能夠擴展大家使用精確去重的場景範圍(補充說明:目前該功能已在1.5.3版本中實現)。
第二,在查詢效率和Build效率上也看到了一些可以優化的部分。比如隊列資源拆分,我們所有計算集群的資源都是按照業務線核算成本的,但是現在Kylin本身還不太支持,這個我們也會抓緊去做,相信在很多公司也有類似的需求。還有大結果集和分頁。當結果到了上百萬的量級時,查詢時延會上升到幾十秒。同時在查詢的時候有可能需要排序並且分頁,就是把結果全讀出來之後,根據其中的一個指標再order by,這個開銷也是比較大的。我們也會想辦法進行優化。
最後,Kylin1.5之後有明細數據和Streaming特性出來,後面也會做這方面的嘗試。
5、Q&A
Q1:之前在Build的時候一直提到成本的問題,能給出一個估計值嗎,如果一百億的數據,需要多少時間?
孫業銳:有一個簡單數據,大概是兩億行數據,維度的話有十四五個,Build時間不超過兩個小時,Build出來的數據是五六百G。
Q2:原始值是多大?
孫業銳:把這個數據抽出來之後,就是只參與Build的數據壓縮後只有幾個G。
Q3:Kerberos認證失效的問題你們遇到過沒有?
孫業銳: Kerberos認證完之後,會在本地臨時目錄下有一個ticket問題,每天在外部定時刷新一下就可以了,服務是不用停的。
主持人:我補充一下我們爲什麽選擇SQL接口?Kylin解決的是真正的用戶面是誰,其實是業務人員和分析人員,他只會SQL,幾乎那些人很少說再學個JAVA,所以能給他一個標准的SQL這個是讓他上船最快的事情。其實這就是易用性很重要。
剛才看到了Kylin在千萬級規模和億級規模的表現,如果數據規模上到十億,百億,千億的時候,我相信Kylin應該會秒殺所有一切。因爲我們現在有另一個案例,生産環境上千億規模的一張表,可以做到90%查詢在1.8秒以內。另外我覺得非常好的一點,像美團、京東這邊貢獻了很多patch,其實就是把需求提出來,大家可以一起來做。
作者介紹
孫業銳,美團高級工程師,Apache Kylin Committer。2012年畢業于電子科技大學,曾在奇虎360工作,負責Hadoop平台建設,2015年加入美團。目前主要負責數據生産和查詢引擎的改進和優化,專注于分布式計算,OLAP分析等領域,對分布式存儲系統亦有豐富經驗。