flink写入orc文件到hive表,hive表读取报数组越界

组件版本:

flink1.13.2

cdh6.3.2

hive2.1.1

问题描述:

flink实时读取日志数据写入hdfs中,保存为orc格式文件。

flink写入文件格式:

hive表建表语句:

hive表查询时报:

org.apache.hive.service.cli.HiveSQLException: 
java.io.IOException: java.lang.ArrayIndexOutOfBoundsException: 7

查看yarn日志:

Caused by: java.lang.ArrayIndexOutOfBoundsException: 7
	at org.apache.orc.OrcFile$WriterVersion.from(OrcFile.java:145)
	at org.apache.orc.impl.OrcTail.getWriterVersion(OrcTail.java:74)
	at org.apache.orc.impl.ReaderImpl.<init>(ReaderImpl.java:385)
	at org.apache.hadoop.hive.ql.io.orc.ReaderImpl.<init>(ReaderImpl.java:62)
	at org.apache.hadoop.hive.ql.io.orc.OrcFile.createReader(OrcFile.java:89)
	at org.apache.hadoop.hive.ql.io.orc.VectorizedOrcInputFormat.getRecordReader(VectorizedOrcInputFormat.java:186)
	at org.apache.hadoop.hive.ql.io.orc.OrcInputFormat.createVectorizedReader(OrcInputFormat.java:1672)
	at org.apache.hadoop.hive.ql.io.orc.OrcInputFormat.getRecordReader(OrcInputFormat.java:1683)
	at org.apache.hadoop.hive.ql.io.CombineHiveRecordReader.<init>(CombineHiveRecordReader.java:68)
	... 16 more

网上查找原因告知:需要调整源码 

[HIVE-14483] java.lang.ArrayIndexOutOfBoundsException org.apache.orc.impl.TreeReaderFactory$BytesColumnVectorUtil.commonReadByteArrays - ASF JIRA

源码切换到2.1.1的分支 : git checkout rel/release-2.1.1

org.apache.orc.OrcFile$WriterVersion.from 

    public static WriterVersion from(int val) {
      if (val >= values.length) return FUTURE; // Special handling for the magic value.
      return values[val];
    }

 并重新打包hive-exec.jar hive-orc.jar包替换集群包。

注意:

cdh没有给出hive的源码,针对cdh中的hive包直接重新打包apache hive源码替换会出现无法连接hive的问题,hiveserver2也会在启动后几分钟内告警。

解决方法:

编译apache hive源码,并下载cdh中hive-exec.jar hive-orc.jar 比对

cdh实际包路径:/opt/cloudera/parcels/CDH/jars   

/opt/cloudera/parcels/CDH/lib/hive/lib 目录中都是软连接关联到/opt/cloudera/parcels/CDH/jars 

org.apache.orc.OrcFile$WriterVersion.class发现两者并无差异。故只替换该类即可。

 替换包命令:

jar uvf hive-exec-2.1.1-cdh6.3.2.jar org/apache/orc/OrcFile\$WriterVersion.class org/apache/orc/OrcFile\$WriterVersion.class

jar uvf hive-orc-2.1.1-cdh6.3.2.jar org/apache/orc/OrcFile\$WriterVersion.class org/apache/orc/OrcFile\$WriterVersion.class

重新上传到 /opt/cloudera/parcels/CDH/jars  中,重启hive验证即可。

注意:替换的包在cdh的每个节点都要上传。

自取包

已经打包好的替换包:cdh-hive2.1.1版本orc格式表读取包数组越界替换包-Hive文档类资源-CSDN下载

要使用Flink将批量数据写入Hive,需要使用FlinkHive Sink。以下是一些步骤: 1. 确保你的Flink集群和Hive集群在同一个Hadoop集群,并且FlinkHive都能够访问同一个Hadoop文件系统。 2. 在Flink应用程序添加Hive Sink依赖项。例如,如果你正在使用Maven构建项目,可以在pom.xml添加以下依赖项: ``` <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-connector-hive_${scala.binary.version}</artifactId> <version>${flink.version}</version> </dependency> ``` 3. 创建Hive并将其注册到Flink。可以使用FlinkHiveCatalog或HiveMetastoreCatalog。例如,以下是使用HiveMetastoreCatalog注册的示例代码: ``` String catalogName = "myhive"; // Hive catalog name String databaseName = "mydb"; // Hive database name String tableName = "mytable"; // Hive table name // Create Hive table String createTableDDL = "CREATE TABLE IF NOT EXISTS " + tableName + " (id INT, name STRING) " + " PARTITIONED BY (dt STRING) " + " STORED AS ORC"; hiveClient.execute(createTableDDL); // Register Hive table as Flink table HiveCatalog hiveCatalog = new HiveCatalog(catalogName, databaseName, hiveConfDir); hiveCatalog.open(); TableSchema tableSchema = new TableSchema(new String[]{"id", "name", "dt"}, new TypeInformation[]{Types.INT, Types.STRING, Types.STRING}); HiveTableDescriptor hiveTableDescriptor = new HiveTableDescriptor(hiveCatalog, tableName, tableSchema); hiveTableDescriptor.setPartitionKeys(new String[]{"dt"}); tableEnv.registerTableSource(tableName, hiveTableDescriptor.getTableSource()); tableEnv.registerTableSink(tableName, hiveTableDescriptor.getTableSink()); ``` 4. 将数据写入Hive。可以使用Flink的DataSet或DataStream API读取批量数据,并使用FlinkHive Sink将数据写入Hive。例如,以下是使用DataSet API将数据写入Hive的示例代码: ``` DataSet<Row> data = ...; // Batch data to be written to Hive table String partitionValue = "20220101"; // Partition value data.addSink( new HiveSink( tableName, new Configuration(), new TableSchema(new String[]{"id", "name", "dt"}, new TypeInformation[]{Types.INT, Types.STRING, Types.STRING}), new String[]{"dt"}, new String[]{partitionValue} ) ); ``` 当你运行Flink应用程序时,数据将被写入Hive的指定分区
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ink__Bamboo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值