[YARN] Yarn下Mapreduce的內存參數理解

博客原文:java

hackershellnode

這篇文章算是給本身從新縷清MR下內存參數的含義算法

Container是什麼?shell

Container就是一個yarn的java進程,在Mapreduce中的AM,MapTask,ReduceTask都做爲Container在Yarn的框架上執行,你能夠在RM的網頁上看到Container的狀態app

基礎框架

Yarn的ResourceManger(簡稱RM)經過邏輯上的隊列分配內存,CPU等資源給application,默認狀況下RM容許最大AM申請Container資源爲8192MB("yarn.scheduler.maximum-allocation-mb"),默認狀況下的最小分配資源爲1024M("yarn.scheduler.minimum-allocation-mb"),AM只能以增量("yarn.scheduler.minimum-allocation-mb")和不會超過("yarn.scheduler.maximum-allocation-mb")的值去向RM申請資源,AM負責將("mapreduce.map.memory.mb")和("mapreduce.reduce.memory.mb")的值規整到能被("yarn.scheduler.minimum-allocation-mb")整除,RM會拒絕申請內存超過8192MB和不能被1024MB整除的資源請求。ide

相關參數spa

YARN日誌

  • yarn.scheduler.minimum-allocation-mbcode

  • yarn.scheduler.maximum-allocation-mb

  • yarn.nodemanager.vmem-pmem-ratio

  • yarn.nodemanager.resource.memory.mb

MapReduce

Map Memory

  • mapreduce.map.java.opts

  • mapreduce.map.memory.mb

Reduce Memory

  • mapreduce.reduce.java.opts

  • mapreduce.reduce.memory.mb

Copy_of_Yarn_mem_params.jpg

從上面的圖能夠看出map,reduce,AM container的JVM,「JVM」矩形表明服務進程,「Max heap」,「Max virtual」矩形表明NodeManager對JVM進程的最大內存和虛擬內存的限制。

以map container內存分配("mapreduce.map.memory.mb")設置爲1536爲例,AM將會爲container向RM請求2048mb的內存資源,由於最小分配單位("yarn.scheduler.minimum-allocation-mb")被設置爲1024,這是一種邏輯上的分配,這個值被NodeManager用來監控改進程內存資源的使用率,若是map Task堆的使用率超過了2048MB,NM將會把這個task給殺掉,JVM進程堆的大小被設置爲1024("mapreduce.map.java.opts=-Xmx1024m")適合在邏輯分配爲2048MB中,一樣reduce container("mapreduce.reduce.memory.mb")設置爲3072也是.

當一個mapreduce job完成時,你將會看到一系列的計數器被打印出來,下面的三個計數器展現了多少物理內存和虛擬內存被分配

Physical memory (bytes) snapshot=21850116096
Virtual memory (bytes) snapshot=40047247360
Total committed heap usage (bytes)=22630105088

虛擬內存

默認的("yarn.nodemanager.vmem-pmem-ratio")設置爲2.1,意味則map container或者reduce container分配的虛擬內存超過2.1倍的("mapreduce.reduce.memory.mb")或("mapreduce.map.memory.mb")就會被NM給KILL掉,若是 ("mapreduce.map.memory.mb") 被設置爲1536那麼總的虛擬內存爲2.1*1536=3225.6MB

當container的內存超出要求的,log將會打印一下信息

Current usage: 2.1gb of 2.0gb physical memory used; 1.6gb of 3.15gb virtual memory used. Killing container.

mapreduce.map.java.opts和mapreduce.map.memory.mb

大概瞭解完以上的參數以後,mapreduce.map.java.opts和mapreduce.map.memory.mb參數之間,有什麼聯繫呢?

經過上面的分析,咱們知道若是一個yarn的container超除了heap設置的大小,這個task將會失敗,咱們能夠根據哪一種類型的container失敗去相應增大mapreduce.{map|reduce}.memory.mb去解決問題。 但同時帶來的問題是集羣並行跑的container的數量少了,因此適當的調整內存參數對集羣的利用率的提高尤其重要。

由於在yarn container這種模式下,JVM進程跑在container中,mapreduce.{map|reduce}.java.opts可以經過Xmx設置JVM最大的heap的使用,通常設置爲0.75倍的memory.mb,由於須要爲java code,非JVM內存使用等預留些空間

補充一下

對於FairScheduler來講(其餘我也沒看),存在着一個增量參數

/** Increment request grant-able by the RM scheduler.

  • These properties are looked up in the yarn-site.xml */
    public static final String RM_SCHEDULER_INCREMENT_ALLOCATION_MB =
    YarnConfiguration.YARN_PREFIX + "scheduler.increment-allocation-mb";
    public static final int DEFAULT_RM_SCHEDULER_INCREMENT_ALLOCATION_MB = 1024;

對於線上2560MB最小分配內存,客戶端的內存爲2048,incrementMemory爲1024,經過其計算算法得出值,demo以下

/**
  • Created by shangwen on 15-9-14.
    */

    public class TestCeil {

    public static void main(String[] args) {

    int clientMemoryReq = 2048;
       int minAllowMermory = 2560;
       int incrementResource = 1024;
       System.out.println(roundUp(Math.max(clientMemoryReq,minAllowMermory),incrementResource));
       // output 3072

    }

    public static int divideAndCeil(int a, int b) {

    if (b == 0) {
           return 0;
       }
       return (a + (b - 1)) / b;

    }

    public static int roundUp(int a, int b) {

    System.out.println("divideAndCeil:" + divideAndCeil(a, b));
       return divideAndCeil(a, b) * b;

    }

    }

得出的結果爲3072MB,即對於map來講,則會分配3G內存,即便你在客戶端寫的是2G,因此你能夠看到如下日誌:

Container [pid=35691,containerID=container_1441194300243_383809_01_000181] is running beyond physical memory limits. Current usage: 3.0 GB of 3 GB physical memory used; 5.4 GB of 9.3 GB virtual memory used.

對於56G內存的NM來講,若是所有跑map則56/3大約跑18個container

假設修改最小分配爲默認的1024,則分配的內存爲2G,即大約能夠跑56/2約28個container。

經過上述的描述,大概就對其參數有個比較綜合的瞭解了。

參考資料

Mapreduce YARN Memory Parameters

相關文章
相關標籤/搜索