Hive大SQL任务异常如何定位
现象描述
MRS 3.5.0-LTS及之后版本,Hive执行的大SQL导致HiveServer或MetaStore内存快速增长,频繁Full GC使得业务无法正常运行,甚至导致实例异常重启。
原因分析
- 查询大字段表导致HiveServer内存异常。
- 执行的SQL涉及的文件数过多,导致HiveServer内存异常。
- 执行的SQL涉及的分区数过多,导致HiveServer或MetaStore内存异常。
处理步骤
- 查询大字段表导致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。
- 任务正常执行打印日志如图4所示,过滤异常时间段打印目录日志“Total number of paths”,但无扫描文件结束日志“Total input files to process”的线程,以及打印文件数“Total input files to process”超过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。
- 在MetaStore审计日志“/var/log/Bigdata/audit/hive/metastore”目录下的MetaStore异常的前一段时间内的日志文件中,使用关键字“get_partitions_by_expr”、“get_partitions”、“get_partitions_with_auth”和“get_partitions_by_filter”过滤异常时间段查询的表,排查相关SQL并联系运维人员进行处理。