摘要:在有贊的技術演進。業(yè)務數(shù)據(jù)量正在不斷增大,這些任務會影響業(yè)務對外服務的承諾。監(jiān)控需要收集上執(zhí)行的的審計信息,包括提交者執(zhí)行的具體,開始結束時間,執(zhí)行完成狀態(tài)。還有一點是詳細介紹了的原理,實踐中設置了的比默認的減少了以上的時間。
前言
有贊數(shù)據(jù)平臺從2017年上半年開始,逐步使用 SparkSQL 替代 Hive 執(zhí)行離線任務,目前 SparkSQL 每天的運行作業(yè)數(shù)量5000個,占離線作業(yè)數(shù)目的55%,消耗的 cpu 資源占集群總資源的50%左右。本文介紹由 SparkSQL 替換 Hive 過程中碰到的問題以及處理經(jīng)驗和優(yōu)化建議,包括以下方面的內容:
有贊數(shù)據(jù)平臺的整體架構。
SparkSQL 在有贊的技術演進。
從 Hive 到 SparkSQL 的遷移之路。
一. 有贊數(shù)據(jù)平臺介紹首先介紹一下有贊大數(shù)據(jù)平臺總體架構:
如下圖所示,底層是數(shù)據(jù)導入部分,其中 DataY 區(qū)別于開源屆的全量導入導出工具 alibaba/DataX,是有贊內部研發(fā)的離線 Mysql 增量導入 Hive 的工具,把 Hive 中歷史數(shù)據(jù)和當天增量部分做合并。DataX / DataY 負責將 Mysql 中的數(shù)據(jù)同步到數(shù)倉當中,F(xiàn)lume 作為日志數(shù)據(jù)的主要通道,同時也是 Mysql binlog 同步到 HDFS 的管道,供 DataY 做增量合并使用。
第二層是大數(shù)據(jù)的計算框架,主要分成兩部分:分布式存儲計算和實時計算,實時框架目前主要支持 JStorm,Spark Streaming 和 Flink,其中 Flink 是今年開始支持的;而分布式存儲和計算框架這邊,底層是 Hadoop 和 Hbase,ETL主要使用 Hive 和 Spark,交互查詢則會使用 Spark,Presto,實時 OLAP 系統(tǒng)今年引入了 Druid,提供日志的聚合查詢能力。
第三層是數(shù)據(jù)平臺部分,數(shù)據(jù)平臺是直接面對數(shù)據(jù)開發(fā)者的,包括幾部分的功能,數(shù)據(jù)開發(fā)平臺,包括日常使用的調度,數(shù)據(jù)傳輸,數(shù)據(jù)質量系統(tǒng);數(shù)據(jù)查詢平臺,包括ad-hoc查詢以及元數(shù)據(jù)查詢。有關有贊數(shù)據(jù)平臺的詳細介紹可以參考往期有贊數(shù)據(jù)平臺的博客內容。
從2017年二季度,有贊數(shù)據(jù)組的同學們開始了 SparkSQL 方面的嘗試,主要的出發(fā)點是當時集群資源是瓶頸,Hive 跑任務已經(jīng)逐漸開始乏力,有些復雜的 SQL,通過 SQL 的邏輯優(yōu)化達到極限,仍然需要幾個小時的時間。業(yè)務數(shù)據(jù)量正在不斷增大,這些任務會影響業(yè)務對外服務的承諾。同時,隨著 Spark 以及其社區(qū)的不斷發(fā)展,Spark 及 Spark SQL 本身技術的不斷成熟,Spark 在技術架構和性能上都展示出 Hive 無法比擬的優(yōu)勢。
從開始上線提供離線任務服務,再到 Hive 任務逐漸往 SparkSQL 遷移,踩過不少坑,也填了不少坑,這里主要分兩個方面介紹,一方面是我們對 SparkSQL 可用性方面的改造以及優(yōu)化,另一方面是 Hive 遷移時遇到的種種問題以及對策。
2.1 可用性改造可用性問題包括兩方面,一個是系統(tǒng)的穩(wěn)定性,監(jiān)控/審計/權限等,另一個是用戶使用的體驗,用戶以前習慣用 Hive,如果 SparkSQL 的日志或者 Spark thrift server 的 UI 不能夠幫助用戶定位問題,解決問題,那也會影響用戶的使用或者遷移意愿。所以我首先談一下用戶交互的問題。
用戶體驗我們碰到的第一個問題是用戶向我們抱怨通過 JDBC 的方式和 Spark thrift server(STS) 交互,執(zhí)行一個 SQL 時,沒有執(zhí)行的進度信息,需要一直等待執(zhí)行成功,或者任務出錯時接收任務報錯郵件得知執(zhí)行完。于是執(zhí)行進度讓用戶可感知是一個必要的功能。我們做了 Spark 的改造,增加運行時的 operation 日志,并且向社區(qū)提交了 patch(spark-22496), 而在我們內部,更增加了執(zhí)行進度日志,每隔2秒打印出當前執(zhí)行的 job/stage 的進度,如下圖所示。
監(jiān)控SparkSQL 需要收集 STS 上執(zhí)行的 SQL 的審計信息,包括提交者執(zhí)行的具體 SQL,開始結束時間,執(zhí)行完成狀態(tài)。原生 STS 會把這些信息通過事件的方式 post 到事件總線,監(jiān)聽者角色 (HiveThriftServer2Listener) 在事件總線上注冊,訂閱消費事件,但是這個監(jiān)聽者只負責 Spark UI 的 JDBC Tab 上的展示,我們改造了 SparkListener 類,將 session 以及執(zhí)行的 sql statement 級別的消息也放到了總線上,監(jiān)聽者可以在總線上注冊,以便消費這些審計信息,并且增加了一些我們感興趣的維度,如使用的 cpu 資源,歸屬的工作流(airflowId)。同時,我們增加了一種新的完成狀態(tài) cancelled,以方便區(qū)分是用戶主動取消的任務。
Thrift Server HA相比于 HiveServer,STS 是比較脆弱的,一是由于 Spark 的 driver 是比較重的,所有的作業(yè)都會通過 driver 編譯 sql,調度 job/task 執(zhí)行,分發(fā) broadcast 變量,二是對于每個 SQL,相比于 HiveServer 會新起一個進程去處理這個 SQL 的執(zhí)行,STS 只有一個進程去處理,如果某個 SQL 有異常,查詢了過多的數(shù)據(jù)量, STS 有 OOM 退出的風險,那么生產環(huán)境維持 STS 的穩(wěn)定性就顯得無比重要。
除了必要的存活報警,首先我們區(qū)分了 ad-hoc 查詢和離線調度的 STS 服務,因為離線調度的任務往往計算結束時是把結果寫入 table 的,而 ad-hoc 大部分是直接把結果匯總在 driver,對 driver 的壓力比較大;此外,我們增加了基于 ZK 的高可用。對于一種類型的 STS(事實上,有贊的 STS 分為多組,如 ad-hoc,大內存配置組)在 ZK 上注冊一個節(jié)點,JDBC 的連接直接訪問 ZK 獲取隨機可用的 STS 地址。這樣,偶然的 OOM ,或者 bug 被觸發(fā)導致 STS 不可用,也不會嚴重到影響調度任務完全不可用,給開發(fā)運維人員比較充足的時間定位問題。
權限控制之后有另一個文章詳細介紹我們對于安全和權限的建設之路,這里簡單介紹一下,Hive的權限控制主要包括以下幾種:
SQL Standards Based Hive Authorization
Storage Based Authorization in the Metastore
ServerAuthorization using Apache Ranger & Sentry
調研對比各種實現(xiàn)方案之后,由于我們是從無到有的增加了權限控制,沒有歷史負擔。我們直接選擇了ranger + 組件 plugin 的權限管理方案。
除了以上提到的幾個點,我們還從社區(qū) backport 了數(shù)十個 patch 以解決影響可用性的問題,如不識別 hiveconf/hivevar (SPARK-13983),最后一行被截斷(HIVE-10541) 等等。
2.2 性能優(yōu)化之前談到,STS 只有一個進程去處理所有提交 SQL 的編譯,所有的 SQL Job 共享一個 Hive 實例,更糟糕的是這個 Hive 實例還有處理 loadTable/loadPartition 這樣的 IO 操作,會阻塞其他任務的編譯,存在單點問題。我們之前測試一個上萬 partition 的 Hive 表在執(zhí)行 loadTable 操作時,會阻塞其他任務提交,時間長達小時級別。對于 loadTable 這樣的IO操作,要么不加鎖,要么減少加鎖的時間。我們選擇的是后者,首先采用的是社區(qū) SPARK-20187 的做法,將 loadTable 實現(xiàn)由 copyFile 的方式改為 moveFile,見下圖:
之后變更了配置spark.sql.hive.metastore.jars=maven,運行時通過 Maven 的方式加載 jar 包,解決包依賴關系,使得加載的 Hive 類是2.1.1的版本,和我們 Hive 版本一致,這樣得好處是很多行為都會和 Hive 的相一致,方便排查問題;比如刪除文件到 Trash,之前 SparkSQL 刪除表或者分區(qū)后是不會落到 Trash 的。
2.3 小文件問題我們在使用 SparkSQL 過程中,發(fā)現(xiàn)小文件的問題比較嚴重,SparkSQL 在寫數(shù)據(jù)時會產生很多小文件,會對 namenode 產生很大的壓力,進而帶來整個系統(tǒng)穩(wěn)定性的隱患,最近三個月文件個數(shù)幾乎翻了個倍。對于小文件問題,我們采用了社區(qū) SPARK-24940 的方式處理,借助 SQL hint 的方式合并小文件。同時,我們有一個專門做 merge 的任務,定時異步的對天級別的分區(qū)掃描并做小文件合并。
還有一點是spark.hadoop.mapreduce.fileoutputcommitter.algorithm.version=2, MapReduce-4815 詳細介紹了 fileoutputcommitter 的原理,實踐中設置了 version=2 的比默認 version=1 的減少了70%以上的 commit 時間。
三. SparkSQL 遷移之路
解決了大部分的可用性問題以后,我們逐步開始了 SparkSQL 的推廣,引導用戶選擇 SparkSQL 引擎,絕大部分的任務的性能能得到較大的提升。于是我們進一步開始將原來 Hive 執(zhí)行的任務向 SparkSQL 轉移。
在 SparkSQL 遷移之初,我們選擇的路線是遵循二八法則,從優(yōu)化耗費資源最多的頭部任務開始,把Top100的任務從 Hive 往 SparkSQL 遷移,逐步積累典型錯誤,包括 SparkSQL 和Hive的不一致行為,比較典型的問題由ORC格式文件為空,Spark會拋空指針異常而失敗,ORC 格式和 metastore 類型不一致,SparkSQL 也會報錯失敗。經(jīng)過一波人工推廣之后,頭部任務節(jié)省的資源相當客觀,在2017年底,切換到 SparkSQL 的任務數(shù)占比5%,占的資源20%,資源使用僅占 Hive 運行的10%-30%。
在 case by case 處理了一段時間以后,我們發(fā)現(xiàn)這種方式不太能夠擴展了。首先和作業(yè)的 owner 協(xié)商修改需要溝通成本,而且小作業(yè)的改動收益不是那么大,作業(yè)的 owner 做這樣的改動對他來說收益比較小,反而有一定概率的風險。所以到這個階段 SparkSQL 的遷移之路進展比較緩慢。
于是我們開始構思自動化遷移方式,構思了一種執(zhí)行引擎之上的智能執(zhí)行引擎選擇服務 SQL Engine Proposer(proposer),可以根據(jù)查詢的特征以及當前集群中的隊列狀態(tài)為 SQL 查詢選擇合適的執(zhí)行引擎。數(shù)據(jù)平臺向某個執(zhí)行引擎提交查詢之前,會先訪問智能執(zhí)行引擎選擇服務。在選定合適的執(zhí)行引擎之后,數(shù)據(jù)平臺將任務提交到對應的引擎,包括 Hive,SparkSQL,以及較大內存配置的 SparkSQL。
并且在 SQL Engine Proposer,我們添加了一系列策略:
規(guī)則策略,這些規(guī)則可以是某一種 SQL pattern,proposer 使用 Antlr4 來處理執(zhí)行引擎的語法,對于某些遷移有問題的問題,將這種 pattern 識別出來,添加到規(guī)則集合中,典型的規(guī)則有沒有發(fā)生 shuffle 的任務,或者只發(fā)生 broadcast join 的任務,這些任務有可能會產生很多小文件,并且邏輯一般比較簡單,使用Hive運行資源消耗不會太多。
白名單策略,有些任務希望就是用Hive執(zhí)行,就通過白名單過濾。當 Hive 和 SparkSQL 行為不一致的時候,也可以先加入這個集合中,保持執(zhí)行和問題定位能夠同時進行。
優(yōu)先級策略,在灰度遷移的時候,是從低優(yōu)先級任務開始的,在 proposer 中我們配置了灰度的策略,從低優(yōu)先級任務切一定的流量開始遷移,逐步放開,在優(yōu)先級內達到全量,目前放開了除 P1P2 以外的3級任務。
過往執(zhí)行記錄,proposer 選擇時會根據(jù)歷史執(zhí)行成功情況以及執(zhí)行時間,如果 SparkSQL 效率比 Hive 有顯著提升,并且在過去一直執(zhí)行成功,那么 proposer 會更傾向于選擇 SparkSQL。
截止目前,執(zhí)行引擎選擇的作業(yè)數(shù)中 SparkSQL 占比達到了73%,使用資源僅占32%,遷移到 SparkSQL 運行的作業(yè)帶來了67%資源的節(jié)省。
我們計劃 Hadoop 集群資源進一步向 SparkSQL 方向轉移,達到80%,作業(yè)數(shù)達70%,把最高優(yōu)先級也開放到選擇引擎,引入 Intel 開源的 Adaptive Execution 功能,優(yōu)化執(zhí)行過程中的 shuffle 數(shù)目,執(zhí)行過程中基于代價的 broadcast
join 優(yōu)化,替換 sort merge join,同時更徹底解決小文件問題。
最后打個小廣告,有贊大數(shù)據(jù)團隊基礎設施團隊,主要負責有贊的數(shù)據(jù)平臺(DP), 實時計算(Storm, Spark Streaming, Flink),離線計算(HDFS, YARN, HIVE, SPARK SQL),在線存儲(HBase),實時 OLAP(Druid) 等數(shù)個技術產品,歡迎感興趣的小伙伴聯(lián)系 zouchenjun@youzan.com
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/11440.html
摘要:在有贊的技術演進。業(yè)務數(shù)據(jù)量正在不斷增大,這些任務會影響業(yè)務對外服務的承諾。監(jiān)控需要收集上執(zhí)行的的審計信息,包括提交者執(zhí)行的具體,開始結束時間,執(zhí)行完成狀態(tài)。還有一點是詳細介紹了的原理,實踐中設置了的比默認的減少了以上的時間。 前言 有贊數(shù)據(jù)平臺從2017年上半年開始,逐步使用 SparkSQL 替代 Hive 執(zhí)行離線任務,目前 SparkSQL 每天的運行作業(yè)數(shù)量5000個,占離線...
摘要:第三個就是比較重點的內容,在有贊的實踐。第四部分是將實時計算化,界面化的一些實踐。二有贊實時平臺架構有贊的實時平臺架構呢有幾個主要的組成部分。實時平臺提供了集群管理,項目管理,任務管理和報警監(jiān)控的功能。。 一、前言 這篇主要由五個部分來組成: 首先是有贊的實時平臺架構。 其次是在調研階段我們?yōu)槭裁催x擇了 Flink。在這個部分,主要是 Flink 與 Spark 的 structure...
摘要:第三個就是比較重點的內容,在有贊的實踐。第四部分是將實時計算化,界面化的一些實踐。二有贊實時平臺架構有贊的實時平臺架構呢有幾個主要的組成部分。實時平臺提供了集群管理,項目管理,任務管理和報警監(jiān)控的功能。。 一、前言 這篇主要由五個部分來組成: 首先是有贊的實時平臺架構。 其次是在調研階段我們?yōu)槭裁催x擇了 Flink。在這個部分,主要是 Flink 與 Spark 的 structure...
閱讀 1294·2021-10-08 10:05
閱讀 4106·2021-09-22 15:54
閱讀 3105·2021-08-27 16:18
閱讀 3106·2019-08-30 15:55
閱讀 1435·2019-08-29 12:54
閱讀 2748·2019-08-26 11:42
閱讀 542·2019-08-26 11:39
閱讀 2128·2019-08-26 10:11