Hive分区表读取了所有分区,尽管具有Spark过滤器

时间:2019-05-22 10:36:05

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

我正在使用带有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“:user:group:-rw-rw ----

如您所见,spark试图读取一个不同的分区,而我在那里没有权限。

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

我用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'
)
|

3 个答案:

答案 0 :(得分:2)

Spark中的镶木配置单元表可以使用以下2条读取流-

  1. 蜂巢流量- 将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. 数据源流-默认情况下,此流已启用分区修剪。

答案 1 :(得分:1)

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

ALTER TABLE db.table RECOVER PARTITIONS

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

答案 2 :(得分:-1)

您将无法读取无法使用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中运行相同的查询,它将不能作为配置单元的一部分。