关于hive中explode函数可能出现的问题之并发修改异常
今天运行hive的sql时,运行一段时间后报错,
如下
Hive Runtime Error while processing row (tag=0) {“key”:{“reducesinkkey0”:13199833},“value”:{"_col0":"-_CSo1gOd48","_col1":[“People”,“Blogs”]}}
详细查看报错日志,可以得出是并发修改异常,然后思考是什么原因导致的错
并发修改异常通常是对集合进行遍历操作的同时进行一些其他的修改操作时引发的错误,这是因为java底层对集合的数据有一个副本,每次遍历后都会进行一次比对,如果原始数据和副本数据不一样了,就会报并发修改异常。
为什么会这样呢?
因为explode函数炸开后的字段和原始字段进行匹配正常情况下,炸开的字段肯定会比原始字段的行数要增加,此时与底层副本保存的数据个数不一致,报并发修改异常
但是,像下面这样又可以同时存在原始字段和炸开字段
此时,我们要知道hive是有优化机制的,即Fetch抓取模式
Fetch抓取是指,Hive中对某些情况的查询可以不必使用MapReduce计算。
例如:SELECT * FROM emp;在这种情况下,Hive可以简单地读取emp对应的存储目录下的文件,然后输出查询结果到控制台。
在hive-default.xml.template文件中hive.fetch.task.conversion默认是more,老版本hive默认是minimal,该属性修改为more以后,在全局查找、字段查找、limit查找等都不走mapreduce。
由此我们可以知道简单的查询是不跑MapReduce的,hive底层就对其进行过优化,所以同时出现这两个字段不会报错,而一旦进行MapReduce计算,此时再同时查询这两个字段,就会报错。
总结:不管怎样,最好是不要让原始字段和炸开字段同时出现在一个select的域中,这样就可以保证不会出现类似的问题。