【问题标题】:spark throws error when reading hive transaction table读取 hive 表时 spark 抛出错误
【发布时间】:2023-03-26 13:09:02
【问题描述】:

我正在尝试从 hive 中的 db.abc 中选择 *,此 hive 表是使用 spark 加载的

它不工作显示错误:

错误:java.io.IOException:java.lang.IllegalArgumentException: bucketId 超出范围:-1 (state=,code=0)

当我使用以下属性时,我能够查询 hive:

set hive.mapred.mode=nonstrict;
set hive.optimize.ppd=true;
set hive.optimize.index.filter=true;
set hive.tez.bucket.pruning=true;
set hive.explain.user=false; 
set hive.fetch.task.conversion=none;

现在当我尝试使用 spark 读取同一个配置单元表 db.abc 时,我收到如下错误:

只有满足以下条件的客户才能访问此表 能力: CONNECTORREAD、HIVEFULLACIDREAD、HIVEFULLACIDWRITE、HIVEMANAGESTATS、HIVECACHEINVALIDATE、CONNECTORWRITE。 此表可能是 Hive 管理的 ACID 表,或者需要其他一些 Spark 当前未实现的功能;在 org.apache.spark.sql.catalyst.catalog.CatalogUtils$.throwIfNoAccess(ExternalCatalogUtils.scala:280) 在 org.apache.spark.sql.hive.HiveTranslationLayerCheck$$anonfun$apply$1.applyOrElse(HiveTranslationLayerStrategies.scala:105) 在 org.apache.spark.sql.hive.HiveTranslationLayerCheck$$anonfun$apply$1.applyOrElse(HiveTranslationLayerStrategies.scala:85) 在 org.apache.spark.sql.catalyst.trees.TreeNode$$anonfun$transformUp$1.apply(TreeNode.scala:289) 在 org.apache.spark.sql.catalyst.trees.TreeNode$$anonfun$transformUp$1.apply(TreeNode.scala:289) 在 org.apache.spark.sql.catalyst.trees.CurrentOrigin$.withOrigin(TreeNode.scala:70) 在 org.apache.spark.sql.catalyst.trees.TreeNode.transformUp(TreeNode.scala:288) 在 org.apache.spark.sql.catalyst.trees.TreeNode$$anonfun$3.apply(TreeNode.scala:286) 在 org.apache.spark.sql.catalyst.trees.TreeNode$$anonfun$3.apply(TreeNode.scala:286) 在 org.apache.spark.sql.catalyst.trees.TreeNode$$anonfun$4.apply(TreeNode.scala:306) 在 org.apache.spark.sql.catalyst.trees.TreeNode.mapProductIterator(TreeNode.scala:187) 在 org.apache.spark.sql.catalyst.trees.TreeNode.mapChildren(TreeNode.scala:304) 在 org.apache.spark.sql.catalyst.trees.TreeNode.transformUp(TreeNode.scala:286) 在 org.apache.spark.sql.catalyst.trees.TreeNode$$anonfun$3.apply(TreeNode.scala:286) 在 org.apache.spark.sql.catalyst.trees.TreeNode$$anonfun$3.apply(TreeNode.scala:286) 在 org.apache.spark.sql.catalyst.trees.TreeNode$$anonfun$4.apply(TreeNode.scala:306) 在 org.apache.spark.sql.catalyst.trees.TreeNode.mapProductIterator(TreeNode.scala:187) 在 org.apache.spark.sql.catalyst.trees.TreeNode.mapChildren(TreeNode.scala:304) 在 org.apache.spark.sql.catalyst.trees.TreeNode.transformUp(TreeNode.scala:286) 在 org.apache.spark.sql.hive.HiveTranslationLayerCheck.apply(HiveTranslationLayerStrategies.scala:85) 在 org.apache.spark.sql.hive.HiveTranslationLayerCheck.apply(HiveTranslationLayerStrategies.scala:83) 在 org.apache.spark.sql.catalyst.rules.RuleExecutor$$anonfun$execute$1$$anonfun$apply$1.apply(RuleExecutor.scala:87) 在 org.apache.spark.sql.catalyst.rules.RuleExecutor$$anonfun$execute$1$$anonfun$apply$1.apply(RuleExecutor.scala:84) 在 scala.collection.LinearSeqOptimized$class.foldLeft(LinearSeqOptimized.scala:124) 在 scala.collection.immutable.List.foldLeft(List.scala:84) 在 org.apache.spark.sql.catalyst.rules.RuleExecutor$$anonfun$execute$1.apply(RuleExecutor.scala:84) 在 org.apache.spark.sql.catalyst.rules.RuleExecutor$$anonfun$execute$1.apply(RuleExecutor.scala:76) 在 scala.collection.immutable.List.foreach(List.scala:392) 在 org.apache.spark.sql.catalyst.rules.RuleExecutor.execute(RuleExecutor.scala:76) 在 org.apache.spark.sql.catalyst.analysis.Analyzer.org$apache$spark$sql$catalyst$analysis$Analyzer$$executeSameContext(Analyzer.scala:124) 在 org.apache.spark.sql.catalyst.analysis.Analyzer.execute(Analyzer.scala:118) 在 org.apache.spark.sql.catalyst.analysis.Analyzer.executeAndCheck(Analyzer.scala:103) 在 org.apache.spark.sql.execution.QueryExecution.analyzed$lzycompute(QueryExecution.scala:57) 在 org.apache.spark.sql.execution.QueryExecution.analyzed(QueryExecution.scala:55) 在 org.apache.spark.sql.execution.QueryExecution.assertAnalyzed(QueryExecution.scala:47) 在 org.apache.spark.sql.Dataset$.ofRows(Dataset.scala:74) 在 org.apache.spark.sql.SparkSession.sql(SparkSession.scala:642) ... 49 省略了

我需要在 spark-submit 或 shell 中添加任何属性吗?或者使用 spark 读取此配置单元表的替代方法是什么

hive 表示例格式:

  CREATE TABLE `hive``(                   |
|   `c_id` decimal(11,0),etc.........       
  ROW FORMAT SERDE                                   |
|   'org.apache.hadoop.hive.ql.io.orc.OrcSerde'      |
| WITH SERDEPROPERTIES (  
 STORED AS INPUTFORMAT                              |
|   'org.apache.hadoop.hive.ql.io.orc.OrcInputFormat'  |
| OUTPUTFORMAT                                       |
|   'org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat' |
 LOCATION                                           |
|  path= 'hdfs://gjuyada/bbts/scl/raw' |
| TBLPROPERTIES (                                    |
|   'bucketing_version'='2',                         |
|   'spark.sql.create.version'='2.3.2.3.1.0.0-78',   |
|   'spark.sql.sources.provider'='orc',              |
|   'spark.sql.sources.schema.numParts'='1',         |
|   'spark.sql.sources.schema.part.0'='{"type":"struct","fields":
[{"name":"Czz_ID","type":"decimal(11,0)","nullable":true,"metadata":{}},
{"name":"DzzzC_CD","type":"string","nullable":true,"metadata":{}},
{"name":"C0000_S_N","type":"decimal(11,0)","nullable":true,"metadata":{}},
{"name":"P_ _NB","type":"decimal(11,0)","nullable":true,"metadata":{}},
{"name":"C_YYYY","type":"string","nullable":true,"metadata":{}},"type":"string","nullable":true,"metadata":{}},{"name":"Cv_ID","type":"string","nullable":true,"metadata":{}},
|   'transactional'='true',                          |
|   'transient_lastDdlTime'='1574817059')  

【问题讨论】:

  • 分享您尝试读取的配置单元表信息。

标签: apache-spark hive apache-spark-sql


【解决方案1】:

您尝试将 Transactional table(transactional = true) 读入 Spark 的问题。

官方 Spark 尚不支持 Hive-ACID 表,请获取 full dump/incremental dump of acid table 到常规的 hive orc/parquet 分区表,然后使用 spark 读取数据。

有一个 Open Jira SPARK-15348 来增加对读取 Hive ACID 表的支持。

  • 如果您在 Acid 表(来自 hive)上运行 major compaction 则 spark 只能读取 base_XXX 目录,但不能读取增量目录 SPARK-16996 在此解决吉拉。

  • 有一些解决方法可以使用此链接中提到的SPARK-LLAP 读取酸表。

  • 我认为HDP-3.XHiveWareHouseConnector开始可以支持读取HiveAcid表。

  • 您可以将事务表的snapshot创建为non transactional,然后从表中读取数据。

     **`create table <non_trans> stored as orc as select * from <transactional_table>`**
    

UPDATE:

1.创建外部hive表:

 CREATE external TABLE `<ext_tab_name>`(  
       <col_name>       <data_type>....etc
           )
    stored as orc
    location '<path>';

2.然后用现有的事务表数据覆盖上述外部表。

 insert overwrite table <ext_tab_name> select * from <transactional_tab_name>;

【讨论】:

  • 您能否提供一些有关从跨国创建非跨国表快照的信息,在从跨国创建 hive 表时是否需要提及 transnational=false?
  • @user12763124,我认为不需要,如果您使用HDP-3,请确保快照表未启用事务!,(或)您可以使用create an external table same schema as transactional table 然后通过从事务表中选择数据插入覆盖到外部表!!
  • create table stored as orc as select * from 显示存储桶超出范围 -1 错误或 创建具有相同架构的外部表由于事务表给出了相同的桶超出范围-1错误
  • 是的,在最初使用 spark 创建的 hive 表上是 transactional =true
【解决方案2】:

你需要用TBLPROPERTIES ( 'transactional'='false' )创建表

CREATE TABLE your_table(
  `col` string, 
  `col2` string)
ROW FORMAT SERDE 
  'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe' 
STORED AS INPUTFORMAT 
  'org.apache.hadoop.mapred.TextInputFormat' 
OUTPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
TBLPROPERTIES ( 
  'transactional'='false' 
)

【讨论】:

    猜你喜欢
    • 2020-12-30
    • 2019-04-29
    • 2018-09-07
    • 1970-01-01
    • 2018-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-08
    相关资源
    最近更新 更多