前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Hive Format异常分析

Hive Format异常分析

作者头像
topgunviper
发布2022-05-12 14:24:28
6710
发布2022-05-12 14:24:28
举报
文章被收录于专栏:啥都有的专栏啥都有的专栏

最近在执行Hive insert/select语句的过程碰到下面这种类型的异常:

代码语言:javascript
复制
# 异常1:
Caused by: java.lang.ClassCastException: org.apache.hadoop.io.Text cannot be cast to org.apache.hadoop.hive.ql.io.orc.OrcSerde$OrcSerdeRow
    at org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat$OrcRecordWriter.write(OrcOutputFormat.java:81)
    at org.apache.hadoop.hive.ql.exec.FileSinkOperator.process(FileSinkOperator.java:753)
    at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:837)
    at org.apache.hadoop.hive.ql.exec.LimitOperator.process(LimitOperator.java:54)
    at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:837)
    at org.apache.hadoop.hive.ql.exec.SelectOperator.process(SelectOperator.java:88)
    at org.apache.hadoop.hive.ql.exec.mr.ExecReducer.reduce(ExecReducer.java:235)
    ... 7 more
代码语言:javascript
复制
# 异常2:
Failed with exception java.io.IOException:java.lang.ClassCastException: org.apache.hadoop.hive.ql.io.orc.OrcStruct cannot be cast to org.apache.hadoop.io.BinaryComparable

本文已上述的错误为切入点,分析下异常原因以及Hive相关的关于Format的异常。主要内容如下:

代码语言:javascript
复制
1. 异常的原因分析及解决方法
2. FAQ

1. 异常的原因分析及解决方法

1.1 异常1分析
代码语言:javascript
复制
# 异常1:
Caused by: java.lang.ClassCastException: org.apache.hadoop.io.Text cannot be cast to org.apache.hadoop.hive.ql.io.orc.OrcSerde$OrcSerdeRow
    at org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat$OrcRecordWriter.write(OrcOutputFormat.java:81)
    at org.apache.hadoop.hive.ql.exec.FileSinkOperator.process(FileSinkOperator.java:753)
    at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:837)
    at org.apache.hadoop.hive.ql.exec.LimitOperator.process(LimitOperator.java:54)
    at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:837)
    at org.apache.hadoop.hive.ql.exec.SelectOperator.process(SelectOperator.java:88)
    at org.apache.hadoop.hive.ql.exec.mr.ExecReducer.reduce(ExecReducer.java:235)
    ... 7 more

该异常发生在insert overwrite阶段,即select出来的数据插入目标表时抛出异常。从异常栈中可以清楚地看到OrcOutputFormat、java.lang.ClassCastException这些信息,可见这是Reduce任务将最终结果进行持久化(写入HDFS文件系统)时出现错误。首先,我们需要明确这个数据持久化的大体流程是什么样的?如下图所示:

read-process

Read过程:InputFormat将输入流(InputStream)分割成纪录(<key,value>),Deserializer将纪录(<key,value>)解析成列对象。

write-process

Write过程:Serializer将列对象转化为纪录(<key,value>),OutputFormat将纪录(<key,value>)格式化为输出流(OutputStream)。

上图中描绘的分别是数据载入内存和持久化的过程。异常信息中的OrcOutputFormat说明错误出在数据持久化过程中。从图中可知,序列化器Serializer的输出数据,就是OutputFormat的输入数据。接下来就是确定目标表的SerDe/InputFormat/OutputFormat分别是什么。通过下面命令查看。

desc formatted $table

结果如下:

代码语言:javascript
复制
# desc formatted $table
# Storage Information
SerDe Library:          org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe
InputFormat:            org.apache.hadoop.hive.ql.io.orc.OrcInputFormat
OutputFormat:           org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat

由上可知,目标表的SerDe为LazySimpleSerDe,而其Input/OutputFormat是orc的。所以异常1的原因也就得出:

异常1原因:序列化/反序列化器LazySimpleSerDe在执行serialize后的结果类型是Text,而OrcOutputFormat的接收数据类型必须是OrcSerdeRow。这就造成了ClassCastException。

下面是OrcOutputFormat的write方法源码:

代码语言:javascript
复制
public class OrcOutputFormat extends ... {
    
    @Override
    public void write(Writable row) throws IOException {
      // 若类型不匹配,会抛出异常。
      OrcSerdeRow serdeRow = (OrcSerdeRow) row;
      if (writer == null) {
        options.inspector(serdeRow.getInspector());
        writer = OrcFile.createWriter(path, options);
      }
      writer.addRow(serdeRow.getRow());
    }
    。。。
}

原因找到后,解决办法就很简单了,将该table的fileformat修改为orc即可,如下所示:

代码语言:javascript
复制
ALTER TABLE $table SET FILEFORMAT ORC;
1.2 异常2分析
代码语言:javascript
复制
# 异常2:
Failed with exception java.io.IOException:java.lang.ClassCastException: org.apache.hadoop.hive.ql.io.orc.OrcStruct cannot be cast to org.apache.hadoop.io.BinaryComparable

通过异常1的分析后,这个异常的原因也就很容易定位了,数据读取阶段:OrcInputFormat的输出结果是OrcStruct类型,其作为输入数据传给LazySimpleSerDe的deserialize方法,很明显,deserialize中进行类型转换时抛出该异常。下面是LazySimpleSerDe的doDeserialize方法源码:

代码语言:javascript
复制
  @Override
  public Object doDeserialize(Writable field) throws SerDeException {
    if (byteArrayRef == null) {
      byteArrayRef = new ByteArrayRef();
    }
    // OrcStruct -> BinaryComparable
    BinaryComparable b = (BinaryComparable) field;
    byteArrayRef.setData(b.getBytes());
    cachedLazyStruct.init(byteArrayRef, 0, b.getLength());
    lastOperationSerialize = false;
    lastOperationDeserialize = true;
    return cachedLazyStruct;
  }

下图是已TEXTFILE格式作为存储格式时的读取流程:

textfile-read-process

现在将TextInputFormat换成OrcInputFormat后:

orc-text-incompatible

小结:以上两种异常的根本原因都是由于序列化/反序列化器SerDe和InputFormat/OutputFormat不匹配造成的。这通常是由于创建表时没有正确指定这三个配置项造成的。

FAQ

1. stored as orc 和 stored as INPUTFORMAT ... OUTPUTFORMAT ...的区别?

当我们使用stored as orc的时候,其实已经隐式的指定了下面三个配置:

  1. SERDE:org.apache.hadoop.hive.ql.io.orc.OrcSerde
  2. INPUTFORMAT:org.apache.hadoop.hive.ql.io.orc.OrcInputFormat
  3. OUTPUTFORMAT:org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat

当我们显示的指定STORED AS INPUTFORMAT/OUTPUTFORMAT:

代码语言:javascript
复制
STORED AS INPUTFORMAT
  ‘org.apache.hadoop.hive.ql.io.orc.OrcInputFormat’
OUTPUTFORMAT
  ‘org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat’

此时SERDE并没有指定,会使用默认的serde,在hive cli中可以通过下面cmd查看:

代码语言:javascript
复制
set hive.default.serde;
hive.default.serde=org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe

当然了,如果hive-site.xml中已经配置了hive.default.fileformat,那么不知道stored as的情况下,会使用hive.default.fileformat指定的文件格式。

代码语言:javascript
复制
<property>
        <name>hive.default.fileformat</name>
        <value>ORC</value>
</property>

参考

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-05-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 异常的原因分析及解决方法
    • 1.1 异常1分析
      • 1.2 异常2分析
      • FAQ
        • 1. stored as orc 和 stored as INPUTFORMAT ... OUTPUTFORMAT ...的区别?
        • 参考
        相关产品与服务
        文件存储
        文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档