最近一直在学习hadoop的一些原理和优化,然后也做了一些实践,也有没有去做实践的,反正个人观点都记录下来
一、yarn的介绍
YARN的基本结构由一个ResourceManager与多个NodeManager组成。ResourceManager负责对NodeManager所持有的资源进行统一管理和调度。当在处理一个作业时ResourceManager会在NodeManager所在节点创建一全权负责单个作业运行和监控的程序ApplicationMaster。
1、ResouceManager(简称RM)
资源管理器负责整个集群资源的调度,该组件由两部分构成:调度器(Scheduler)和ApplicationsManager。调度器会根据特定调度器实现调度算法,结合作业所在的队列资源容量,将资源按调度算法分配给每个任务。分配的资源将用容器(container)形式提供,容器是一个相对封闭独立的环境,已经将CPU、内存及任务运行所需环境条件封装在一起。通过容器可以很好地限定每个任务使用的资源量。YARN调度器目前在生产环境中被用得较多的有两种:能力调度器(Capacity Scheduler)和公平调度器(Fair Scheduler)(FIFO一般都不使用)。
2、ApplicationMaster(简称AM)
每个提交到集群的作业(job)都会有一个与之对应的AM 来管理。它负责进行数据切分,并为当前应用程序向RM 去申请资源,当申请到资源时会和NodeManager 通信,启动容器并运行相应的任务。此外,AM还负责监控任务(task)的状态和执行的进度。
3、NodeManage(简称NM)
NodeManager负责管理集群中单个节点的资源和任务,每个节点对应一个NodeManager, NodeManager负责接收ApplicationMaster的请求启动容器,监控容器的运行状态,并监控当前节点状态及当前节点的资源使用情况和容器的运行情况,并定时回报给ResourceManager
更具体点的知识可以参考hadoop之yarn详解(基础架构篇)、hadoop之yarn详解(框架进阶篇)和hadoop之yarn详解(命令篇)这几篇文章
二、yarn的优化
丢个官网:https://hadoop.apache.org/docs/stable/hadoop-yarn/hadoop-yarn-common/yarn-default.xml
这里不说调度器的配置,一般都是选用能力调度器(Capacity Scheduler)和公平调度器(Fair Scheduler),这些一般都是根据公司的具体情况进行配置,比如根据用户配置资源比例,或者更具时间点的不同配置,毕竟有时候离线计算在某些时候压力会比较大,可以根据公司的具体情况,对具体的一些时间段进行相应的调整,防止集群压力过大,造成集群不健康。
2.1、资源配置
在YARN中可供分配和管理的资源有内存和CPU资源,在Hadoop 3.0中将GPU、FPGA资源也纳入可管理的资源中。
既然yarn是用来管理资源的,所以资源的来源还是来源于服务器的cpu和内存。所以也就是我们配置服务器的多少资源作为yarn的资源。这里有两种配置,一种是自己更具服务器的资源,自己判断预留给服务器多少资源提供给其他服务,其他配置给yarn作为资源,还有一种就是让yarn去扫描服务器的资源,按照比例进行配置(这个理论上可行,没有实践)
这里再说一句,优化这个东西呢其他在集群没有出现瓶颈的时候就不要去优化,一个是看不出效果,还有就是浪费时间,反正资源够用,没啥好优化的,优化的目的就是在有限的资源下,保证集群的稳定,又能挺高资源的利用率和提高集群的并发能力。
首先我们说第一种:手动配置固定的资源给yarn
yarn.nodemanager.resource.cpu-vcores,默认值为-1。默认表示集群中每个节点可被分配的虚拟CPU个数为8。为什么这里不是物理CPU个数?因为考虑一个集群中所有的机器配置不可能一样,即使同样是16核心的CPU性能也会有所差异,所以YARN在物理CPU和用户之间加了一层虚拟CPU,一个物理CPU可以被划分成多个虚拟的CPU。这里确实可以配置超过物理cpu的个数,确实能够提高并发,但是尝试了一把,这样子服务器的负载就很大了,基本上是处理不过来,而且这样配置没有个服务器留有空余的cpu去执行其他的任务或者其他的集群。因为是生产环境,也没敢去做压测,检测到服务器的负载都是cpu核数的十倍了,所以负载太大,不太敢太激进,所以最终配置是比物理cup核数少那么几个,预留几个cpu给服务器或者其他服务使用。
yarn.nodemanager.resource.memory-mb,默认值为-1。当该值为-1时,默认表示集群中每个节点可被分配的物理内存是8GB。这个一般配置是给服务器预留20%的内存即可。
接下来说说第二种:让yarn自动探测服务器的资源,然后预留一定比例给服务器,然后就可以把vcore调的大一些,这样既能提高cpu的使用率,有能保证给服务器留有一定的cpu
首先yarn.nodemanager.resource.cpu-vcores和yarn.nodemanager.resource.memory-mb都要采用默认值-1,这样如下的配置才会生效:
yarn.nodemanager.resource.detect-hardware-capabilities 配置为true,表示可以让yarn自动探测服务器的资源,比如cpu和内存等
然后我们就配置可以留给服务器的内存和可以使用物理cpu的比例:
yarn.nodemanager.resource.system-reserved-memory-mb:YARN保留的物理内存,给非YARN任务使用,该值一般不生效,只有当yarn.nodemanager.resource.detect-hardware-capabilities为true的状态才会启用,会根据系统的情况自动计算
yarn.nodemanager.resource.percentage-physical-cpu-limit:默认是100,表示100%使用,这里我们比如可以配置80%,表示预留给服务器或者其他应用20%的cpu
yarn.nodemanager.resource.pcores-vcores-multiplier:默认为1,表示一个物理cpu当做一个vcore使用,如果我们已经预留给了服务器cpu的话,那我们这里可以调整问题2或者3,这样一个物理cpu可以当做2个或者3个vcore使用,毕竟每个map和reduce作业都要配置cpu,但是有些map和reduce作业又不是计算型作业,所以这样就可以更合理的利用资源。类似把蛋糕切小块,少需的拿一块,多需求的多拿几块,这样提高了cpu的利用率和提高了集群的并发能力。(这么配置的前提是集群的瓶颈在于cpu不够使用)
yarn.nodemanager.vmem-pmem-ratio,默认值为2.1。该值为可使用的虚拟内存除以物理内存,即YARN 中任务的单位物理内存相对应可使用的虚拟内存。例如,任务每分配1MB的物理内存,虚拟内存最大可使用2.1MB,如果集群缺内存,可以增大该值。
注意:如果集群的资源很充足,就不要把一个物理cpu当2个或者3个使用,也不要吧虚拟内存比例调大,资源够用就是不用优化,优化只是在资源不够的情况进行的。
如上我们配置yarn集群的资源,cpu和内存,但是在作业的执行的过中是以container为单位的,现在我们来配置container的资源。
yarn.scheduler.minimum-allocation-mb:默认值1024MB,是每个容器请求被分配的最小内存。如果容器请求的内存资源小于该值,会以1024MB 进行分配;如果NodeManager可被分配的内存小于该值,则该NodeManager将会被ResouceManager给关闭。
yarn.scheduler.maximum-allocation-mb:默认值8096MB,是每个容器请求被分配的最大内存。如果容器请求的资源超过该值,程序会抛出InvalidResourceRequest Exception的异常。
yarn.scheduler.minimum-allocation-vcores:默认值1,是每个容器请求被分配的最少虚拟CPU 个数,低于此值的请求将被设置为此属性的值。此外,配置为虚拟内核少于此值的NodeManager将被ResouceManager关闭。
yarn.scheduler.maximum-allocation-vcores:默认值4,是每个容器请求被分配的最少虚拟CPU个数,高于此值的请求将抛出InvalidResourceRequestException的异常。如果开发者所提交的作业需要处理的数据量较大,需要关注上面配置项的配置
2.2、线程配置
资源配置固然重要,但是影响yarn性能的不单单只是资源,还有各个组件之间的配合,线程的数量直接影响到并发的能力,当然也不能配置的太高,这样会给集群造成不小的压力,所以要根据自己集群的状态进行合理的配置。
yarn.resourcemanager.client.thread-count:默认50,用于处理应用程序管理器请求的线程数
yarn.resourcemanager.amlauncher.thread-count:默认50,用于启动/清理AM的线程数
yarn.resourcemanager.scheduler.client.thread-count:默认50,处理来自ApplicationMaster的RPC请求的Handler数目,比较重要
yarn.resourcemanager.resource-tracker.client.thread-count:默认50,处理来自NodeManager的RPC请求的Handler数目,比较重要
yarn.resourcemanager.admin.client.thread-count:默认1,用于处理RM管理接口的线程数。
yarn.nodemanager.container-manager.thread-count:默认20,container 管理器使用的线程数。
yarn.nodemanager.collector-service.thread-count:默认5,收集器服务使用的线程数
yarn.nodemanager.delete.thread-count:默认4,清理使用的线程数。
yarn.nodemanager.localizer.client.thread-count:默认5,处理本地化请求的线程数。
yarn.nodemanager.localizer.fetch.thread-count:默认4,用于本地化获取的线程数
yarn.nodemanager.log.deletion-threads-count:默认4,在NM日志清理中使用的线程数。在禁用日志聚合时使用
yarn.timeline-service.handler-thread-count:用于服务客户端RPC请求的处理程序线程计数。
2.3、log日志和文件目录配置
yarn.nodemanager.log-dirs:日志存放地址(建议配置多个目录),默认值:${yarn.log.dir}/userlogs
yarn.nodemanager.local-dirs:中间结果存放位置,建议配置多个目录,分摊磁盘IO负载,默认值:${hadoop.tmp.dir}/nm-local-dir
yarn.log-aggregation-enable:默认false,是否启用日志聚合
yarn.log-aggregation.retain-seconds:聚合日志的保留时长,设置到3-7天即可,默认-1
yarn.nodemanager.remote-app-log-dir:默认/tmp/logs,本地聚合在hdfs上的日志目录
yarn.nodemanager.remote-app-log-dir-suffix:{yarn.nodemanager.remote-app-log-dir}/${user}/{thisParam}用于存放聚合后的日志
yarn.nodemanager.recovery.dir:默认${hadoop.tmp.dir}/yarn-nm-recovery,本地文件系统目录,当启用恢复时,nodemanager将在其中存储状态。只有当yarn.nodemanager.recovery.enabled为true的情况下才有用,该值默认false
yarn.resourcemanager.recovery.enabled:默认fasle,当RM启用高可用的时候默认启用,但是必须配置yarn.resourcemanager.store.class,该值默认为org.apache.hadoop.yarn.server.resourcemanager.recovery.FileSystemRMStateStore,最好配置配org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore