您好,登錄后才能下訂單哦!
怎么解決yarn-cluster模式的JVM棧內(nèi)存溢出問題,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。
公司里面你的機(jī)器節(jié)點(diǎn)一般都是虛擬機(jī)??!所以yarn-client會(huì)有網(wǎng)絡(luò)激增的問題!Yarn-client模式可以跑,但是Yarn-cluster模式不能跑,就是報(bào)那么一個(gè)JVM永久代溢出的那么一個(gè)問題!
spark-submit腳本提交spark application到ResourceManager
去ResourceManager申請(qǐng)啟動(dòng)ApplicationMaster
通知一個(gè)NodeManager去啟動(dòng)ApplicationMaster(Driver進(jìn)程)
ApplicationMaster去找ResourceManager申請(qǐng)Executor
ResourceManager分配container,container代表你能啟動(dòng)的Executor占有的資源,包括內(nèi)存+CPU返回已經(jīng)啟動(dòng)container的NodeManager的地址
ApplicationMaster去找NodeManager在container里面申請(qǐng)啟動(dòng)Executor
Executor進(jìn)程會(huì)反過來去向Driver注冊(cè)上去
最后Driver接收到了Executor資源之后就可以去進(jìn)行我們spark代碼的執(zhí)行了
執(zhí)行到某個(gè)action就觸發(fā)一個(gè)JOB
DAGScheduler會(huì)劃分JOB為一個(gè)個(gè)Stage
TaskScheduler會(huì)劃分Stage為一個(gè)個(gè)Task
Task發(fā)送到Executor執(zhí)行
Driver就來進(jìn)行Task的調(diào)度
到這里為止,ApplicationMaster(Driver),就知道自己有哪些資源可以用(executor)。然后就會(huì)去執(zhí)行job、拆分stage、提交stage的task,進(jìn)行task調(diào)度,分配到各個(gè)executor上面去執(zhí)行。
總結(jié)一下yarn-client和yarn-cluster模式的不同之處:
yarn-client模式,driver運(yùn)行在本地機(jī)器上的;
yarn-cluster模式,driver是運(yùn)行在yarn集群上某個(gè)nodemanager節(jié)點(diǎn)上面的。
yarn-client會(huì)導(dǎo)致本地機(jī)器負(fù)責(zé)spark作業(yè)的調(diào)度,所以網(wǎng)卡流量會(huì)激增;
yarn-cluster模式就沒有這個(gè)問題。
yarn-client的driver運(yùn)行在本地,通常來說本地機(jī)器跟yarn集群都不會(huì)在一個(gè)機(jī)房的,所以說性能可能不是特別好;
yarn-cluster模式下,driver是跟yarn集群運(yùn)行在一個(gè)機(jī)房內(nèi),性能上來說,也會(huì)好一些。
實(shí)踐經(jīng)驗(yàn),碰到的yarn-cluster的問題:
有的時(shí)候,運(yùn)行一些包含了spark sql的spark作業(yè),可能會(huì)碰到y(tǒng)arn-client模式下,可以正常提交運(yùn)行;yarn-cluster模式下,可能是無法提交運(yùn)行的,會(huì)報(bào)出JVM的PermGen(永久代)的內(nèi)存溢出,OOM。JVM里面的一個(gè)區(qū)域,就是會(huì)放Class里面一些字符串常量這些東西的。
yarn-client模式下,driver是運(yùn)行在本地機(jī)器上的,spark使用的JVM的PermGen的配置,是本地的spark-class文件(spark客戶端是默認(rèn)有配置的),JVM的永久代的大小是128M,這個(gè)是沒有問題的;但是呢,在yarn-cluster模式下,driver是運(yùn)行在yarn集群的某個(gè)節(jié)點(diǎn)上的,使用的是沒有經(jīng)過配置的默認(rèn)設(shè)置(PermGen永久代大?。?,82M。
spark-sql,它的內(nèi)部是要進(jìn)行很復(fù)雜的SQL的語義解析、語法樹的轉(zhuǎn)換等等,特別復(fù)雜,在這種復(fù)雜的情況下,如果說你的sql本身特別復(fù)雜的話,很可能會(huì)比較導(dǎo)致性能的消耗,內(nèi)存的消耗??赡軐?duì)PermGen永久代的占用會(huì)比較大。
所以,此時(shí),如果對(duì)永久代的占用需求,超過了82M的話,但是呢又在128M以內(nèi);就會(huì)出現(xiàn)如上所述的問題,yarn-client模式下,默認(rèn)是128M,這個(gè)還能運(yùn)行;如果在yarn-cluster模式下,默認(rèn)是82M,就有問題了。會(huì)報(bào)出PermGen Out of Memory error log。
如何解決這種問題?
既然是JVM的PermGen永久代內(nèi)存溢出,那么就是內(nèi)存不夠用。咱們呢,就給yarn-cluster模式下的,driver的PermGen多設(shè)置一些。
//spark-submit腳本中,加入以下配置即可: --conf spark.driver.extraJavaOptions="-XX:PermSize=128M -XX:MaxPermSize=256M" //這個(gè)就設(shè)置了driver永久代的大小,默認(rèn)是128M,最大是256M。那么,這樣的話, //就可以基本保證你的spark作業(yè)不會(huì)出現(xiàn)上述的yarn-cluster模式導(dǎo)致的永久代內(nèi)存溢出的問題。
多講一句,可能還有一個(gè)問題(spark sql,sql,要注意,一個(gè)問題)
sql,有大量的or語句。比如where keywords='' or keywords='' or keywords='' ,當(dāng)or語句,有成百上千的時(shí)候,此時(shí)可能就會(huì)出現(xiàn)一個(gè)driver端的jvm stack overflow,JVM棧內(nèi)存溢出的問題
JVM棧內(nèi)存溢出,基本上就是由于調(diào)用的方法層級(jí)過多,因?yàn)楫a(chǎn)生了大量的,非常深的,超出了JVM棧深度限制的,遞歸。遞歸方法。我們的猜測,spark sql,有大量or語句的時(shí)候,spark sql內(nèi)部源碼中,在解析sql,比如轉(zhuǎn)換成語法樹,或者進(jìn)行執(zhí)行計(jì)劃的生成的時(shí)候,對(duì)or的處理是遞歸。or特別多的話,就會(huì)發(fā)生大量的遞歸。
JVM Stack Memory Overflow,棧內(nèi)存溢出。
這種時(shí)候,建議不要搞那么復(fù)雜的spark sql語句。采用替代方案:將一條sql語句,拆解成多條sql語句來執(zhí)行。每條sql語句,就只有100個(gè)or子句以內(nèi);一條一條SQL語句來執(zhí)行。根據(jù)生產(chǎn)環(huán)境經(jīng)驗(yàn)的測試,一條sql語句,100個(gè)or子句以內(nèi),是還可以的。通常情況下,不會(huì)報(bào)那個(gè)棧內(nèi)存溢出。
看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。