Hive大SQL任务异常如何定位
现象描述
MRS 3.5.0-LTS及之后版本,Hive执行的大SQL导致HiveServer或MetaStore内存快速增长,频繁Full GC使得业务无法正常运行,甚至导致实例异常重启。
原因分析
- 查询大字段表导致HiveServer内存异常。
- 执行的SQL涉及的文件数过多,导致HiveServer内存异常。
- 执行的SQL涉及的分区数过多,导致HiveServer或MetaStore内存异常。
- MRS 3.6.0-LTS及之后版本,配置的堆内存不合理,导致HiveServer内存异常。
- MRS 3.6.0-LTS及之后版本,大量连接使用完未关闭,导致HiveServer内存异常。
处理步骤
- 查询大字段表导致HiveServer内存异常场景
HiveServer查询结果分批次返回客户端,默认一批次返回1000条数据,大字段将大量占用实例内存,严重时将导致HiveServer OOM自动重启,当前实例正在运行的任务全部失败。
大字段表查询异常时,客户端异常如图1所示,调用FetchResults时无法处理大字段,HiveServer异常重启,连接中断。
参考如下操作进行处理:
- 登录Manager页面,选择“运维 > 事件”,在事件列表中查看Hive对象“进程重新启动”事件的详细信息,在“定位信息”中记录上报该事件的HiveServer主机名;并记录该事件的“产生时间”,即为HiveServer重启时间。
- 登录1查看到的重启的HiveServer节点,执行以下命令查看重启时是否生成JVM错误日志“hs_err_pid_*log”:
ll /var/log/Bigdata/hive/hiveserver/hs_err_pid_*log
- 使用关键字“HiveSessionImpl.fetchResults”在“hs_err_pid_*log”日志中查找正在获取返回结果的线程名称,执行5。
图2 查找线程名称
- 在HiveServer运行日志“/var/log/Bigdata/hive/hiveserver”目录下的HiveServer重启前一段时间内的运行日志文件中,查找OOM重启日志“Stopping HiveServer2 due to OOM”,并记录线程名称,执行5。
- 在HiveServer审计日志“/var/log/Bigdata/audit/hive/hiveserver/hive-audit.log”中使用编译线程名称查找HiveServer重启时间之前执行的查询SQL,并联系相关业务排查相关表是否包含大字段,停止对应的任务或修改相关表。
图3 查找SQL语句
- SQL涉及的文件数过多,导致HiveServer内存异常
HiveServer使用MapReduce引擎执行SQL时,提交任务前在HiveServer内存中读取文件进行切片,每个文件约占用2k内存,文件数过多将导致HiveServer内存异常。
- 登录Manager页面,选择“集群 > 服务 > Hive > 配置 > 全部配置”,查看是否配置如下参数:
hive-ext.combine.input.file.limit.enable:用于设置是否开启读取文件数限制,默认值为“false”。开启该功能后,提交Hive任务前会统计读取的文件数并判断是否拦截该SQL,将增大对应任务执行的时间。
hive-ext.combine.input.file.limit.threshold:若开启读取文件数限制参数,文件数超过该参数值的SQL将失败,默认值为1000000。
- 在HiveServer运行日志“/var/log/Bigdata/hive/hiveserver”目录下的HiveServer重启前一段时间内的运行日志文件中,使用关键字“The number of files exceeds”过滤超过限制值50%的线程名称,排查对应的SQL并联系业务人员进行处理。
- 联系业务人员确认是否需要开启相关参数限制大任务运行,文件数达到配置的限制值50%将打印提示日志“The number of files exceeds ***”,文件数达到限制值的SQL将失败。
- 是,在HiveServer自定义配置中添加以上两个参数,并重启HiveServer实例。
- 否,执行4。
- MRS 3.6.0-LTS之前版本,任务正常执行打印日志如图4所示,过滤异常时间段打印目录日志“Total number of paths”,但无扫描文件结束日志“Total input files to process”的线程,以及打印文件数“Total input files to process”超过10万的线程,并联系运维人员排查对应的SQL进行处理。
MRS 3.6.0-LTS及之后版本,任务正常执行会打印扫描的文件数,MapReduce引擎搜索关键字“Number of all splits”,Tez和Spark引擎搜索关键字“Total input files”,找到关键字日志内容中“files”的值超过10万对应的线程,并联系运维人员排查对应的SQL进行处理。
- 登录Manager页面,选择“集群 > 服务 > Hive > 配置 > 全部配置”,查看是否配置如下参数:
- SQL涉及的分区数过多,导致HiveServer或MetaStore内存异常
分区表查询或msck、analyze、alter删除大量分区等SQL执行不带分区过滤条件时,HiveServer将会查询所有分区名,再根据分区名分批查询分区对象,将占用大量HiveServer内存;带分区过滤条件时,HiveServer将条件下推到MetaStore,若满足条件的分区过多,MetaStore内存也会被大量占用。
- 确认异常的节点是HiveServer还是MetaStore。
- 在HiveServer运行日志“/var/log/Bigdata/hive/hiveserver”目录下的HiveServer异常的前一段时间内的运行日志文件中,使用关键字“The number of part size”过滤异常时间段扫描分区数大于10000的表,根据线程名排查相关SQL,联系运维人员进行处理。
- 登录Manager页面,选择“集群 > 服务 > Hive > 配置 > 全部配置”,查看是否配置以下参数:
metastore.limit.partition.request:默认值为-1,配置该参数值大于0时,MetaStore会使用过滤条件提前count查询的分区数量,结果值超过此参数的分区过滤查询将失败。
- 在MetaStore运行日志“/var/log/Bigdata/hive/metastore”目录下的MetaStore异常的前一段时间内的运行日志文件中,使用关键字“The number of part size”过滤异常时间段扫描分区数大于10000的表,根据表名排查相关SQL,联系运维人员进行处理。
- 联系业务确认是否需要开启相关参数,限制大任务运行,配置后分区过滤将增加count操作,将增加查询耗时。
- 是,在MetaStore自定义配置中添加相关参数并重启MetaStore实例。
- 否,执行6。
- MRS 3.6.0-LTS之前版本,在MetaStore审计日志“/var/log/Bigdata/audit/hive/metastore”目录下的MetaStore异常的前一段时间内的日志文件中,使用关键字“get_partitions_by_expr”、“get_partitions”、“get_partitions_with_auth”和“get_partitions_by_filter”过滤异常时间段查询的表,排查相关SQL并联系运维人员进行处理。
MRS 3.6.0-LTS及之后版本,在MetaStore运行日志“/var/log/Bigdata/hive/metastore”目录下的MetaStore异常的前一段时间内的日志文件中,使用关键字“The number of scanned partitions in”过滤异常时间段查询的表,排查相关SQL并联系运维人员进行处理。
- MRS 3.6.0-LTS及之后版本,配置的堆内存不合理,导致HiveServer内存异常场景
由于业务需要运行过多的SQL任务使得HiveServer或Metastore实例内存使用率很大,但系统内存仍使用的默认值,或者配置过小不能满足实际的需要,从而会导致进程频繁GC。方法如下:
- 在Manager首页,选择“运维 告警 告警”,“Hive服务进程堆内存使用超出阈值”告警展开详情页面,在定位信息中确认内存使用异常的节点是HiveServer还是MetaStore。
- 在Manager首页,选择“集群 > 服务 > Hive > 实例”,单击告警上报的HiveServer,进入实例“概览”页面,单击图表区域右上角的下拉菜单,选择“定制 > CPU和内存”,勾选“HiveServer内存使用率统计”,单击“确定”,查看HiveServer进程使用的堆内存是否长期达到或接近HiveServer进程设定的最大堆内存的阈值(默认95%)。
- 是,执行4。
- 否,操作结束。
- 在Manager首页,选择“集群 > 服务 > Hive > 实例”,单击告警上报的MetaStore,进入实例“概览”页面,单击图表区域右上角的下拉菜单,选择“定制 > CPU和内存”,勾选“MetaStore内存使用率统计”,单击“确定”,查看MetaStore进程使用的堆内存是否长期达到或接近MetaStore进程设定的最大堆内存的阈值(默认95%)。
- 是,执行4。
- 否,操作结束。
- 在Manager首页,选择“集群 > 服务 > Hive > 配置”,选择“全部配置”,在左侧导航栏选择“HiveServer(角色)/MetaStore(角色) > JVM”,将“HIVE_GC_OPTS/METASTORE_GC_OPTS”参数中“-Xmx”的值根据如下建议进行调整,单击“保存”保存配置,并重启Hive使配置生效。
- MRS 3.6.0-LTS及之后版本,大量连接使用完未关闭导致HiveServer内存异常场景
创建Hive连接时,JDBC驱动对象、结果集对象ResultSet、语句对象Statement、内部缓冲区等都会存储在堆内存中,如果大量的连接未正常关闭,会持续占用堆内存空间,导致老年代对象堆积并触发回收需求,触发Full GC报错。
- 确认异常的节点是HiveServer还是MetaStore。
- 登录Manager页面,选择“集群 > 服务 > Hive > 图表”,在“图表分类”中选择“Session”,在图表区域查看“HiveServer的session数统计”图表,确认HiveServer的session数是否出现持续增高的现象。
- 是,执行4。
- 否,操作结束。
- 登录Manager页面,选择“集群 > 服务 > Hive > 实例 > MetaStore > 图表”,在“图表分类”中选择“连接数”,在图表区域查看“MetaStore连接数统计”图表,确认MetaStore的session数是否出现持续增高的现象。
- 是,执行5。
- 否,操作结束。
- 登录异常的HiveServer节点,执行以下命令:
grep 'OpenSession' /var/log/Bigdata/audit/hive/hiveserver/hive-audit.log | awk '{print $9}' | sort | uniq -c | sort
grep 'CloseSession' /var/log/Bigdata/audit/hive/hiveserver/hive-audit.log | awk '{print $9}' | sort | uniq -c | sort
分析以上命令执行后的统计结果,根据审计日志中打开session和关闭session的日志记录信息排查session是否正常关闭,如果关闭session的日志信息少于打开session的日志,且相差的数量远大于正在运行的任务数量,则说明存在大量连接数未关闭的情况,需要业务侧检查是否有未正常关闭的连接、连接池配置的是否合理,如果存在需及时处理。
- 联系业务侧开发人员排查连接MetaStore的代码,检查是否有未正常关闭的连接、连接池配置的是否合理,如果存在需及时处理。

