1. 程式人生 > >spark調優經驗(待續)

spark調優經驗(待續)

spark調優是需要根據業務需要調整的,並不是說某個設定是一成不變的,就比如機器學習一樣,是在不斷的除錯中找出當前業務下更優的調優配置。下面零碎的總結了一些我的調優筆記。

spark 儲存的時候存在嚴重的分配不均的現象,有幾臺機器在過渡使用, 有幾臺機器卻很少被使用,有幾臺機器快取了幾十個上百個RDD blocks  有的機器一個RDD blocks 都沒有,這樣儲存有RDD blocks 的可以進行運算,運算的tasks 最多為該機器core數。

spark.storage.memoryFraction 分配給用於快取RDD的記憶體的比例  

比如如果spark.executor.memory              30g  spark.storage.memoryFraction       0.5          則用於快取的記憶體為14G 多, 預設留一些做其他用。



每一個RDD blocks  的大小不一定是64兆 可能小於64兆,另外如果driver不是子節點,driver 程式執行的節點上的用於快取的記憶體 ,就不會被使用。


事實上一個兩三G 的資料 需要用的快取也至少需要兩三G,如果中間過程中還有產生RDD 且也需要快取到記憶體,則需要分配更多的記憶體用於快取。在快取足夠多的情況的
更多的記憶體不足錯誤提示(OOM) 來源於計算的時候產生的一些中間物件即計算所需要的記憶體。


所以分配用於快取的記憶體 應該是這麼算的, 比如我有10G的檔案,4臺機器,則每臺機器至少2.5g快取,如果每臺機器分配給excutor 的記憶體為10g ,則memoryFraction 則至少為0.25  最好配大一些,但不能太大, 太大會導致計算記憶體不夠。而且如果中間過程還有產生新的RDD,則需要根據實際情況調大memoryFraction。



RDD 快取分佈不均勻 是影響spark 的很大的效能之一,為什麼這麼說?

因為有的機器分配給用於RDD 快取的記憶體都用完了  ,這樣相對而言在這個機器上計算的開銷也會大,有的機器快取佔用的記憶體很少,就算用這個機器來計算,還需要啟動Node_local 模式,這樣會影響計算的時間。

調優過程也遇到了一些問題,還沒解決,比如:

為什麼一個2G 的資料,預設塊大小為64M. default.parallelism 設定成100,可它總是不按這個資料來分,比如經常分成了108個blocks,影響partions個數的引數還有哪些?還有我明明有四個節點,但經常有節點被分配的RDD 和計算都很少很少,這種資源浪費的情況應該怎麼調解?

《續》

1.      spark效能配置

我目前的環境是5臺機器,每臺機器8個核。如果有以下兩種配置方案:

(a)

   SPARK_WORKER_INSTANCES = 8

   SPARK_WORKER_CORES = 1

 (b)

   SPARK_WORKER_INSTANCES = 1

      SPARK_WORKER_CORES = 8

 如何處理?

答: a方案每個節點會啟動8個worker執行8個JVM,每個worker將會啟動一個excutors, b方案將會啟動一個worker執行一個JVM。如果資料很小,選擇b方案,因為可以節省啟動JVM的開銷,如果資料很大,啟動JVM的時間可以忽略,則選a方案。

如果5臺機器的記憶體都是48g,a,b方案在新增如下配置:

(a)SPARK_WORKER_MEMORY = 6g     //給每個worker 分配6G 記憶體

(b)SPARK_WORKER_MEMORY = 48g

配置的時候注意:

SPARK_WORKER_CORES * SPARK_WORKER_INSTANCES= 每臺機器總cores  

2.Hadoop配置詳解

1.core-site.xml

常用的設定:

 fs.default.name   hdfs://mastername:9000

這是一個描述叢集中NameNode結點的URI(包括協議、主機名稱、埠號),叢集裡面的每一臺機器都需要知道NameNode的地址。DataNode結點會先在NameNode上註冊,這樣它們的資料才可以被使用。獨立的客戶端程式通過這個URI跟DataNode互動,以取得檔案的塊列表。預設的檔案系統的名稱,預設的是設定單機配置,如果是偽分散式則設定hdfs://localhost:9000,如果是完全分散式則設定成hdfs://mastername:9000

 hadoop.tmp.dir    /tmp/hadoop-${user.name}

hadoop.tmp.dir是hadoop檔案系統依賴的基礎設定,很多路徑都依賴它,如果hdfs-site.xml中不配置namenode和datanode的存放位置,預設就放在這個路徑中,所以最好設定,而且設定到持久目錄中。使用預設的路徑會根據不同的使用者名稱生成不同的臨時目錄。

優化引數:

hadoop.logfile.size       10000000         日誌檔案最大為10M

hadoop.logfile.count      10               日誌檔案數量為10個

hadoop跑了很多工後,可以通過設定hadoop.logfile.size和hadoop.logfile.count來設定最大的日誌大小和數量來自動清楚日誌。

io.file.buffer.size        4096             流檔案的緩衝區為4K 

這是讀寫sequence file的buffer size,可以減少I/O次數,在大型的Hadoop cluster,建議使用更大的值。

hdfs-site.xml

常用設定:

dfs.replication    它決定著 系統裡面的檔案塊的資料備份個數。對於一個實際的應用,它應該被設為3(這個數字並沒有上限,但更多的備份可能並沒有作用,而且會佔用更多的空間)。少於三個的備份,可能會影響到資料的可靠性(系統故障時,也許會造成資料丟失)

dfs.data.dir   這是DataNode結點被指定要儲存資料的本地檔案系統路徑。DataNode結點上的這個路徑沒有必要完全相同,因為每臺機器的環境很可能是不一樣的。但如果每臺機器上的這個路徑都是統一配置的話,會使工作變得簡單一些。預設的情況下,它的hadoop.tmp.dir, 這個路徑只能用於測試的目的,因為,它很可能會丟失掉一些資料。所以,這個值最好還是被覆蓋。

dfs.name.dir   這是NameNode結點儲存hadoop檔案系統資訊的本地系統路徑。這個值只對NameNode有效,DataNode並不需要使用到它。上面對於/temp型別的警告,同樣也適用於這裡。在實際應用中,它最好被覆蓋掉。

dfs.permissions       true     檔案操作時的許可權檢查標識,控制讀寫許可權,false不控制讀寫許可權。

dfs.block.size              67108864          預設的檔案塊大小為64M

hadoop fsck /檔案目錄 –files –locations –blocks  檢視檔案儲存資訊

用法:hadoop fsck [GENERIC_OPTIONS]<path> [-move | -delete | -openforwrite] [-files [-blocks [-locations |-racks]]]

<path>      檢查的起始目錄。

-move      移動受損檔案到/lost+found

-delete     刪除受損檔案。

-openforwrite     打印出寫開啟的檔案。

-files             打印出正被檢查的檔案。

-blocks     打印出塊資訊報告。

-locations     打印出每個塊的位置資訊。

-racks             打印出data-node的網路拓撲結構。

dfs.namenode.logging.level     info        輸出日誌型別

優化設定:

dfs.df.interval                60000         磁碟空間統計間隔為6秒

dfs.client.block.write.retries    3           塊寫入出錯時的重試次數

dfs.heartbeat.interval           3          資料節點的心跳檢測間隔時間

dfs.balance.bandwidthPerSec     1048576     啟動負載均衡的資料節點可利用頻寬最大值為1M

dfs.datanode.failed.volumes.tolerated      0      

決定停止資料節點提供服務充許卷的出錯次數。0次則任何卷出錯都要停止資料節點。

dfs.datanode.data.dir.perm 755          資料節點的存貯塊的目錄訪問許可權設定

更多資訊請參讀:

http://hadoop.apache.org/docs/r2.2.0/hadoop-project-dist/hadoop-hdfs/hdfs-default.xml

mapred-site.xml

mapreduce.framework.name         yarn

mapred.job.tracker     mastername:9001  作業跟蹤管理器是否和MR任務在一個程序中。預設值是local,單節點。Job 執行的host和埠號。

mapred.local.dir       ${hadoop.tmp.dir}/mapred/local  MR的中介資料檔案存放目錄

mapred.system.dir     ${hadoop.tmp.dir}/mapred/system MR的控制檔案存放目錄

mapred.temp.dir       ${hadoop.tmp.dir}/mapred/temp   MR臨時共享檔案存放區

常見名詞解釋:

Driver:使用Driver這一概念的分散式框架很多,比如Hive等,spark中的Driver即執行Application的main() 函式並且建立SparkContext,建立sparkContext的目的是為了準備spark應用程式的執行環境,在spark中由SparkContext負責和clusterManager通訊,進行資源的申請、任務的分配和監控等。當Excutor部分執行完畢後,Driver同時負責將SparkContext關閉,通常用SparkContext代表Driver。

  Excutor:某個Appliction執行在Worker節點上的一個程序,該程序負責執行某些Task,並且負責將資料存在記憶體或者磁碟上。每個Application都有各自獨立的一批Excutor。在Spark on yarn 模式下,程序名稱為CoarseGrainedExcutorBackend。一個CoarseGrainedExcutorBackend程序有且僅有一個Excutor物件,它負責將Task包裝成taskRunner,並從執行緒池中抽取出一個空閒執行緒執行Task,每個CoarseGrainedExcutorBackend能並行執行的Task的數量就取決於分配給他的cpu的個數了。

 Cluster Manager:指的是在叢集上獲取資源的外部服務,目前有:

Standalone:Spark原生的資源管理,有Master負責資源的分配,可以在亞馬遜的EC2上執行。

Apache Mesos:與Hadoop Mapreduce相容性良好的一種資源排程框架;

Hadoop Yarn:主要是指的Yarn的ResourceManger;