带有Hive的ORC文件:java.io.IOException:两个读取器

时间:2019-06-03 06:58:28

标签: hive orc hdp

我有一个ACID配置单元表,其中包含ORC格式的文件。尝试压缩时,出现以下错误:Task: ... exited : java.io.IOException: Two readers for ...完整错误如下:

2019-06-03 07:01:05,357 ERROR [IPC Server handler 2 on 41085] org.apache.hadoop.mapred.TaskAttemptListenerImpl: Task: attempt_1558939181485_29861_m_000001_0 - exited : java.io.IOException: Two readers for {originalWriteId: 143, bucket: 536870912(1.0.0), row: 3386, currentWriteId 210}: new [key={originalWriteId: 143, bucket: 536870912(1.0.0), row: 3386, currentWriteId 210}, nextRecord={2, 143, 536870912, 3386, 210, null}, reader=Hive ORC Reader(hdfs://HdfsNameService/tbl/delete_delta_0000209_0000214/bucket_00001, 9223372036854775807)], old [key={originalWriteId: 143, bucket: 536870912(1.0.0), row: 3386, currentWriteId 210}, nextRecord={2, 143, 536870912, 3386, 210, null}, reader=Hive ORC Reader(hdfs://HdfsNameService/tbl/delete_delta_0000209_0000214/bucket_00000, 9223372036854775807)]
    at org.apache.hadoop.hive.ql.io.orc.OrcRawRecordMerger.ensurePutReader(OrcRawRecordMerger.java:1171)
    at org.apache.hadoop.hive.ql.io.orc.OrcRawRecordMerger.<init>(OrcRawRecordMerger.java:1126)
    at org.apache.hadoop.hive.ql.io.orc.OrcInputFormat.getRawReader(OrcInputFormat.java:2402)
    at org.apache.hadoop.hive.ql.txn.compactor.CompactorMR$CompactorMap.map(CompactorMR.java:964)
    at org.apache.hadoop.hive.ql.txn.compactor.CompactorMR$CompactorMap.map(CompactorMR.java:941)
    at org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:54)
    at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:465)
    at org.apache.hadoop.mapred.MapTask.run(MapTask.java:349)
    at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:174)
    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:1730)
    at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:168)

此表的创建和更新是通过merge将avro文件放入orc表中,因此是一堆delete_deltadelta的增量。

我还有许多其他这样的表,它们没有这个问题。该表没有任何异常,实际上很小(<100k行,磁盘上有2.5M),在上个月已更新了100次(更新了2万行,更新了5M数据)。 DDL是:

CREATE TABLE `contact_group`(
  `id` bigint,
  `license_name` string,
  `campaign_id` bigint,
  `name` string,
  `is_system` boolean,
  `is_test` boolean,
  `is_active` boolean,
  `remarks` string,
  `updated_on_utc` timestamp,
  `created_on_utc` timestamp,
  `deleted_on_utc` timestamp,
  `sys_schema_version` int,
  `sys_server_ipv4` bigint,
  `sys_server_name` string,
  `load_ts` timestamp)
ROW FORMAT SERDE
  'org.apache.hadoop.hive.ql.io.orc.OrcSerde'
STORED AS INPUTFORMAT
  'org.apache.hadoop.hive.ql.io.orc.OrcInputFormat'
OUTPUTFORMAT
  'org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat'
LOCATION
  'hdfs://HdfsNameService/dwh/vault/contact_group'
TBLPROPERTIES (
  'bucketing_version'='2',
  'last_modified_by'='hive',
  'last_modified_time'='1553512639',
  'transactional'='true',
  'transactional_properties'='default',
  'transient_lastDdlTime'='1559522011')

这每隔几个月就会发生一次。当其他所有事情(选择,合并)都起作用时,解决方法通常是创建第二个表(create table t as select * from contact_group)并切换表,但是我想找到真正的根本原因。

我发现有关错误的 only 引用是在code本身中,对我没有太大帮助。

这是在Hive 3上的hdp3.1上。

4 个答案:

答案 0 :(得分:1)

我也遇到了问题。通过orc-tools我扫描了delete_delta下的所有文件,可以发现这些文件中的所有行都是相同的(例如,bucket_00000中有7行,而相同的7行在另一个文件bucket_00001中。)因此,当迭代下一个存储桶文件时,密钥(原始Transacion-bucket-rowId-currentWriteId)将相同。

另一种解决方法是将表创建为存储桶,也许可以避免该问题。

答案 1 :(得分:1)

以下是我们的一位用户所观察到的问题的摘要:

表在从磁盘获取任务操作期间失败,它被 delete_delta 文件 (https://issues.apache.org/jira/browse/HIVE-22318) 中的重复键标识符损坏,有一个临时解决方法可以通过设置 set hive 来读取表.fetch.task.conversion=none 但这无助于压缩或任何获取任务操作的成功。

创建表备份的步骤:

  • 与直线连接并在会话中运行以下属性:

    set hive.fetch.task.conversion=none ;

  • 现在您将能够对提到的表运行选择语句。

  • 运行以下语句为表创建备份

    create table <backup_tbl_name> as select * from <problem_tbl> ;

  • 准备好备份后,从会话中注销并检查 不设置任何属性的备份表,(检查计数和表 数据质量的一致性)

    select * from <backup_tbl_name> ;

从备份表创建原始副本:

  • 现在您可以删除问题表并替换为备份表

    drop table <problem_tbl> ;

    alter table <backup_tbl_name> rename to <original_tbl_name> ;

注意:为避免将来出现此问题,请在 DDL 中创建带有分桶列的表

答案 2 :(得分:1)

就我而言,我无法使用@ShuBham ShaRma 建议的解决方案解决问题。 在查看@cang_yun 的发现后,我尝试删除其中一个存储桶文件 (bucket_00001),并且能够再次在该表上运行 select 语句。我不确定这是不是正确的方法,但它对我来说很有效。

答案 3 :(得分:0)

就我而言,这是由用户错误引起的。这是由两个引用同一hdfs目录的表引起的。创建表时,我创建了位置名称,并意外地将同一目录复制到另一个表中。

然后,我的程序对两个事务表进行了更改,导致无法解析的增量文件。