Spark+Alluxio性能调优十大技巧
戳藍字“CSDN云計算”關注我們哦!
由于統一訪問對象存儲(如S3)和HDFS數據的場景的出現和普及,Apache Spark結合Alluxio的大數據棧越來越受歡迎。此外,越來越流行的計算與存儲分離的架構導致計算端查詢延遲增大。因此,Alluxio常被用作貼近計算端的熱數據存儲以提高性能。為了能夠獲得最佳性能,用戶需要像使用其他技術棧組合一樣遵循最佳的實戰經驗。本文介紹了在Alluxio上運行Spark時,對于實際工作負載性能調優的十大技巧。
關于數據本地性
數據本地性就是盡量將計算移到數據所在的節點上進行,避免數據在網絡上的傳輸。分布式數據并行環境下,數據的本地性非常重要。提高數據本地性能夠極大地提升Spark作業的性能。如果需要計算的數據存儲在節點本地,那么Spark任務可以直接以內存速度(當配置ramdisk時)從本地Alluxio worker中讀取Alluxio中的數據,而不必通過網絡進行數據傳輸。首先我們要介紹的幾個調優技巧是關于數據本地性方面的。
1 檢查Spark作業讀取Alluxio時的數據本地性
當Spark worker與Alluxio worker同置部署(co-locate)在同一節點上時,Alluxio能夠通過支持短路讀寫(見文末鏈接1)為Spark計算任務提供最佳的性能。用戶有多種方法檢查I/O請求是否實際由Alluxio短路讀/寫提供數據訪問服務,具體方法如下:
方法1:當運行Spark任務時,觀察監控頁面Alluxio metrics UI page(見文末鏈接2)上的Short-circuit reads和From RemoteInstance的兩個指標。此外,還可以觀察cluster.BytesReadAlluxioThroughput和cluster.BytesReadLocalThroughput兩個指標的值進行判斷。如果數據的本地讀寫吞吐量為零或遠低于總吞吐量,那么說明該Spark作業可能沒有本地的Alluxio worker進行數據交互。
方法2:利用dstat(見文末鏈接3)等工具檢測網絡流量,這樣我們就可以看到短路讀取是否發生以及實際的網絡吞吐量。YARN用戶還可以在/var/log/hadoop-yarn/userlogs日志中查找如下信息:INFO ShuffleBlockFetcherIterator: Started 0 remote fetches in 0ms,觀察遠程讀取是否發生,或者都是短路讀取。運行Spark作業時,用戶可以通過配置YARN相關參數(例如--master yarn--num-executors 4 --executor-cores 4)來開啟收集這些日志。
如果用戶通過上述方法發現Alluxio對Spark作業只提供了一小部分短路讀取或寫入,請閱讀下面幾條技巧以提升數據本地性。
2?確保Spark Executor本地性
Spark中的數據本地性分為兩種:executor 層面的本地性(executor locality)、task 層面的本地性(task locality) 。Executor級別的本地性意味著當Spark作業由其他資源管理框架(如Mesos和YARN)部署時,Spark Executor會被分配在同時運行Alluxio worker的節點上,從而和Alluxio worker運行于統一的節點。如果Executor的本地性沒有達到,Alluxio就無法為Spark作業提供本地的數據服務。我們經常會發現,相比于Spark Standalone模式部署,當Spark通過Spark on Yarn或Spark on Mesos等資源管理框架的模式進行部署時,executor本地性經常難以保證。
較新版本的Spark在YARN和Mesos框架調度分發executors時能夠考慮數據本地性因素,此外還有方法可以強制在所需節點上啟動executors。因此,一個簡單的策略是在每個節點上都啟動executor,這樣能夠保證在每個所需節點上都至少有一個executor運行著。
然后,由于實際情況下的資源限制,在通常生產環境中的每個節點上都部署運行Alluxioworker還比較困難。為了能夠將Alluxioworker與計算節點同置部署(co-locate),用戶可以利用類似于資源管理框架YARN中的節點標簽(見文末鏈接4)功能。具體地,首先,將包含Alluxioworker的NodeManagers節點標簽標記為alluxio(具體標簽取名不重要)。然后,用戶將Spark作業提交到該alluxio標簽指定的節點。最后,系統會在這些機器節點上啟動Spark作業的executors并與Alluxio workers進行協同工作。
3?確保Spark Task本地性
Task層面的數據本地性是屬于下一層次的本地性,它是由Spark本身決定的。達到Task本地性表示一旦啟動executor,Spark能夠將task調度到滿足數據本地性的executor上執行(在與Alluxio結合的場景下,即在將task調度到通過Alluxio提供本地數據的executor上執行)。為了達到該目標,Spark任務調度器需要首先從Alluxio收集所有數據的位置信息。該位置信息以Alluxio worker的主機名列表進行表示。然后,嘗試匹配Spark executor主機名進行調度。用戶可以從Alluxio master web UI中查看到Alluxio worker的主機名,也可以通過Spark driver web UI找到Spark executor的主機名。
然而,有時由于不同網絡環境或配置方面的原因,在同一臺機器上運行的Alluxio worker和Spark executor提供的主機名可能并不匹配。在這種情況下,Spark?的任務調度器將會混淆主機名的匹配從而無法確保數據本地性。因此,Alluxio worker的主機名與Spark executor的主機名采用相同的“主機名名稱空間”非常重要。用戶經常會遇到的一個問題是:Alluxio worker和Spark executor一個使用IP地址標示,而另一個使用主機名標示。如果發生了這種情況,用戶仍然可以在Spark中手動設置Alluxio-client屬性alluxio.user.hostname(見文末鏈接5),并將Alluxio worker中的alluxio.worker.hostname屬性設置為相同值來解決該問題。此外,用戶也可以查閱JIRASPARK-10149(見文末鏈接6)以獲取Spark開源社區的解決方案。
4?優先考慮Spark調度器中的本地性因素
關于本地性, Spark客戶端有一些配置參數可供調優。具體地,spark.locality.wait:即數據本地性降級的等待時間,默認是3000毫秒,如果超時就啟動下一本地優先級別的task。該配置參數同樣可以應用到不同優先級的本地性之間(PROCESS_LOCAL,NODE_LOCAL,RACK_LOCAL,ANY)。我們也可以通過將參數spark.locality.wait.node設置為特定的本地性級別,從而實現自定義每個節點的本地性等待時間。
負載均衡
負載均衡同樣非常重要,它能夠確保Spark作業的執行能夠均勻地分布在不同可用節點上。以下的幾個技巧介紹如何避免由于Alluxio輸入數據傾斜導致負載或者任務調度不均衡。
5?使用DeterministicHashPolicy通過Alluxio從UFS冷讀數據
同一個Spark作業的多個task經常會讀取相同的輸入文件。當該文件沒有加載到Alluxio中時,默認情況下,不同task的本地Alluxio worker將從UFS讀取相同的文件。這可能導致如下后果:
多個Alluxio worker同時競爭相同數據的Alluxio-UFS連接。如果從Alluxio到UFS的連接速度很慢,每個worker都會因為這些不必要的競爭而造成數據讀取速度變慢。
同一份數據會在Alluxio緩存空間中存儲多個副本,造成大量的空間浪費,并間接造成那些對其他查詢有用的數據被剔出出Alluxio緩存空間。
解決此問題的一種方法是將alluxio.user.ufs.block.read.location.policy設置為DeterministicHashPolicy以協調Alluxio worker從UFS讀取數據的過程,避免產生不必要的競爭。例如,編輯spark / conf /spark-defaults.conf以確保最多允許四個隨機Alluxio worker讀取給定數據塊。(具體數目由alluxio.user.ufs.block.read.location.policy.deterministic.hash.shards參數決定)
spark.driver.extraJavaOptions=-Dalluxio.user.ufs.block.read.location.policy=alluxio.client.block.policy.DeterministicHashPolicy
spark.executor.extraJavaOptions=-Dalluxio.user.ufs.block.read.location.policy.deterministic.hash.shards=4
注意,通過上述設置,系統將為不同的數據塊隨機選擇一組不同的四個worker與之對應。
6 采用更小的Alluxio數據塊獲得更高的并行度
數據塊(block)是Alluxio系統中最小的存儲單元。當Alluxio數據塊大小(默認為512MB)相較于一個文件本身很大時,就意味著該文件只包含少數幾個數據塊。因此,也就只有少數幾個Alluxio worker能夠為并行地讀取文件提供服務。具體地,為了獲得數據NODE_LOCAL本地性,在Spark的“文件掃描”階段,task可能只分配給少數幾個服務器處理。這會導致大多數服務器閑置,從而導致集群負載不平衡,處理并發度低下。在這種情況下,使用較小的塊來組織存儲Alluxio的文件(例如,將alluxio.user.block.size.bytes.default設置為128MB或更小),能夠增加文件的數據塊數量,使得文件的數據分散地存儲在更多的機器中,從而提升文件數據讀取的并行度。。請注意,當UFS是HDFS時,自定義調整Alluxio塊大小的方法會不適用,因為Alluxio的數據塊大小會被強制設置為HDFS塊大小。
7?調整優化executor數目以及每個executor的task數目
在一個executor中運行過多的task并發地從Alluxio中讀取數據可能會造成網絡連接、網絡帶寬等資源的爭用。基于Alluxio worker節點的數量,用戶可以通過合理地調整executor的數量以及每個executor的task數量( Spark中可配),從而更好地將task分配給更多節點(獲取更高的Alluxio帶寬),并減少資源爭用的開銷。
8?預加載數據到Alluxio
盡管Alluxio提供了透明性和異步緩存機制(見文末鏈接7),但是用戶的第一次冷讀取還是會存在性能開銷。為了避免這個問題,用戶通過使用以下命令行將數據預加載到Alluxio存儲空間中:
bash
$ bin/alluxio fs load /path/to/load
--Dalluxio.user.ufs.block.read.location.policy=alluxio.client.file.policy.MostAvailableFirstPolicy
注意:load命令只是簡單地從底層存儲的這臺節點中中加載目標文件到Alluxio,因此數據寫入到Alluxio的速度往往會受到單個服務器節點的限制。在Alluxio 2.0中,我們計劃實現分布式加載數據功能以提高加載的吞吐量。
容量管理
Alluxio為用戶提供一個高層的熱點輸入數據緩存服務。事實上,正確合理的分配和管理緩存的容量配額對取得好性能同樣非常重要。
9?使用SSD或HDD擴展Alluxio系統存儲容量
Alluxio workers也可以使用本地SSD(固態硬盤)或者HDD(硬盤)來和RAM(內存)存儲資源進行互補。為了減少數據被剔除Alluxio存儲空間,我們建議在Alluxio存儲層中設置多級存儲目錄而非僅采用單一存儲層,詳情參見文末鏈接8。在AWS EC2上運行Alluxio workers的用戶需要注意:將EBS存儲掛載為本地磁盤會通過網絡傳輸數據,這可能會造成數據訪問速度可能很慢。
10?關閉被動緩存特性以防緩存垃圾
Alluxio客戶端的配置參數alluxio.user.file.passive.cache.enabled可以控制是否在Alluxio中緩存額外的數據副本。這個屬性是默認開啟的(即alluxio.user.file.passive.cache.enabled=true)。因此,在客戶端請求數據時,一個Alluxio worker可能會緩存已經在其他worker上存在的數據。當該屬性為false時,Alluxio存儲空間中數據將不會有任何額外副本。
值得注意的是,當開啟該屬性時,相同的數據塊可以在多個workers處訪問到,這樣的多副本存儲會降低Alluxio空間的總存儲容量。根據數據集的大小與Alluxio的存儲容量,關閉被動緩存對于不需要數據本地性但希望更大的Alluxio存儲容量的工作負載是有益的。未來,?Alluxio 2.0將會支持更細粒度的數據副本設置,例如靈活配置Alluxio中給定文件的副本數最小值和最大值。
附錄鏈接:
鏈接1:
https://www.alluxio.org/docs/1.8/en/Architecture-DataFlow.html#local-cache-hit
鏈接2:
http://www.alluxio.org/docs/1.8/en/operation/Metrics-System.html
鏈接3:
https://linux.die.net/man/1/dstat
鏈接4:
https://hadoop.apache.org/docs/r2.9.1/hadoop-yarn/hadoop-yarn-site/ NodeLabel. html
鏈接5:
http://www.alluxio.org/docs/1.8/en/compute/Spark.html#advanced -setup
鏈接6:
https://issues.apache.org/jira/browse/SPARK-10149
鏈接7:
https://www.alluxio.com/blog/asynchronous-caching-in-alluxio-high-performance-for-partial-read-caching
鏈接8:
https://www.alluxio.org/docs/1.8/en/advanced/Alluxio-Storage-Management. html# single-tier-storage
本文作者:范斌, 馮濱, Gene Pang, Madan Kumar and Reid Chan (Momo)
作者簡介:范斌, 馮濱,?Gene Pang, Madan Kumar均為Alluxio maintainer。Reid Chan 陌陌大數據平臺開發工程師,負責Alluxio, HBase, Phoenix, Kerberos等開發運維工作,支持鼓勵開源工作,是HBase Committer之一。
1.微信群:
添加小編微信:color_ld,備注“進群+姓名+公司職位”即可,加入【云計算學習交流群】,和志同道合的朋友們共同打卡學習!
2.征稿:
投稿郵箱:liudan@csdn.net;微信號:color_ld。請備注投稿+姓名+公司職位。
推薦閱讀
2018,這一年的騰訊優圖,我們總結一下!
有問有答 | AWS使用精華問答,帶您開啟 AWS 上的云計算之旅!
程序員的年度未解之謎:加班背鍋的是我,得優秀員工的卻是他
特斯拉“撞死”機器人,是炒作還是事故?
買不到回家的票,都是“搶票加速包”惹的禍?
君士坦丁堡硬分叉姍姍來遲,以太坊2.0還要等多久?
剛剛!程序員集體榮獲2個冠軍,這份2018 IT報告還說這些!
點擊“閱讀原文”,打開 CSDN App 閱讀更貼心!
喜歡就點擊“好看”吧!總結
以上是生活随笔為你收集整理的Spark+Alluxio性能调优十大技巧的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为什么要吃腊八粥?
- 下一篇: 凉拌冰菜的拼盘名字是什么?