容器资源超限和盈余调度
(1)YARN集群资源管理
YARN集群上所有的资源,可以通过YARN的Web UI直接查看
通过查看集群监控,可以看到总共的内存大小、虚拟CPU核的个数,我们也可以看到每个NodeManager的资源。很明显,YARN集群中总共能使用的内存就是每个NodeManager的资源和,虚拟CPU核也是一样。
(2)NodeManager总计资源
在yarn-default.xml中有一项配置为:yarn.nodemanager.resource.memory-mb,它的默认值为:-1
Hadoop的官方解释:
这个配置是表示NodeManager总共能够使用的物理内存,这也是可以给container使用的物理内存。如果配置为-1,且yarn.nodemanager.resource.detect-hardware- capabilities配置为true,那么则不限制yarn使用CPU的數量。而yarn.node manager.resource.detect-hardware-capabilities默认为false,所以,此处默认Nod eManager就是8G。这就是解释了为什么每个NM的可用内存是8G
yarn.nodemanager.vmem-pmem-ratio,它的默认配置是2.1
这个配置是针对NodeManager上的container,如果说某个Container的物理内存不足时,可以使用虚拟内存,能够使用的虚拟内存默认为物理内存的2.1倍
yarn.nodemanager.resource.cpu-vcores配置,它的默认配置也为-1
这个配置与内存类似,它也有一个默认值:就是8,这就解释了为什么每个NodeManager的总计资源是8G和8个虚拟CPU核了
(3)scheduler调度资源
通过YARN的Web UI,点击scheduler,我们可以看到的调度策略、最小和最大资源分配
通过Web UI,我们可以看到当前YARN的调度策略为容量调度(Capacity Scheduler)。调度资源的单位是基于MB的内存、和Vcore(虚拟CPU核)。最小的一次资源分配是:1024M(1G)和1个VCORE。最大的一次分配是:4096M(4G)和4个VCORE。注意:内存资源和VCORE都是以Container承载的
yarn.scheduler.minimum-allocation-mb, 它的默认配置是1024
说明:该配置表示每个容器的最小分配。因为RM是使用scheduler来进行资源调度的,如果请求的资源小于1G,也会设置为1G。这表示,如果我们请求一个256M的container,也会分配1G
yarn.scheduler.maximum-allocation-mb, 它的默认配置是8192
说明:容器最大分配的内存,如果比这个内存高,就会抛出InvalidResourceReques tException异常。这里也就意味着,最大请求的内存不要超过8G。上述截图显示是4G,是因为在yarn-site.xml中配置了最大分配4G,最大分配内存可以进行配置改变。
yarn.scheduler.minimum-allocation-vcores, 它的默认配置是1
说明:同容器内存的最小分配
yarn.scheduler.maximum-allocation-vcores, 它的默认配置是4
说明:同容器内存的最大分配
(4)Container总计资源
在YARN中,资源都是通过Container来进行调度的,程序也是运行在Container中。Container能够使用的最大资源,是由scheduler决定的。如果按照Hadoop默认配置,一个container最多能够申请8G的内存、4个虚拟核。例如:我们请求一个Container,内存为3G、VCORE为2,是OK的。考虑一个问题:如果当前NM机器上剩余可用内存不到3G,怎么办?此时,就会使用虚拟内存。不过,虚拟内存,最多为内存的2.1倍,如果物理内存+虚拟内存仍然不足3G,将会给container分配资源失败,容器因虚拟内存不足而被杀死。
根据上述分析,如果我们申请的container内存为1G、1个VCORE。那么NodeManager最多可以运行8个Container。如果我们申请的container内存为4G、4个vcore,那么NodeManager最多可以运行2个Container。
(5)Container是一个JVM进程吗
当向RM请求资源后,RM会在NodeManager上创建Container。问题是:Container是不是有自己独立运行的JVM进程呢?还是说,NodeManager上可以运行多个Container?Container和JVM的关系是什么?
实际上,每一个Container就是一个独立的JVM实例。(此处不讨论Uber模式)。每一个任务都是在Container中独立运行,例如:MapTask、ReduceTask。当scheduler调度时,它会根据任务运行需要来申请Container,而每个任务其实就是一个独立的JVM。
(6)容量调度器
Hadoop使用的默认调度器是Capacity Scheduler。
Capacity Scheduler,以队列为单位划分资源,每个队列可设定一定比例的资源最低保证和使用上限,同时,每个用户也可设定一定的资源使用上限以防止资源滥用。而当一个队列的资源有剩余时,可暂时将剩余资源共享给其他队列。
Capacity Scheduler 主要有以下几个特点:
容量保证。管理员可为每个队列设置资源最低保证和资源使用上限,而所有提交到该队列的应用程序共享这些资源。
灵活性。如果一个队列中的资源有剩余,可以暂时共享给那些需要资源的队列,而一旦该队列有新的应用程序提交,则其他队列释放的资源会归还给该队列。这种资源灵活分配的方式可明显提高资源利用率。
多重租赁。支持多用户共享集群和多应用程序同时运行。为防止单个应用程序、用户或者队列独占集群中的资源,管理员可为之增加多重约束(比如单个应用程序同时运行的任务数等)。
安全保证。每个队列有严格的ACL列表规定它的访问用户,每个用户可指定哪些用户允许查看自己应用程序的运行状态或者控制应用程序(比如杀死应用程序)。
此外,管理员可指定队列管理员和集群系统管理员,动态更新配置文件。管理员可根据需要动态修改各种配置参数,以实现在线集群管理。
(7)均衡器(hadoop balancer)
问题:hadoop出现报警,有些节点数据磁盘已经占用了90%,有些节点磁盘用了50%
解决:HDFS自带的balancer工具来解决,保证每个节点的数据分布均衡
Hadoop的HDFS集群非常容易出现机器与机器之间磁盘利用率不平衡的情况,比如集群中添加新的数据节点。当HDFS出现不平衡状况的时候,将引发很多问题,比如MR程序无法很好地利用本地计算的优势,机器之间无法达到更好的网络带宽使用率,机器磁盘无法利用等等。可见,保证HDFS中的数据平衡是非常重要的。在Hadoop中,包含一个Balancer程序,通过运行这个程序,可以使得HDFS集群达到一个平衡的状态,它会通过将文件块从高负载的DataNode转移到低使用率的DataNode上。
具体步骤为:
1.从namenode获取datanode磁盘使用情况
2.计算哪些节点需要把哪些数据移动到哪里(是可以跨机架均衡的)
3.分别移动,完成后删除旧的block信息
4.循环执行,直到达到平衡标准
启动balancer的方法
start-balancer.sh -threshold 1
hadoop balancer -threshold 1
hadoop-daemon.sh start balancer -threshold 1