一次Hadoop集群的资源死锁问题排查

2021-01-06 10:48:22 浏览数 (1)

1.概述

最近集群资源使用出现了一些问题,以下是对这次问题的分析整理。

2.资源问题

2.1现象

生产集群出现大量任务积压,运行缓慢的情况,怀疑是集群资源分配出现了问题。

该集群总共有569个Node Manger,总计Vcore数是27704个,总计内存是171T,资源比较丰富,属于重点生产集群,理论上足够任务运行。

经过排查分析,发现如下现象。

集群总体资源使用高,有很少量的剩余资源。

如下图所示,集群资源使用非常高了,但是仍有少量剩余,其中CPU使用了95%,但仍有剩余。

YARN页面YARN页面

队列最小资源没有得到满足

从上图可以看出,目前配置的队列最小资源都设置的比较大,及时集群资源使用非常高,仍然没有满足最小资源的需求。队列最小资源,是集群有资源的情况下,必须要满足的资源。并且集群中,绝大部分队列都没有达到最小资源。

出现大量Map Pening

如下图所示,集群中出现大量的任务都有如下的现象。Reduce已经启动,在等待Map阶段完成,然后向前执行,但是Map阶段还有部分任务没有完成,这部分任务也拿不到资源执行,running的map为0。从而出现了死锁的情况。即Reduce启动了占用了资源,但是在等待Map,而Map拿不到资源无法执行。

job页面job页面

2.2分析

根据上面的现象,可以分析得出,导致任务出现积压的情况,直接原因是因为,出现了资源分配的死锁。即Reduce阶段占用了资源,但是需要等待Map阶段执行完成,而Map阶段在等待资源,但是资源已经被Reduce都占用了,无法申请到资源,因此无法执行。大量的任务都出现了这种情况,集群中绝大部分的资源都被Reduce的Container占用了,而Map阶段分到的资源很少。

Mapreduce任务在执行任务时,分为Map,Reduce两个阶段,这两个阶段都需要申请yarn 的container容器,进行运行。并且Yarn并不区分Map,Reduce的容器类型,只要是申请资源,会一视同仁。Reduce阶段,需要获取Map阶段的输出,从而继续往下执行。Yarn通过参数mapreduce.job.reduce.slowstart.completedmaps,设定比例,例如设置为0.8(目前集群设置为0.8),则Map阶段完成80%后,Reduce阶段就会开始申请容器,占用资源。提前启动Reduce的好处是,可以尽早的申请到资源,然后Reduce首先从已经完成的Map任务中拷贝数据,Map同时执行。从而,加快整体任务的执行。

然而,这个设定,在极端情况下,会出现问题:

1. 集群中存在大量任务同时运行

2. 其中不少的任务都需要启动大量的Map任务和reduce任务

3. 集群总体的资源使用率已经非常高,没有很多的剩余资源

在上述的情况下,就有可能出现资源死锁的情况。由于大量的任务同时运行,并且其中不少的任务都有大量的Map任务和Reduce任务, 当Map任务完成到一定比例之和,就开始启动Reduce任务,Reduce任务启动之后,占用了资源,但是Map还没有结束。集群总体的资源使用率已经非常高,没有很多的剩余资源,Map阶段分配不到足够的资源,只能非常缓慢的运行,或者甚至分不到资源,直接不运行了。整个任务就停滞了,但是也不超时。另外一个加剧该现象的原因是,因为目前集群队列的资源设定中,每个资源池的最小资源占比设置的比较大,总和已经超过了集群资源的总和 。

设定队列的最小资源,是为了保证队列能够至少能够拿到最小资源,不至于被饿死。并且集群有一定的剩余资源,可以供资源池之间竞争,作为补充。但是目前的设定,导致即使集群所有的资源也无法满足每个队列的最小资源。这样的情况,就导致了,集群的所有资源基本会被使用完,并且关键的是,所有的队列都认为是自己的最小资源。及时某个队列出现了资源饥饿 的情况,也无法从集群或者其他队列抢占部分资源来补充。

2.3解决方案

设置mapreduce.job.reduce.slowstart.completedmaps为1

设置为1之后,Reduce需要等待Map阶段都完成之后,才会申请资源并启动,这样的话,就不会出现Reduce占用资源而Map分配不到的情况了。

如下图所示,通过CM,设置mapreduce.job.reduce.slowstart.completedmaps为1。同时,原来设定默认reduce个数为600, 这个值偏大,修改为40。

cm配置页面cm配置页面

重新调整资源池的设定

重新调整各资源池,最小资源,最大资源,以及并发任务数。

建议调整所有资源池的最小资源为集群资源的60%。最大资源为集群资源的100%。

NodeManager内存调整

如下图所示,目前集群NodeManager内存为2G,对于一个比较繁忙,并且规模很大的集群,NodeManager内存建议可以设置的稍微大一点,下图修改成4G。

cm配置cm配置

控制map数量

可以通过设置mapreduce.input.fileinputformat.split.minsize参数来控制任务的Map数,该参数控制每个map的最小处理数据量。在hive 中可以通过set mapreduce.input.fileinputformat.split.minsize=67108864来设定。

3.总结

本次集群计算资源的问题在基本得到解决,其实归根结底还是业务与业务、业务与集群的脱离,没有良好的调度策略是最根本的原因,调优路其慢慢且修远,吾将上下而求索。

0 人点赞