hiveserver2 定时挂采坑记

2019-06-26  本文已影响0人  六层楼那么高

0 问题描述

集群的 3 台 hiveserver 非常有规律 (每隔 4-5 天)相继下线,无法提供服务,日志里面大量报错,报错里面的一个关键信息如下:

logs/hiveserver2.log.2019-04-09:2019-04-09 17:53:42,526 ERROR [HiveServer2-Handler-Pool: Thread-741270]: util.Shell (Shell.java:runCommand(913)) - Caught java.lang.OutOfMemoryError: unable to create new native thread. One possible reason is that ulimit setting of 'max user processes' is too low. If so, do 'ulimit -u <largerNum>' and try again.

集群信息:HDP hive(1.2.1)

1 问题定位与解决思路如下

1.1 从日志报错入手

通过日志从 'max user processes' is too low 入手,三个问题:

  1. user processes 是什么,进程?线程?
    通过 ulimit -a 可以查看到有一项配置为 'max user processes' ,通过了解到,这个 process 是线程维度,而不是我们平时了解的进程维度。

  2. 如何查看 hive 用户当前的 user processes ?:
    ps -U hive -L | wc -l
    说明 : 加上 -L 才能查看线程 (LWP Light Weight Processes)

  3. 查看 hive 的 max user processes 配置:
    注:这里有一个大坑,必须切换到 hive 用户下,查看 ulimit -a,因为 hiveserver hivemetastore 等服务是 hive 用户启动的 ;我们之前通过运维账号 ulimit -a 查看 配置的是 65535 然并卵。


    image.png

hive 用户 启动的服务有 hiveserver 和 hivemetastore , max user processes (单个用户最大线程数) 为 16000(这个配置在 HDP 的配置中)
通过 ps -U hive -L | wc -l 查看 hive 用户线程数在16000 左右就会出现 unable to create native threads
跟观察到的现象一致

1.2 解决办法:

先修改 hive 的 ulimit, 可以直接在 Ambari 修改后,重启 hiveserver 即可

  1. Ambari UI -> HIVE -> Configs -> Advanced -> Advanced hive-env -> hive_user_nofile_limit 65535
  2. Ambari UI -> HIVE -> Configs -> Advanced -> Advanced hive-env -> hive_user_noproc_limit 65535

1.3 进一步定位根源

进一步思考:启动服务几天后 hiveserver 启动的进程会累计增加到 15K+ ,线程为何没有释放 这是一个问题;通过 jstack 命令查看线程栈信息,大部分线程为,线程的状态为:TIMED_WAITING。

Truststore reloader thread" daemon prio=10 tid=0x00007f96d14d3000 nid=0x2323 waiting on condition [0x00007f959773e000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at org.apache.hadoop.security.ssl.ReloadingX509TrustManager.run(ReloadingX509TrustManager.java:194)
at java.lang.Thread.run(Thread.java:745)

统计此类线程个数:
grep -o "ruststore reloader thread" /tmp/hiveserver.jstack.129.20.20190522.17 | wc -l 7417 (总线程数 7580 占比 97%)
经过关键词检索,定位到是 hive 1.2.1 的 bug ,存在内存(线程)泄露的问题,见 HIVE-1421。hive 启动 hadoop 任务之后忘了关闭连接。

ExecDriver needs to call jobclient.close() to trigger the clean-up of the resources after the submitted job is done/failed

1.4 最终结论:

2 实际解决方案:

通过阅读该 bug 的补丁代码后发现代码的改动实际很小(hadoop 连接没有释放),下载源码,加上释放连接的代码 重新打包替换原先 hive-exec.jar ,相继重启 hiveserver 服务搞定,自此 hive 用户的线程数 稳定在 150 左右。

3 总结

  1. 通过日志定位到的问题不一定是根源问题(root cause);
  2. linux 下查看用户的 ulimit 相关参数一定要切换到影响到的该用户下去查看;
  3. 善用工具 linux 相关的 ps lsof ulimit, Java 相关的 jstack(线程信息) jmap (内存占用信息),jstat(gc);
  4. 问题的解决不一定要按部就班,根据实际场景,可以另寻出路,改源码换 jar 包的方式一天搞定,升级版本的方式可能得大半个月的验证时间。
上一篇 下一篇

猜你喜欢

热点阅读