HQL 抛出 ArrayList 无法转换为 org.apache.hadoop.io.Text
Posted
技术标签:
【中文标题】HQL 抛出 ArrayList 无法转换为 org.apache.hadoop.io.Text【英文标题】:HQL throws ArrayList cannot be cast to org.apache.hadoop.io.Text 【发布时间】:2020-06-22 12:43:48 【问题描述】:我有一个查询在减少时失败,抛出的错误是:
Error: Error while processing statement: FAILED: Execution Error, return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask (state=08S01,code=2)
但是,当深入了解 YARN 日志时,我发现了这一点:
错误:java.lang.RuntimeException: org.apache.hadoop.hive.ql.metadata.HiveException: Hive 运行时错误,同时处理行 (tag=0) "key":"reducesinkkey0":"2020-05 -05","reducesinkkey1":10039,"reducesinkkey2":103,"reducesinkkey3":"2020-05-05","reducesinkkey4":10039,"reducesinkkey5":103,"value":"_col0": 103,"_col1":["1","2"] 在 org.apache.hadoop.hive.ql.exec.mr.ExecReducer.reduce(ExecReducer.java:265) 在 org.apache.hadoop.mapred .ReduceTask.runOldReducer(ReduceTask.java:444) 在 org.apache.hadoop.mapred.ReduceTask.run(ReduceTask.java:392) 在 org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:164)在 java.security.AccessController.doPrivileged(Native Method) 在 javax.security.auth.Subject.doAs(Subject.java:422) 在 org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1920) 在 org .apache.hadoop.mapred.YarnChild.main(YarnChild.java:158) 原因:org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error while processing row (tag=0) "key": "r educesinkkey0":"2020-05-05","reducesinkkey1":10039,"reducesinkkey2":103,"reducesinkkey3":"2020-05-05","reducesinkkey4":10039,"reducesinkkey5":103,"value ":"_col0":103,"_col1":["1","2"] 在 org.apache.hadoop.hive.ql.exec.mr.ExecReducer.reduce(ExecReducer.java:253) 。 .. 7 更多原因:java.lang.ClassCastException: java.util.ArrayList 无法转换为 org.apache.hadoop.io.Text
最相关的部分是:
java.util.ArrayList 无法转换为 org.apache.hadoop.io.Text
这是我正在执行的查询(仅供参考:这是更大查询中的子查询):
SELECT
yyyy_mm_dd,
h_id,
MAX(CASE WHEN rn=1 THEN prov_id ELSE NULL END) OVER (partition by yyyy_mm_dd, h_id) as primary_prov,
collect_set(api) OVER (partition by yyyy_mm_dd, h_id, p_id) prov_id_api, --re-assemple array to include all elements from multiple initial arrays if there are different arrays per prov_id
prov_id
FROM(
SELECT --get "primary prov" (first element in ascending array))
yyyy_mm_dd,
h_id,
prov_id,
api,
ROW_NUMBER() OVER(PARTITION BY yyyy_mm_dd, h_id ORDER BY api) rn
FROM(
SELECT --explode array to get data at row level
t.yyyy_mm_dd,
t.h_id,
prov_id,
collect_set(--array of integers, use set to remove duplicates
CASE
WHEN e.apis_xml_element = 'res' THEN 1
WHEN e.apis_xml_element = 'av' THEN 2
...
...
ELSE e.apis_xml_element
END) as api
FROM
mytable t
LATERAL VIEW EXPLODE(apis_xml) e AS apis_xml_element
WHERE
yyyy_mm_dd = "2020-05-05"
AND t.apis_xml IS NOT NULL
GROUP BY
1,2,3
)s
)s
我已将问题进一步缩小到***选择,因为内部选择本身可以正常工作,这让我相信问题在这里特别发生:
collect_set(api) OVER (partition by yyyy_mm_dd, h_id, prov_id) prov_id_api
但是,我不确定如何解决它。在最内部的选择中,apis_xml
是一个 array<string>
,它将诸如 'res' 和 'av' 之类的字符串保存到一个点为止。然后使用整数。因此使用 case 语句来对齐这些。
奇怪的是,如果我通过 Spark 运行它,即spark.sql=(above_query)
,它可以工作。但是,在通过 HQL 的直线上,作业会被终止。
【问题讨论】:
【参考方案1】:删除内部查询中的collect_set
,因为它已经产生了数组,上面的collect_set
应该接收标量。还要在内部查询中删除 group by
,因为没有 collect_set 就不再有聚合。如果需要删除重复项,可以使用 DISTINCT
【讨论】:
一个快速测试,它看起来像这样工作!谢谢你。在这种情况下,什么是缩放器,这是导致错误的原因吗?这花了我几天的时间来解决,所以我想知道更多的未来 @Someguywhocodes 我的意思是 collect_set 接受简单类型值而不是数组。 @Someguywhocodes Spark 允许 collect_set 的复杂类型参数以上是关于HQL 抛出 ArrayList 无法转换为 org.apache.hadoop.io.Text的主要内容,如果未能解决你的问题,请参考以下文章
将 ArrayList 转换为 Array 抛出 java.lang.ArrayStoreException
使用 hql 将列表中的列转换为数组和数组到 hive 中的列表
转换 Arrays.asList 导致异常:java.util.Arrays$ArrayList 无法转换为 java.util.ArrayList