- 问题处理记录
- 关于问题的思考
- 思考
- 寻找真像
问题不是巡检发现的,是群里有哥们通知说YARN节点LOST了,然后就上去看了下
从WEBUI和Ambari的监控接口看到有多个节点发生了LOST的现象,看样子是普遍现象:
第一反应不是服务器本身的问题,大概率是GC宕了、或者被OOM Killer,或者某些资源相关的配置项设置不合理等,顺着这个思路再去查日志,关键报错:Too many open files,然后看一下ulimit:
行吧,这个问题很明显,就是资源限制的锅,直接改yarn的limit为100000,然后下发:
最后批量重启NM就行了,安全起见,滚动重启:
问题处理完成后,我还是觉得很奇怪,在进行服务器初始化的时候,我就已经修改了全局的limit.conf,为何还是调ulimit进行查看的时候,还是32768的默认值呢?非常奇怪,随即我查了一下Ambari创建的其他用户的ulimit,这里看的是hbase用户:
32000?不对,接着看一下我的全局初始化配置:
确认是没错的,那就很奇怪了,一种说得通的解释就是:我设置的全局配置,对于Ambari创建的用户不生效,而Ambari创建的用户会使用一个默认的资源限制值!
那么接下来需要弄清楚,这个默认值是linux系统规定的,Ambari只是去用,还是Ambari自己定得??
首先,我们再找几个环境上由ambari创建的用户,来看看他们的limit配置值及实际值,这里我们就统一以最大文件打开数做统一指标:
| 用户名 | 全局配置项 | 用户配置项 | 实际值 |
|---|---|---|---|
| hbase | 100000 | 32000 | 32000 |
| elasticsearch | 100000 | 65535 | 65535 |
| mapred | 100000 | 32768 | 32768 |
由此,至少可以得出这几个结论:
- Ambari创建的用户的资源限制值并不一样,应该不是统一进行配置的;
- 全局配置项会被用户配置项的值所覆盖;
关于第二点结论,我们在进行一个验证,那就是删除用户配置项,保留全局配置项:
可以看到全局配置项这个时候就生效了,顺便还测试了其他几种配置方式,这里就把结论贴出来,不多截图了:
- 当只在/etc/security/limit.conf中配置资源限制时,若只配置了* nofile的资源限制,则全部用户以此值为准;
- 对于Centos7操作系统,当在/etc/security/limits.d/20-nproc.conf中对用户配置了资源限制时,新建用户的限制值以此为准,同时这个值会覆盖掉limit.conf文件中的配置;
- 当在/etc/security/limit.conf中配置了针对特定用户的资源限制时,且没有配置/etc/security/limits.d目录下单独用户的配置,则最终以limit.conf文件中的值为准;
- 若配置了limits.d目录下对单个用户的限制,则这个值拥有最高优先级;
是不是看起来不好理解,那么总结一下,我把所有配置的生效级别排个序:
/etc/security/limits.d/username.conf > /etc/security/limits.d/20-nproc.conf中的username配置 > /etc/security/limit.conf 中的username配置 > /etc/security/limits.d/20-nproc.conf中的全局配置 > /etc/security/limits.conf中的全局配置
如果还不懂的话就自己手动去实验一下,看三遍不如操作一遍!
ok,现在我们可以确定这个资源限制的一个生效的优先级了,继续往下深入,先确定到底是Ambari创建用户的时候由Linux来确定这个资源限制还是由Ambari来限制?
答案其实已经显而易见了,一定是Ambari去设置的这个值,因为正常情况下创建Linux操作系统用户的话,不会创建用户的.conf文件,而且就算创建,也会统一使用一个默认值,现在的现象是不同用户的这个限制也不一样;
接下来只需要在找到证据来证明这个事情就可以盖棺定论了!
如果熟悉Ambari并且看过官方文档,这个问题的排查并不难!我们进入到Ambari的服务配置目录下,具体的结构这里就不细说了,以2.7.5的Ambari为例,找到ambari-serversrcmainresourcescommon-servicesHbase .96.0.2.0packagescriptshbase.py脚本,这其中有一个OsFamilyFuncImpl装饰器:
@OsFamilyFuncImpl(os_family=OsFamilyImpl.DEFAULT)
def hbase(name=None):
import params
......
# On some OS this folder could be not exists, so we will create it before pushing there files
Directory(params.limits_conf_dir,
create_parents = True,
owner='root',
group='root'
)
# 这里执行了关键操作,用于创建资源限制配置文件
File(os.path.join(params.limits_conf_dir, 'hbase.conf'),
owner='root',
group='root',
mode=0644,
content=Template("hbase.conf.j2")
)
注意!!这里我们看到了hbase的用户配置文件使用了一个jinja2模板,难道这个模板中有玄机??赶快打开看看!路径在:ambari-serversrcmainresourcescommon-servicesHbase .96.0.2.0packagetemplateshbase.conf.j2
好家伙,套娃呢,这里又是引用的变量,那就继续查这个变量,最终能够在ambari-serversrcmainresourcescommon-servicesHbase .96.0.2.0configurationhbase-env.xml中找到该配置:
真相大白了!hbase-env.xml中写死了资源限制值,所以安装的时候这个值就一同被写入了资源限制文件中了,为了确认,我们再查看一下Yarn用户的值是不是32768:
果然如此!



