繁体   English   中英

尽管有Spark过滤器,但Hive分区表会读取所有分区

[英]Hive partitioned table reads all the partitions despite having a Spark filter

我正在使用带scala的spark来读取特定的Hive分区。 分区是yearmonthdayab

scala> spark.sql("select * from db.table where year=2019 and month=2 and day=28 and a='y' and b='z'").show

但我得到这个错误:

org.apache.spark.SparkException:作业因阶段失败而中止:阶段0.0中的任务236失败4次,最近失败:阶段0.0中失去的任务236.3(TID 287,服务器,执行程序17):org.apache.hadoop。 security.AccessControlException:权限被拒绝:user = user,access = READ,inode =“/ path-to-table / table / year = 2019 / month = 2 / day = 27 / a = w / b = x / part-00002 “:用户:组:-rw-RW ----

正如你所看到的,spark试图读取不同的分区,我没有那里的permisions。

它不应该,因为我创建了一个过滤器,这个过滤器是我的分区。

我用Hive尝试了相同的查询,它的工作完美(没有访问问题)

Hive> select * from db.table where year=2019 and month=2 and day=28 and a='y' and b='z';

为什么spark试图读取这个分区而Hive不会?

我错过了一个Spark配置?

编辑:更多信息

一些文件是使用Hive创建的,其他文件是从一台服务器复制并以不同的权限粘贴到我们的服务器(我们无法更改权限),然后他们应该刷新数据。

我们正在使用: cloudera 5.13.2.1 hive 1.1.0 spark 2.3.0 hadoop 2.6.0 scala 2.11.8 java 1.8.0_144

显示创建表

|CREATE EXTERNAL TABLE Columns and type
PARTITIONED BY (`year` int COMMENT '*', `month` int COMMENT '*', `day` int COMMENT '*', `a` string COMMENT '*', `b` string COMMENT '*')
ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
WITH SERDEPROPERTIES (
 'serialization.format' = '1'
)
STORED AS
 INPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat'
 OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat'
LOCATION 'hdfs://path'
TBLPROPERTIES (
 'transient_lastDdlTime' = '1559029332'
)
|

Spark中的镶木地板蜂巢表可以使用以下2个读取流程 -

  1. Hive流 - 当spark.sql.hive.convertMetastoreParquet设置为false时将使用此流。 要在这种情况下将分区修剪工作,您必须设置spark.sql.hive.metastorePartitionPruning=true

    spark.sql.hive.metastorePartitionPruning:如果为true,则会将某些谓词下推到Hive Metastore中,以便可以提前消除不匹配的分区。 这仅影响未转换为文件源关系的Hive表(有关详细信息,请参阅HiveUtils.CONVERT_METASTORE_PARQUET和HiveUtils.CONVERT_METASTORE_ORC)

  2. 数据源流 - 默认情况下,此流程已启用分区修剪。

当Metastore没有分区列的分区值时,可能会发生这种情况。 我们可以从Spark运行吗?

ALTER TABLE db.table RECOVER PARTITIONS

然后重新运行相同的查询。

您将无法使用Spark-Hive API读取您无法访问其所有分区的表中的特殊分区。 Spark正在使用Hive表访问权限,而在Hive中,您需要对表进行完全访问。

您不能将spark-hive视为unix访问的原因。 如果你需要使用spark.csv(或任何格式)。 然后将数据作为文件读取。

你可以简单地使用spark.csv.read("/path-to-table/table/year=2019/month=2/day=27/a=w/b=x/part-")

如果您需要验证我的答案,忽略spark并尝试在Hive shell中运行相同的查询,它将无法作为配置单元配置的一部分。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM