1. 程式人生 > >08JVM調優之原理概述以及降低cache操作的記憶體佔比

08JVM調優之原理概述以及降低cache操作的記憶體佔比

效能調優分類

  1. 常規效能調優:分配資源、並行度等等方式。

  2. JVM 調優(Java虛擬機器):JVM相關的引數。通常情況下,如果你的硬體配置、基礎的 JVM 的配置都 ok 的話,JVM 通常不會造成太嚴重的效能問題,反而更多的是在 troubleshooting 中 JVM 佔了很重要的地位, JVM 造成線上的 spark 作業的執行報錯,甚至失敗(比如OOM)。

  3. shuffle 調優(相當重要):spark 在執行 groupByKey、reduceByKey 等操作時的 shuffle 環節的調優,這個很重要。shuffle 調優其實對 spark 作業的效能的影響是相當之高!經驗總結:在 spark 作業的執行過程中只要一牽扯到有 shuffle 的操作,基本上 shuffle 操作的效能消耗要佔到整個 spark 作業的 50%~90%。

  4. spark 操作調優(spark運算元調優,比較重要):原來使用groupByKey進行的操作現在使用 countByKey 或 aggregateByKey 來重構實現,用foreachPartition替代foreach。有些運算元的效能是比其他一些運算元的效能要高的。如果一旦遇到合適的情況,效果還是不錯的。

調優順序最好依照:

  1. 分配資源、並行度、RDD架構與快取;
  2. shuffle調優;
  3. spark運算元調優;
  4. JVM調優、廣播大變數……

理論基礎

Spark 是用 scala 開發的,大家不要以為 scala 就跟java一點關係都沒有了,這是一個很常見的錯誤。spark 的 scala 程式碼呼叫了很多 java api,scala 也是執行在 java 虛擬機器中的,spark 是執行在 java 虛擬機器中的。java虛擬機器可能會產生的問題就是記憶體不足!我們的 RDD 的快取、task執行定義的運算元函式可能會建立很多物件,都可能會佔用大量記憶體,沒搞好的話,可能導致JVM出問題。

JVM結構

這裡寫圖片描述
JVM中的堆記憶體存放我們建立的一些物件,堆記憶體裡有年輕代(yong generation)和老年代(old generation),年輕代內部又分為三部分:Eden區域和兩個survivor 區域。理想情況下,老年代都是放一些宣告週期很長的物件,數量應該是很少的,比如資料庫連線池。

我們在 spark task 執行運算元函式的時候可能會建立很多物件,這些物件都是要放入JVM 年輕代中的。

每一次放物件的時候都是放入 eden 區域和其中一個 survivor 區域,另外一個 survivor 區域是空閒的。當 eden 區域和一個 survivor 區域放滿了以後(spark執行過程中,產生的物件實在太多了)就會觸發 minor gc(小型垃圾回收),把不再使用的物件從記憶體中清空,給後面新建立的物件騰出來點兒地方。

清理掉了不再使用的物件之後,也會將存活下來的物件(還要繼續使用的)放入之前空閒的那一個 survivor 區域中。這裡可能會出現一個問題:預設 eden、survior1 和 survivor2 的記憶體佔比是 8:1:1,問題是如果存活下來的物件是1.5,一個 survivor區域放不下,此時就可能通過JVM的擔保機制(不同JVM版本可能對應的行為)將多餘的物件直接放入老年代了。

如果你的JVM記憶體不夠大的話,可能導致頻繁的年輕代記憶體滿溢,頻繁的進行 minor gc,頻繁的 minor gc 會導致短時間內有些存活的物件多次垃圾回收都沒有回收掉,會導致這種短宣告週期(其實不一定是要長期使用的)物件年齡過大(垃圾回收次數太多還沒有回收到)跑到老年代。

老年代中可能會因為記憶體不足囤積非常多的短生命週期的,本來應該在年輕代中的可能馬上就要被回收掉的物件。此時,可能導致老年代頻繁滿溢,頻繁進行 full gc(全域性/全面垃圾回收),full gc就會去回收老年代中的物件。full gc由於這個演算法的設計針對的是老年代中的物件數量很少,滿溢進行full gc的頻率應該很少,因此採取了不太複雜,但是耗費效能和時間的垃圾回收演算法,full gc很慢。

full gc / minor gc無論是快還是慢,都會導致 jvm 的工作執行緒停止工作(stop the world)。簡而言之,就是說:gc 的時候 spark 停止工作了,等著垃圾回收結束。

記憶體不充足的時候會導致的問題: 
1. 頻繁minor gc 也會導致頻繁spark停止工作; 
2. 老年代囤積大量活躍物件(短生命週期的物件)導致頻繁full gc,full gc時間很長,短則數十秒,長則數分鐘,甚至數小時,可能導致 spark 長時間停止工作。 
3. 嚴重影響咱們的 spark 的效能和執行的速度。

JVM調優

JVM調優的第一個點:降低cache操作的記憶體佔比 
spark 中堆記憶體又被劃分成了兩塊兒,一塊兒是專門用來給 RDD 的cache、persist 操作進行 RDD 資料快取用的;另外一塊兒是用來給 spark 運算元函式的執行使用的,用來存放函式中自己建立的物件。

預設情況下,給RDD cache操作的記憶體佔比是0.6,也就是說60%的記憶體都給了cache 操作了。但是問題是如果某些情況下 cache 不是那麼的緊張,問題在於 task 運算元函式中建立的物件過多,然後記憶體又不太大,導致了頻繁的minor gc,甚至頻繁full gc,導致spark頻繁的停止工作,效能影響會很大。

針對上述這種情況,大家可以在spark ui 中yarn 的介面去檢視 spark 作業的執行統計,一層一層點選進去可以看到每個stage 的執行情況,包括每個task的執行時間、gc時間等等。如果發現gc太頻繁,時間太長,此時就可以適當調價這個比例。降低cache操作的記憶體佔比,大不了用 persist 操作選擇將一部分快取的RDD資料寫入磁碟或者序列化方式,配合Kryo序列化類減少RDD快取的記憶體佔用,降低cache操作記憶體佔比,對應的運算元函式的記憶體佔比就提升了。這個時候,可能就可以減少 minor gc 的頻率,同時減少 full gc 的頻率,對效能的提升是有一定的幫助的。

最終實現的效果就是:讓 task 執行運算元函式時,有更多的記憶體可以使用。

程式碼實現

通過spark.storage.memoryFraction引數進行調節 cache 記憶體佔比,預設是0.6,可以調節為 0.5 , 0.4 或 0.2,具體調節資料要根據 yarn 介面的spark執行統計而定。具體在專案中設定是在構建Spark上下文的時候傳入這個引數:

        SparkConf conf = new SparkConf()
                .setAppName(Constants.SPARK_APP_NAME_SESSION)
                .setMaster("local")
                .set("spark.storage.memoryFraction", "0.5")
                .set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
                .registerKryoClasses(new Class[]{
                        CategorySortKey.class,
                        IntList.class});    

相關推薦

08JVM調原理概述以及降低cache操作記憶體

效能調優分類常規效能調優:分配資源、並行度等等方式。JVM 調優(Java虛擬機器):JVM相關的引數。通常情況下,如果你的硬體配置、基礎的 JVM 的配置都 ok 的話,JVM 通常不會造成太嚴重的效能問題,反而更多的是在 troubleshooting 中 JVM 佔了很

spark JVM調原理概述以及降低cache操作記憶體

每一次放物件的時候,都是放入eden區域,和其中一個survivor區域;另外一個survivor區域是空閒的。 當eden區域和一個survivor區域放滿了以後(spark執行過程中,產生的物件實在太多了),就會觸發minor gc,小型垃圾回收。把不再使用的物件,從記憶體中清空,給後面新建立

Spark效能調原理分析

spark效能調優之前先明白原理,具體如下: 使用spark-submit提交一個Spark作業之後,這個作業就會啟動一個對應的Driver程序。根據使用的部署模式(deploy-mode)不同,Driver程序可能在本地啟動,也可能在叢集中某個工作節點上啟動。Driver程序本身會根

JVM調探索CMS和G1的實體記憶體歸還機制

前言: 公司有一個資產統計系統,使用頻率很低,但是要求在使用時查詢速度快,因此想到做一些快取放在記憶體中,在長時間沒有使用,持久化到磁碟中,並對垃圾進行回收,歸還實體記憶體給作業系統,從而節省寶貴資源給其它業務系統。當我做好快取時,卻發現了一個棘手的問題,通過程式釋放資源並通知GC回收資源後,堆記憶體的已用記

效能調MySQL篇三:MySQL配置定位以及優化

1、優化方式 一般的優化方法有:硬體優化,配置優化,sql優化,表結構優化。下面僅僅介紹配置優化,具體優化設定可以參考本人另外一篇部落格,傳送門:https://www.cnblogs.com/langhuagungun/p/9507206.html 2、mysql配置分析 1)常見瓶頸 90%系統瓶

效能調MySQL篇四:MySQL配置定位以及優化

一、CPU最大效能模式 cpu利用特點 5.1 最高可用4個核 5.5 最高可用24核 5.6 最高可用64核心 一次query對應一個邏輯CPU 你仔細檢查的話,有些伺服器上會有的一個有趣的現象:你cat /proc/cpuinfo時,會發現CPU的頻率竟然跟它標

Spark效能調——在實際專案中重構RDD架構以及RDD持久化

一、RDD架構重構與優化是什麼。 儘量去複用RDD,差不多的RDD,可以抽取為一個共同的RDD,供後面的RDD計算時,反覆使用。 二、怎麼做? 快取級別: case "NONE" => NONE case "DISK_ONL

Spark性能調道——解決Spark數據傾斜(Data Skew)的N種姿勢

sca ace 便是 triplet 大小 spark 構建 由於 itl 原文:http://blog.csdn.net/tanglizhe1105/article/details/51050974 背景 很多使用Spark的朋友很想知道rdd

spark性能調資源調

重要 cnblogs logs 做的 參數說明 span 分配 比例 drive 轉https://tech.meituan.com/spark-tuning-basic.html spark作業原理 使用spark-submit提交一個Spark作業之後,這個作

ORACLE sql調記錄一次trim函數引發的大表全表掃描

oracle trim 全表掃描 sql 調優 2017年8月14日,一地市oracle相關的調度程序ETL抽取速度奇慢,sql語句每次執行平均時間要9秒左右,如果所示:該調度過程涉及的sql語句如下:select count(*) from (SELECT rtrim(

七、Hadoop學習筆記————調Hadoop參數調

node 參數 受限 .com 資源 mage 預留空間 嘗試 nod dfs.datanode.handler.count默認為3,大集群可以調整為10 傳統MapReduce和yarn對比 如果服務器物理內存128G,則容器內存建議為100比較合理 配置總

八、Hadoop學習筆記————調Hive調

需要 cnblogs log logs nbsp .cn 集中 bsp 9.png 表1表2的join和表3表4的join同時運行 此法需要關註是否有數據傾斜(大量數據集中在某一區間段) 八、Hadoop學習筆記————調優之Hive調優

【Spark篇】---Spark調代碼調,數據本地化調,內存調,SparkShuffle調,Executor的堆外內存調

左右 任務調度 combiner flight 觸發 年齡 ans minor 序列化機制 一、前述 Spark中調優大致分為以下幾種 ,代碼調優,數據本地化,內存調優,SparkShuffle調優,調節Executor的堆外內存。 二、具體 1、代碼調優 1、避免創

JVM調jstack找出最耗cpu的線程並定位代碼

grep 輪詢 tin jstack stack ads OS 分享 bject jstack可以定位到線程堆棧,根據堆棧信息我們可以定位到具體代碼,所以它在JVM性能調優中使用得非常多。下面我們來一個實例找出某個Java進程中最耗費CPU的Java線程並定位堆棧信息,用到

Apache調開啟deflate壓縮模塊

Apache 壓縮 模塊 調優 啟用Apache的deflate模塊,可以開啟壓縮功能,減小網站傳輸時的帶寬。apache需要編譯安裝方式,以/usr/local/apache為apache的安裝目錄,以源碼包/usr/local/src/httpd-2.4.33為例首先查看/usr/loca

Spark學習路 (十一)SparkCore的調Spark內存模型

精準 規模 memory 此外 結構定義 申請 管理方式 存儲 內部 摘抄自:https://www.ibm.com/developerworks/cn/analytics/library/ba-cn-apache-spark-memory-management/index

Spark學習路 (十二)SparkCore的調資源調JVM的基本架構

程序員 存儲 src ron 指示器 引用 double strong 功能 一、JVM的結構圖 1.1 Java內存結構 JVM內存結構主要有三大塊:堆內存、方法區和棧。 堆內存是JVM中最大的一塊由年輕代和老年代組成,而年輕代內存又被分成三部分,Eden空間、

Spark學習路 (十二)SparkCore的調資源調

限制 無法 數據 block 可能 executors 頻繁 通過 操作 摘抄自:https://tech.meituan.com/spark-tuning-basic.html 一、概述 在開發完Spark作業之後,就該為作業配置合適的資源了。Spark的資源參數,基

Spark學習路 (十四)SparkCore的調資源調JVM的GC垃圾收集器

當前 復制 event 只需要 引用 應用 之前 相互 分享 一、概述 垃圾收集 Garbage Collection 通常被稱為“GC”,它誕生於1960年 MIT 的 Lisp 語言,經過半個多世紀,目前已經十分成熟了。 jvm 中,程序計數

Linux系統性能調性能分析

ios 狀況 CP data- lin raid5 生成 參考 .so 1.Linux性能分析的目的1)找出系統性能瓶頸(包括硬件瓶頸和軟件瓶頸);2)提供性能優化的方案(升級硬件?改進系統系統結構?);3)達到合理的硬件和軟件配置;4)使系統資源使用達到最大的平衡。(一般