Spark SQL在携程的实践经验分享
本文根據(jù)張翼老師在2018年5月13日【第九屆中國數(shù)據(jù)庫技術大會】現(xiàn)場演講內(nèi)容整理而成。
講師簡介:
張翼,10年互聯(lián)網(wǎng)老兵;2015年3月加入攜程,攜程的大數(shù)據(jù)平臺技術總監(jiān),帶領團隊構(gòu)建穩(wěn)定,高效的數(shù)據(jù)平臺和系統(tǒng),保證了攜程數(shù)據(jù)的高速發(fā)展;加入攜程之前,在大眾點評負責數(shù)據(jù)基礎架構(gòu),從0開始組建團隊,搭建起點評的數(shù)據(jù)分析平臺;平時關注與大數(shù)據(jù)及AI系統(tǒng)的發(fā)展,致力于將開源技術和公司場景相結(jié)合,創(chuàng)造業(yè)務價值。
摘要:
之前,大多數(shù)公司大數(shù)據(jù)的數(shù)倉都是構(gòu)建在Hive上的,數(shù)據(jù)開發(fā)的ETL任務以及用戶對于數(shù)據(jù)的即時查詢主要使用的工具也是Hive,隨著Spark以及其社區(qū)的不斷發(fā)展,Spark及Spark SQL本身技術的不斷成熟,Spark在技術架構(gòu)和性能上都展示出Hive無法比擬的優(yōu)勢,如何使用Spark構(gòu)建大數(shù)據(jù)的數(shù)倉?如何將現(xiàn)有的數(shù)倉平臺從Hive轉(zhuǎn)到Spark上?這些問題都是每家公司需要考慮的問題;攜程原先的數(shù)倉也是構(gòu)建在Hive之上的,每天運行超過20000個Hive的定時任務,從2017年9月份開始,我們正式啟動了SparkSQL落地的一系列項目,到目前為止,大部分的ETL作業(yè)和用戶的臨時查詢已經(jīng)使用了SparkSQL;在這個演講中,我將分享下我們在這段時間中的做法,實踐和思考,我們遇到問題,以及我們的解決方案。
分享大綱:
1、平臺簡介
2、總體方案和效果
3、經(jīng)驗分享
4、未來展望
正文:
1、平臺簡介
首先介紹一下攜程大數(shù)據(jù)平臺總體架構(gòu):
如下圖所示,底層是資源部署和運維監(jiān)控,主要包括兩部分:自動運維系統(tǒng)和監(jiān)控系統(tǒng);自動運維系統(tǒng)大大降低了我們運維的effort,也降低了運維操作出錯的概率,是我們能在很少的運維人力投入的情況下維護大規(guī)模的集群;隨著系統(tǒng)變大,各個相關系統(tǒng)增多,一個有效的監(jiān)控能幫助我們及時發(fā)現(xiàn)問題,并嘗試進行自動的處理,這個也能夠大大提升運維的效率。
第二層是開源的大數(shù)據(jù)框架,主要分成兩部分:分布式存儲計算和實時框架,實時框架目前主要支持JStorm,Spark Streaming和Flink,其中Flink是今年新支持的;而分布式存儲和計算框架這邊,底層是Hadoop,ETL主要使用Hive和Spark,交互查詢則會使用Spark,Presto和Kylin。
第三層是工具系統(tǒng)層,直接提供給BI同學或者業(yè)務用戶,主要分為以下幾部分:數(shù)據(jù)開發(fā)平臺,包括日常使用的調(diào)度,數(shù)據(jù)傳輸,主數(shù)據(jù)以及數(shù)據(jù)質(zhì)量系統(tǒng);數(shù)據(jù)查詢平臺,主要包括報表系統(tǒng)Art nova和Adhoc查詢系統(tǒng);機器學習算法平臺,包括一個基于Spark的MLlib圖形化拖拽平臺,以及基于Docker的GPU云平臺,主要提供給數(shù)據(jù)算法科學家做模型訓練使用;最后一塊是實時數(shù)據(jù)平臺Muise,通過一個系統(tǒng)提供對所有類型實時作業(yè)的發(fā)布,管理,監(jiān)控和運維的功能。
本文重點介紹Spark SQL在攜程數(shù)據(jù)開發(fā)和數(shù)據(jù)查詢系統(tǒng)的落地實踐過程,所以在平臺簡介部分我先簡單介紹一下這兩大塊的系統(tǒng):
數(shù)據(jù)開發(fā)系統(tǒng)運行在分布式存儲計算框架之上,分布式存儲和計算框架最下面一層是Hadoop,其上是Hive和Spark;開發(fā)平臺Zeus主要由調(diào)度系統(tǒng)、主數(shù)據(jù)系統(tǒng)、傳輸系統(tǒng)以及數(shù)據(jù)質(zhì)量系統(tǒng)四部分組成。目前,我們的集群規(guī)模在1300臺左右,調(diào)度系統(tǒng)的Active任務數(shù)超過75000個,每天運行調(diào)度任務的實例超過13萬個,換算成底層MapReduce任務數(shù)大約在30萬左右,系統(tǒng)中的傳輸任務和ETL任務大約占比50%,在2017年Q4季度,我們內(nèi)部絕大多數(shù)在使用Hive。
數(shù)據(jù)查詢系統(tǒng)同樣運行在分布式存儲和計算框架之上,整個平臺包含兩部分——報表系統(tǒng)ArtNova和Adhoc查詢;Adhoc系統(tǒng)每天的查詢數(shù)載每天1萬+,2017年Q4季度主要支持Hive和Presto;新建報表系統(tǒng)ART Nova在去年12月正式上線,設計初衷就考慮摒棄Hive,改用Spark SQL或者Presto做查詢。
那么為什么我們要將數(shù)據(jù)平臺的計算引擎從Hive轉(zhuǎn)到SparkSQL來呢?
在對于Hive優(yōu)缺點的分析中我們能夠發(fā)現(xiàn)這個原因;Hive的優(yōu)點是歷史悠久,且穩(wěn)定性有保證,已經(jīng)被用戶廣泛接受。而Hive的缺點也很明顯,第一,其計算效率相比新一代計算引擎,比如Spark、Presto等要慢得多,因為其HQL會轉(zhuǎn)化為多個MR Job,MR Job之間需要進行數(shù)據(jù)落地,效率自然比不上純內(nèi)存RDD的Spark效率,把Hive轉(zhuǎn)到新一代的計算引擎能夠大幅度地提升平臺的計算效率;第二,Hive的源代碼結(jié)構(gòu)比較混亂,了解需要花費一定時間,在其上進行優(yōu)化的代價也比較大。
那么怎么來做呢?我們曾經(jīng)考慮過2種候選方案:第一,更換Hive的執(zhí)行引擎為Tez或者Spark,第二,更換一個能同時兼容Hive Table(讀、寫、權(quán)限等)并可保持HQL最大兼容性的計算引擎。很長一段時間,我們傾向于第一種候選方案,也就是Hive on Spark的方案
而SparkSQL 和Presto則被用來作為即時查詢計算引擎 。但是,下面的原因使我們最終下決心擁抱SparkSQL,并把其作為整個查詢和開發(fā)平臺的主要引擎:
-
2017下半年,和攜程規(guī)模相當,甚至比攜程規(guī)模小的互聯(lián)網(wǎng)公司完成或已經(jīng)開始SparkSQL的遷移,并取得了一些成果
-
SparkSQL的成熟,特別是2.2之后它的兼容性,穩(wěn)定性,性能有很大的提升
-
Hive on Spark除了Uber外很少有其他的用例
-
Hive社區(qū)的衰落和Spark社區(qū)的繁榮
-
時機,2017下半年,我們已經(jīng)基本解決了Hadoop集群增長帶來的穩(wěn)定性問題,有精力做較大的項目
2、總體方案和效果
遷移SparkSQL的挑戰(zhàn)主要體現(xiàn)在技術和團隊兩層面:
技術層面,最大的挑戰(zhàn)是對于已經(jīng)在運行的大量作業(yè),我們需要考慮如何將遷移過程的影響降到最小,需要做到以下3點:
-
第一點也是最重要的需要有灰度升級過程
-
第二點是SQL語法盡量兼容Hive原有語法
-
第三點是權(quán)限控制需要兼容Hive原有方式
第二大挑戰(zhàn)是原有與Hive配套的大量周邊設施需要改造,比如日志、Metrics收集、監(jiān)控和告警系統(tǒng)以及Dr Elephant等作業(yè)分析系統(tǒng)。
團隊層面,我們對SparkSQL源碼以及Scala并不熟悉,缺乏較大改動經(jīng)驗。
基于上述原因,我們將整個遷移過程分為四個階段:
第一階段,集中力量解決Blocking技術問題,主要的Blocking Issue有兩個:
將Hive權(quán)限控制機制移植到SparkSQL之上
實現(xiàn)Thrift Server的impersonation
通過這個過程熟悉Spark和Scala,積累技術實力。
第二階段,在Adhoc查詢平臺開始初步嘗試,由于是即席查詢,如果失敗,用戶可人工覆蓋到Hive,影響較小;后面也新的報表系統(tǒng)ArtNova中嘗試使用;在這個過程中,我們修復了大量bug,積累了開發(fā)和運維經(jīng)驗。
第三階段,改造開發(fā)平臺,讓整個平臺支持灰度推送。
第四階段,開發(fā)平臺作業(yè)全面灰度升級,優(yōu)化性能并處理遺留的長尾問題。
根據(jù)上述四個階段,我們制定了遷移時間表:
截止到今年5月份,Adhoc查詢工具中使用Spark SQL查詢占比57%,Art Nova大約有52%使用了Spark SQL。開發(fā)平臺的非數(shù)據(jù)傳輸作業(yè)大約52%使用了Spark SQL,差不多是兩萬多個,也可理解為原有Hive腳本已全部轉(zhuǎn)成Spark SQL方式。轉(zhuǎn)化完成,計算效率較之前提升了6-7倍。
3、經(jīng)驗分享
3.1 開發(fā)平臺的灰度變更支持
首先分享我們在灰度變更部分的經(jīng)驗,這也是整個過程最重要的部分。我們最初在開發(fā)平臺構(gòu)建灰度變更機制是在Hive從0.13升級到1.1時,最開始僅支持環(huán)境變量等簡單規(guī)則,在本次SparkSQL升級的過程中添加了執(zhí)行engine / shell cmd變更規(guī)則等更多復雜的規(guī)則;系統(tǒng)支持變更組,也支持包括多種類型的變更策略:如全量推送,分作業(yè)優(yōu)先級按照百分比推送,指定單個作業(yè)進行推送;最后一點是在作業(yè)失敗后,fallback到當前默認配置的功能,這點對于作業(yè)穩(wěn)定性保障至關重要。
一個典型的用戶操作流程如下圖所示:
我們在SparkSQL灰度升級時的實際配置如下:
Spark灰度升級引入了一種新的灰度升級規(guī)則 - engine,如上圖所示,我們先在規(guī)則配置里設置一條使用SQL的引擎,即SparkSQL;我們配置了3條策略,對低優(yōu)先級任務,當前的推送比例是100%,對高優(yōu)先級任務,我們的推送比例是70%,并外我們還設置了一條Black List的策略,將遇到問題的作業(yè)暫時排除在推送之外
3.2 問題及其解決
在整個升級的過程中,我們遇到了很多問題,需有問題社區(qū)已經(jīng)有了相關的解決方案(Apply社區(qū)Jira的修復超過30),還有很多問題需要我們自己解決,這邊我分享下我們遇到的幾個主要的問題:
1. 權(quán)限相關
? 1.1 Hive權(quán)限落地
? 1.2 Thrift Server Impersonation
2. 小文件合并
3. 資源利用率優(yōu)化
Hive權(quán)限落地
Hive權(quán)限控制模式主要有四種:
在Hive 0.13版本之前,是Default Authorization,簡稱v1,當然官方文章上曾提及該版本存在一些問題
在Hive 0.13或者之后的版本中,提出的是 SQL Standards Based Hive Authorizatio,簡稱v2
第三種是Storage Based Authorization in the Metastore Server
最后一個是 Authorization using Apache Ranger & Sentry方式
由于攜程使用Hive的歷史比較長,所以我們主要使用的權(quán)限控制方式是第一種,在這個基礎上對問題進行修復,比如grant無權(quán)限控制等問題等;考慮到未來的實際需求,Spark SQL也需要支持前兩種權(quán)限控制方式。
我們對Spark code進行了修改以支持這兩種權(quán)限控制的方式;Spark用到了很多Hive代碼,最終通過ExternalCatalog調(diào)用HiveExternalCatalog執(zhí)行 HiveClientImpl里的方法,在HiveClientImpl里,我們增加了權(quán)限檢查方法,從而做到在Spark語句執(zhí)行前檢查在Hive中設置的權(quán)限;對于權(quán)限控制模式v2的話,實現(xiàn)非常簡單,基本加一行code就可以;而權(quán)限控制模式v1相對來說復雜一點,需要把Hive的權(quán)限和相關邏輯全部移植過來。做法與v2相同,代碼量大約在400行左右
Thrift Server Impersonation
Adhoc查詢平臺使用Thrift Server的方式執(zhí)行SparkSQL,雖然其上的絕大多數(shù)操作是查詢,但是也有少量的寫操作,Thrift Server是以Hive賬號啟動的,如果沒有用戶賬號的Impersonation,寫的文件的Owner是Hive賬號,但是我們希望的Owner是用戶在Adhoc平臺上選擇的賬號。
Hortonworks有自己的解決方案,Thrift Server只作為Proxy Server,在用戶作業(yè)提交時再以其身份去啟動AM和executor,以用戶+connection id維度重用資源;這樣做的問題是賬號較多的情況下,executor的啟停帶來額外的開銷。由于攜程內(nèi)部BU較多,每個BU使用的賬號也非常多,這種方式可能對我們不是太適用。
我們采取的做法是在Thrift Server啟動時預先啟動AM和executor,將各賬號keytab分配到各個nodemanager之上,然后在executor端真正執(zhí)行Task時,使用超級賬戶把用戶impersonate 成實際用戶。
下圖為詳細技術圖:
小文件問題
如果不做任何修改,Spark在寫數(shù)據(jù)時會產(chǎn)生很多小文件;由于我們集群本身的存量文件就較多,Spark大量產(chǎn)生小文件的話,就會對NN產(chǎn)生很大的壓力,進而帶來整個系統(tǒng)穩(wěn)定性的隱患,我們在灰度推送到30%(6000 Job / day)時發(fā)現(xiàn)不到3周的時間內(nèi)就使NN的文件 + Block數(shù)飆升了近1億,這個還是在每天有程序合并小文件的情況下;另外文件變小帶來了壓縮率的降低,數(shù)據(jù)會膨脹3-4倍。
修復的方法其實比較簡單,在Insert Into Table或是Create Table as的情況下,如果本身沒有RepartitionByExpression的話,就增加一個RepartitionByExpression的stage
下面是相關的代碼:
在這之后,小文件問題就得到了控制,運行到目前為止還是比較正常的。
資源利用效率優(yōu)化
上圖橘色的圖片是每個作業(yè)的平均時間,在紅色邊框的時間內(nèi)沒有明顯變化,下方紫色的圖片是整個集群的平均延遲,可以看到有30%的下降。雖然這個改動非常簡單,但是對整體集群的資源利用效率有很大提升。
4、未來展望
近期工作
1. 繼續(xù)推進SparkSQL在數(shù)據(jù)開發(fā)平臺的使用比例,我們的目標是在5月底達到90%
目前純粹的Hive的分析任務已經(jīng)基本轉(zhuǎn)換完成,剩余的主要任務是轉(zhuǎn)換Legacy的Shell腳本中使用到Hive的地方,我們使用的方法是用函數(shù)的方式將hive直接替換為sparksql的command
2. 優(yōu)化作業(yè)內(nèi)存的使用,作業(yè)轉(zhuǎn)到SparkSQL之后,對內(nèi)存的使用量也急劇上升,在某些時間點出現(xiàn)了應用內(nèi)存分配滿而無法分配更多作業(yè)的情況,我們的解決思路有兩個:
-
根據(jù)作業(yè)歷史的內(nèi)存使用情況,在調(diào)度系統(tǒng)端自動設置合適的內(nèi)存
-
https://issues.apache.org/jira/browse/YARN-1011
未來我們希望做2件事:
1. 能夠進一步優(yōu)化長尾的SparkSQL作業(yè)的性能;從Hive轉(zhuǎn)換為SparkSQL之后,絕大多數(shù)作業(yè)的性能得到了較大的提高,但是還有有少量的作業(yè)運行效率反而下降了,也有一些作業(yè)出現(xiàn)運行失敗的情況(目前都fallback到Hive),我們簡單地統(tǒng)計了一下
-
有2.5%左右的作業(yè)會出現(xiàn)失敗(400~)
-
有6%左右的作業(yè)運行效率接近或比Hive更差(1000~)
-
有2.5%左右的作業(yè)運行時間比Hive慢5分鐘以上
后續(xù)我們會針對上面這些問題作業(yè)的共性問題,進行研究和解決
2. 升級到Spark 2.3
積極跟進社區(qū)的步伐,調(diào)研,測試,適配Spark 2.3;當然正式的生產(chǎn)使用會放在Spark 2.3.1發(fā)布之后。
以上是我所有的分享,希望對大家有所幫助,謝謝!
本文來自 “ ITPUB博客 ” ,鏈接:http://blog.itpub.net/31545816/viewspace-2221925/
總結(jié)
以上是生活随笔為你收集整理的Spark SQL在携程的实践经验分享的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JAVA数据结构与算法【稀疏数组】
- 下一篇: mysql的分页查询