Spark Core優化

Spark Tuning概述:
Spark Program的瓶頸:
CPU:
memory:
CPU和memory合稱爲資源
network bandwidth:

Spark哪些地方可以優化:
	storing RDDs in serialized form to decrease memory usage
		以序列化的方式存儲減少內存的使用
	memory:

內存調優:
1. 對象佔用了多少內存 cache測試一下
2. 訪問對象花費的內存
By default, Java objects are fast to access,
but can easily consume a factor of 2-5x more space than
the “raw” data inside their fields
3. GC (garbage collection)

Memory Management
Execution: shuffles, joins, sorts and aggregations
Storage: cache
統一內存管理:
兩者能互相借內存
但是,執行可以強行佔用存儲的內存
存儲不能強行佔用執行的內存 (強行的意思是,兩者都在工作的時候,
如果必要,執行的時候內存不夠了,可以不管storage,直接拿它的內存)

Spark1.5之前默認採用的是StaticMemoryManager,exe的最大安全內存和storage的最大安全內存都是固定的,調優的話需要手動去調優

Spark1.6之後默認採用的是UnifiedMemoryManager
	UnifiedMemoryManager
	// 假如系統內存10G  系統默認的reservedMemory是300M
	val usableMemory = systemMemory - reservedMemory  //10G-300M
	//默認內存最大使用百分之60
        val memoryFraction = conf.getDouble("spark.memory.fraction", 0.6)
	//(10G-300M)*0.6
            (usableMemory * memoryFraction).toLong
	// 最大存儲所佔內存佔0.5 所以最大運行內存也佔0.5
	onHeapStorageRegionSize =
		(maxMemory * conf.getDouble("spark.memory.storageFraction", 0.5)).toLong,

GC:

Serialization:
Java:
large
slow
Kryo(spark2.4對應的是version 4):
並不支持all serializable types
需要註冊 register the classes
quickly
compact(緊湊,小)

	如果沒註冊
	就會慢一些,大一些

	更換序列化方式:
		沒有必要寫到代碼裏
		建議寫到 $SPARK_HOME/conf/spark-default
		也可以 ./spark-submit --conf key=value (優先級高一些)
	
測試數據佔用內存:
	data==>rdd.cache	默認採用MEMORY_ONLY
	data==>rdd.cache()	採用MEMORY_ONLY_SER
	然後將spark.serializer 更改爲Kryo
	data==>rdd.cache()	採用MEMORY_ONLY_SER
	再regist後
	data==>rdd.cache()	採用MEMORY_ONLY_SER

查看RDD佔用內存
	1. put rdd into cache,look at the Storage 
	2. 在代碼中使用SizeEstimator類的estimate方法
		SizeEstimator.estimate(path) 爲啥大了那麼多???

		將文件變成RDD,本身會擴大2-5倍
		但是上面這個estimate爲啥會接近10倍

並行度:
textFile 中的參數 minPartition 可以改用以提升並行度
groupByKey,reduceByKey(在PairRDDFunction)

總體來說:
      set the config property   spark.default.parallelism   to change the default
	可以在配置文件中更改 spark.default.parallelism 來改變默認的並行度

推薦一個core跑兩到三個task(不管是實際core還是虛擬core)

廣播變量:

減少每個task的內存(增加並行度):
分區太大,一個分區裝的數據太多,可能會導致OOM
需要通過增加並行度的方式來解決,這樣可以使每個分區的數量減少。
但是這種增加並行度的方式解決不了數據傾斜

數據本地性:
當一個作業申請到資源以後,需要Driver端將code發到Executor中去,之後需要在Executor上執行操作。
如果Executor執行的這個代碼和他操作需要的數據在一個節點上,這個計算的速度就會很快,效率也會很高
數據本地性是指code和data要儘可能近,最好是能在一個節點(理想)
tips:一個作業在申請完資源後,就被定到一臺機器上了,正常情況下之後再移動的只能是數據
數據和code的位置關係:
PROCESS_LOCAL(最佳) : 兩者在一個JVM裏,是一個進程的操作;這種情況是數據已經cache到executor中了(executor:run tasks and cache data)
NODE_LOCAL: (一臺機器)數據在HDFS上,作業在Executor上;跑的是兩個進程
RACK_LOCAL:
ANY:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章