YARN的Memory和CPU调优配置详解

来源:互联网 发布:数据融合方法概论 编辑:程序博客网 时间:2024/06/06 20:17

转载自:http://blog.javachen.com/2015/06/05/yarn-memory-and-cpu-configuration.html?utm_source=tuicool&utm_medium=referral


Hadoop YARN同时支持内存和CPU两种资源的调度,本文介绍如何配置YARN对内存和CPU的使用。

YARN作为一个资源调度器,应该考虑到集群里面每一台机子的计算资源,然后根据application申请的资源进行分配Container。Container是YARN里面资源分配的基本单位,具有一定的内存以及CPU资源。

在YARN集群中,平衡内存、CPU、磁盘的资源的很重要的,根据经验,每两个container使用一块磁盘以及一个CPU核的时候可以使集群的资源得到一个比较好的利用。

内存配置

关于内存相关的配置可以参考hortonwork公司的文档Determine HDP Memory Configuration Settings来配置你的集群。

YARN以及MAPREDUCE所有可用的内存资源应该要除去系统运行需要的以及其他的hadoop的一些程序,总共保留的内存=系统内存+HBASE内存。

可以参考下面的表格确定应该保留的内存:

每台机子内存系统需要的内存HBase需要的内存4GB1GB1GB8GB2GB1GB16GB2GB2GB24GB4GB4GB48GB6GB8GB64GB8GB8GB72GB8GB8GB96GB12GB16GB128GB24GB24GB255GB32GB32GB512GB64GB64GB

计算每台机子最多可以拥有多少个container,可以使用下面的公式:

containers = min (2*CORES, 1.8*DISKS, (Total available RAM) / MIN_CONTAINER_SIZE)

说明:

  • CORES为机器CPU核数
  • DISKS为机器上挂载的磁盘个数
  • Total available RAM为机器总内存
  • MIN_CONTAINER_SIZE是指container最小的容量大小,这需要根据具体情况去设置,可以参考下面的表格:
每台机子可用的RAMcontainer最小值小于4GB256MB4GB到8GB之间512MB8GB到24GB之间1024MB大于24GB2048MB

每个container的平均使用内存大小计算方式为:

RAM-per-container = max(MIN_CONTAINER_SIZE, (Total Available RAM) / containers))

通过上面的计算,YARN以及MAPREDUCE可以这样配置:

配置文件配置设置默认值计算值yarn-site.xmlyarn.nodemanager.resource.memory-mb8192 MB= containers * RAM-per-containeryarn-site.xmlyarn.scheduler.minimum-allocation-mb1024MB= RAM-per-containeryarn-site.xmlyarn.scheduler.maximum-allocation-mb8192 MB= containers * RAM-per-containeryarn-site.xml (check)yarn.app.mapreduce.am.resource.mb1536 MB= 2 * RAM-per-containeryarn-site.xml (check)yarn.app.mapreduce.am.command-opts-Xmx1024m= 0.8 * 2 * RAM-per-containermapred-site.xmlmapreduce.map.memory.mb1024 MB= RAM-per-containermapred-site.xmlmapreduce.reduce.memory.mb1024 MB= 2 * RAM-per-containermapred-site.xmlmapreduce.map.java.opts = 0.8 * RAM-per-containermapred-site.xmlmapreduce.reduce.java.opts = 0.8 * 2 * RAM-per-container

举个例子:对于128G内存、32核CPU的机器,挂载了7个磁盘,根据上面的说明,系统保留内存为24G,不适应HBase情况下,系统剩余可用内存为104G,计算containers值如下:

containers = min (2*32, 1.8* 7 , (128-24)/2) = min (64, 12.6 , 51) = 13

计算RAM-per-container值如下:

RAM-per-container = max (2, (124-24)/13) = max (2, 8) = 8

你也可以使用脚本yarn-utils.py来计算上面的值:

点击(此处)折叠或打开

  1. #!/usr/bin/env python
  2. import optparse
  3. from pprint import pprint
  4. import logging
  5. import sys
  6. import math
  7. import ast

  8. ''' Reserved for OS + DN + NM, Map: Memory => Reservation '''
  9. reservedStack = { 4:1, 8:2, 16:2, 24:4, 48:6, 64:8, 72:8, 96:12, 
  10.                    128:24, 256:32, 512:64}
  11. ''' Reserved for HBase. Map: Memory => Reservation '''
  12.   
  13. reservedHBase = {4:1, 8:1, 16:2, 24:4, 48:8, 64:8, 72:8, 96:16, 
  14.                    128:24, 256:32, 512:64}
  15. GB = 1024

  16. def getMinContainerSize(memory):
  17.   if (memory <= 4):
  18.     return 256
  19.   elif (memory <= 8):
  20.     return 512
  21.   elif (memory <= 24):
  22.     return 1024
  23.   else:
  24.     return 2048
  25.   pass

  26. def getReservedStackMemory(memory):
  27.   if (reservedStack.has_key(memory)):
  28.     return reservedStack[memory]
  29.   if (memory <= 4):
  30.     ret = 1
  31.   elif (memory >= 512):
  32.     ret = 64
  33.   else:
  34.     ret = 1
  35.   return ret

  36. def getReservedHBaseMem(memory):
  37.   if (reservedHBase.has_key(memory)):
  38.     return reservedHBase[memory]
  39.   if (memory <= 4):
  40.     ret = 1
  41.   elif (memory >= 512):
  42.     ret = 64
  43.   else:
  44.     ret = 2
  45.   return ret
  46.                     
  47. def main():
  48.   log = logging.getLogger(__name__)
  49.   out_hdlr = logging.StreamHandler(sys.stdout)
  50.   out_hdlr.setFormatter(logging.Formatter(' %(message)s'))
  51.   out_hdlr.setLevel(logging.INFO)
  52.   log.addHandler(out_hdlr)
  53.   log.setLevel(logging.INFO)
  54.   parser = optparse.OptionParser()
  55.   memory = 0
  56.   cores = 0
  57.   disks = 0
  58.   hbaseEnabled = True
  59.   parser.add_option('-c', '--cores', default = 16,
  60.                      help = 'Number of cores on each host')
  61.   parser.add_option('-m', '--memory', default = 64, 
  62.                     help = 'Amount of Memory on each host in GB')
  63.   parser.add_option('-d', '--disks', default = 4, 
  64.                     help = 'Number of disks on each host')
  65.   parser.add_option('-k', '--hbase', default = "True",
  66.                     help = 'True if HBase is installed, False is not')
  67.   (options, args) = parser.parse_args()
  68.   
  69.   cores = int (options.cores)
  70.   memory = int (options.memory)
  71.   disks = int (options.disks)
  72.   hbaseEnabled = ast.literal_eval(options.hbase)
  73.   
  74.   log.info("Using cores=" + str(cores) + " memory=" + str(memory) + "GB" +
  75.             " disks=" + str(disks) + " hbase=" + str(hbaseEnabled))
  76.   minContainerSize = getMinContainerSize(memory)
  77.   reservedStackMemory = getReservedStackMemory(memory)
  78.   reservedHBaseMemory = 0
  79.   if (hbaseEnabled):
  80.     reservedHBaseMemory = getReservedHBaseMem(memory)
  81.   reservedMem = reservedStackMemory + reservedHBaseMemory
  82.   usableMem = memory - reservedMem
  83.   memory -= (reservedMem)
  84.   if (memory < 2):
  85.     memory = 2
  86.     reservedMem = max(0, memory - reservedMem)
  87.     
  88.   memory *= GB
  89.   
  90.   containers = int (min(* cores,
  91.                          min(math.ceil(1.* float(disks)),
  92.                               memory/minContainerSize)))
  93.   if (containers <= 2):
  94.     containers = 3

  95.   log.info("Profile: cores=" + str(cores) + " memory=" + str(memory) + "MB"
  96.            + " reserved=" + str(reservedMem) + "GB" + " usableMem="
  97.            + str(usableMem) + "GB" + " disks=" + str(disks))
  98.     
  99.   container_ram = abs(memory/containers)
  100.   if (container_ram > GB):
  101.     container_ram = int(math.floor(container_ram / 512)) * 512
  102.   log.info("Num Container=" + str(containers))
  103.   log.info("Container Ram=" + str(container_ram) + "MB")
  104.   log.info("Used Ram=" + str(int (containers*container_ram/float(GB))) + "GB")
  105.   log.info("Unused Ram=" + str(reservedMem) + "GB")
  106.   log.info("yarn.scheduler.minimum-allocation-mb=" + str(container_ram))
  107.   log.info("yarn.scheduler.maximum-allocation-mb=" + str(containers*container_ram))
  108.   log.info("yarn.nodemanager.resource.memory-mb=" + str(containers*container_ram))
  109.   map_memory = container_ram
  110.   reduce_memory = 2*container_ram if (container_ram <= 2048) else container_ram
  111.   am_memory = max(map_memory, reduce_memory)
  112.   log.info("mapreduce.map.memory.mb=" + str(map_memory))
  113.   log.info("mapreduce.map.java.opts=-Xmx" + str(int(0.* map_memory)) +"m")
  114.   log.info("mapreduce.reduce.memory.mb=" + str(reduce_memory))
  115.   log.info("mapreduce.reduce.java.opts=-Xmx" + str(int(0.* reduce_memory)) + "m")
  116.   log.info("yarn.app.mapreduce.am.resource.mb=" + str(am_memory))
  117.   log.info("yarn.app.mapreduce.am.command-opts=-Xmx" + str(int(0.8*am_memory)) + "m")
  118.   log.info("mapreduce.task.io.sort.mb=" + str(int(0.* map_memory)))
  119.   pass

  120. if __name__ == '__main__':
  121.   try:
  122.     main()
  123.   except(KeyboardInterrupt, EOFError):
  124.     print("\nAborting ... Keyboard Interrupt.")
  125.     sys.exit(1)


执行下面命令:

python yarn-utils.py -c 32 -m 128 -d 7 -k False 


返回结果如下:

点击(此处)折叠或打开

  1. Using cores=32 memory=128GB disks=7 hbase=False
  2.  Profile: cores=32 memory=106496MB reserved=24GB usableMem=104GB disks=7
  3.  Num Container=13
  4.  Container Ram=8192MB
  5.  Used Ram=104GB
  6.  Unused Ram=24GB
  7.  yarn.scheduler.minimum-allocation-mb=8192
  8.  yarn.scheduler.maximum-allocation-mb=106496
  9.  yarn.nodemanager.resource.memory-mb=106496
  10.  mapreduce.map.memory.mb=8192
  11.  mapreduce.map.java.opts=-Xmx6553m
  12.  mapreduce.reduce.memory.mb=8192
  13.  mapreduce.reduce.java.opts=-Xmx6553m
  14.  yarn.app.mapreduce.am.resource.mb=8192
  15.  yarn.app.mapreduce.am.command-opts=-Xmx6553m
  16.  mapreduce.task.io.sort.mb=3276



这样的话,每个container内存为8G,似乎有点多,我更愿意根据集群使用情况任务将其调整为2G内存,则集群中下面的参数配置值如下:

配置文件配置设置计算值yarn-site.xmlyarn.nodemanager.resource.memory-mb= 52 * 2 =104 Gyarn-site.xmlyarn.scheduler.minimum-allocation-mb= 2Gyarn-site.xmlyarn.scheduler.maximum-allocation-mb= 52 * 2 = 104Gyarn-site.xml (check)yarn.app.mapreduce.am.resource.mb= 2 * 2=4Gyarn-site.xml (check)yarn.app.mapreduce.am.command-opts= 0.8 * 2 * 2=3.2Gmapred-site.xmlmapreduce.map.memory.mb= 2Gmapred-site.xmlmapreduce.reduce.memory.mb= 2 * 2=4Gmapred-site.xmlmapreduce.map.java.opts= 0.8 * 2=1.6Gmapred-site.xmlmapreduce.reduce.java.opts= 0.8 * 2 * 2=3.2G

对应的xml配置为:

点击(此处)折叠或打开

  1. <property>
  2.       <name>yarn.nodemanager.resource.memory-mb</name>
  3.       <value>106496</value>
  4.   </property>
  5.   <property>
  6.       <name>yarn.scheduler.minimum-allocation-mb</name>
  7.       <value>2048</value>
  8.   </property>
  9.   <property>
  10.       <name>yarn.scheduler.maximum-allocation-mb</name>
  11.       <value>106496</value>
  12.   </property>
  13.   <property>
  14.       <name>yarn.app.mapreduce.am.resource.mb</name>
  15.       <value>4096</value>
  16.   </property>
  17.   <property>
  18.       <name>yarn.app.mapreduce.am.command-opts</name>
  19.       <value>-Xmx3276m</value>
  20.   </property>

另外,还有一下几个参数:

  • yarn.nodemanager.vmem-pmem-ratio:任务每使用1MB物理内存,最多可使用虚拟内存量,默认是2.1。
  • yarn.nodemanager.pmem-check-enabled:是否启动一个线程检查每个任务正使用的物理内存量,如果任务超出分配值,则直接将其杀掉,默认是true。
  • yarn.nodemanager.vmem-pmem-ratio:是否启动一个线程检查每个任务正使用的虚拟内存量,如果任务超出分配值,则直接将其杀掉,默认是true。

第一个参数的意思是当一个map任务总共分配的物理内存为2G的时候,该任务的container最多内分配的堆内存为1.6G,可以分配的虚拟内存上限为2*2.1=4.2G。另外,照这样算下去,每个节点上YARN可以启动的Map数为104/2=52个。

CPU配置

YARN中目前的CPU被划分成虚拟CPU(CPU virtual Core),这里的虚拟CPU是YARN自己引入的概念,初衷是,考虑到不同节点的CPU性能可能不同,每个CPU具有的计算能力也是不一样的,比如某个物理CPU的计算能力可能是另外一个物理CPU的2倍,这时候,你可以通过为第一个物理CPU多配置几个虚拟CPU弥补这种差异。用户提交作业时,可以指定每个任务需要的虚拟CPU个数。

在YARN中,CPU相关配置参数如下:

  • yarn.nodemanager.resource.cpu-vcores:表示该节点上YARN可使用的虚拟CPU个数,默认是8,注意,目前推荐将该值设值为与物理CPU核数数目相同。如果你的节点CPU核数不够8个,则需要调减小这个值,而YARN不会智能的探测节点的物理CPU总数。
  • yarn.scheduler.minimum-allocation-vcores:单个任务可申请的最小虚拟CPU个数,默认是1,如果一个任务申请的CPU个数少于该数,则该对应的值改为这个数。
  • yarn.scheduler.maximum-allocation-vcores:单个任务可申请的最多虚拟CPU个数,默认是32。

对于一个CPU核数较多的集群来说,上面的默认配置显然是不合适的,在我的测试集群中,4个节点每个机器CPU核数为31,留一个给操作系统,可以配置为:

点击(此处)折叠或打开

  1. <property>
  2.       <name>yarn.nodemanager.resource.cpu-vcores</name>
  3.       <value>31</value>
  4.   </property>
  5.   <property>
  6.       <name>yarn.scheduler.maximum-allocation-vcores</name>
  7.       <value>124</value>
  8.   </property>

阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 偏差 偏差值 认知偏差 进度偏差 偏差英语 决策偏差 投资偏差和进度偏差 基本偏差 相对平均偏差 相对平均偏差公式 相对偏差计算公式 相对偏差公式 标准偏差公式 相对标准偏差 偏差计算公式 相对平均偏差计算公式 相对标准偏差公式 标准偏差计算公式 平均偏差计算公式 平均偏差公式 标准偏差怎么算 桩位偏差允许范围 左右眼视力偏差大怎么办 相对偏差怎么算 平均值标准偏差 偏差的计算公式 平均偏差的计算公式 相对平均偏差范围 钢筋直径允许偏差 平均值的标准偏差 平均值的标准偏差的计算公式 塔吊垂直度允许偏差 墙体垂直度允许偏差 人工挖孔桩轴线偏差 分户验收层高允许偏差 偏心老太太 陛下太偏心 偏心轮 偏心 快穿之偏心 偏心轮机构