R-Hive流处理报错求助:机器学习模型大数据集评分异常
你遇到的问题很典型——本地测试正常的R脚本放到Hive集群处理大数据时就报错,结合你给出的错误日志,我整理了几个针对性的排查方向:
首先把错误信息贴出来方便参考:
Error: java.lang.RuntimeException: org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error while processing row (tag=0) {"key":{},"value":{"_col0":986436000,"_col1":"0","_col2":"0"} at org.apache.hadoop.hive.ql.exec.mr.ExecReducer.reduce(ExecReducer.java:256) at org.apache.hadoop.mapred.ReduceTask.runOldReducer(ReduceTask.java:444) at org.apache.hadoop.mapred.ReduceTask.run(ReduceTask.java:392) at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:170) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.Subject.doAs(Subject.java:422) at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1866) at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:164)
Caused by: org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error while processing row (tag=0) {"key":{},"value":{"_col0":986436000,"_col1":"0"} at org.apache.hadoop.hive.ql.exec.mr.ExecReducer.reduce(ExecReducer.java:244) ... 7 more
Caused by: org.apache.hadoop.hive.ql.metadata.HiveException: [Error 20001]: An error occurred while reading or writing to your custom script. It may have crashed with an error.
排查思路:
核对Hive与R脚本的数据交互格式
从错误日志里的行数据能看到,Hive传给R脚本的是类似JSON格式的内容,但这个JSON明显不完整(缺少闭合大括号)。本地测试时你可能用的是CSV或自定义分隔格式,但Hive默认会用序列化后的格式传递数据。要确认R脚本的输入读取逻辑是否适配Hive的输出格式:比如是否正确解析JSON结构,有没有处理特殊字符(比如引号、换行)导致的格式断裂,或者是否需要在Hive里指定ROW FORMAT DELIMITED来用简单分隔符传递数据,降低解析难度。检查集群节点的R环境依赖
本地的R环境和Hive集群节点的环境大概率存在差异:比如你本地安装的机器学习包(像caret、xgboost这类),集群节点上可能没装,或者版本不兼容;甚至R本身的版本都可能不一样。建议登录到集群的任意一个节点,手动运行你的R脚本(用Hive表导出的抽样数据做测试),看是否能正常执行,缺失的包要在所有集群节点上统一安装,或者通过Hive的ADD FILE命令把依赖的脚本/包文件挂载到任务环境中。调整Hive任务的资源配置
本地测试数据量小,资源压力小,但处理大型数据集时,Reducer阶段很容易因为内存不足崩溃。这个错误刚好是在ExecReducer.reduce环节抛出的,你可以尝试调整资源参数:- 增大Reducer的内存配额:
set mapreduce.reduce.memory.mb=4096;(根据集群资源调整,比如8G内存的节点可以设到6144) - 增加Reducer的数量:
set mapreduce.job.reduces=15;(避免单个Reducer处理过多数据) - 同时也可以调整Map任务的内存:
set mapreduce.map.memory.mb=2048;
- 增大Reducer的内存配额:
捕获R脚本的详细错误日志
Hive默认只会返回脚本崩溃的笼统错误,看不到R脚本内部的报错信息。你可以在R脚本里添加日志输出逻辑:# 在脚本开头添加日志输出 sink("/tmp/r_model_score_log.txt", append = TRUE, split = TRUE) print(paste("Script started at:", Sys.time()))这样脚本运行时的所有输出(包括报错)都会写到集群节点的
/tmp目录下的日志文件里,你可以登录节点查看具体是哪一行代码出了问题,比如是不是处理某条异常数据时抛出了错误。验证数据集的完整性
错误里的行数据JSON不完整,可能是Hive在序列化时遇到了异常数据(比如字段里包含换行符、未转义的引号),导致数据截断。你可以先抽样查询Hive表,检查是否有格式异常的行:SELECT * FROM your_table LIMIT 100;重点看
_col0、_col1这些字段是否有特殊字符,如果有的话,需要先对数据做清洗,比如用regexp_replace去掉特殊字符,再传给R脚本处理。
内容的提问来源于stack exchange,提问作者Sachin Sharma

