Разделенная таблица Hive считывает все разделы, несмотря на наличие фильтра Spark - PullRequest
7 голосов
/ 22 мая 2019

Я использую spark со scala для чтения определенного раздела Hive. Раздел: year, month, day, a и b

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: задание прервано из-за сбоя этапа: сбой задачи 236 на этапе 0.0 4 раза, последний сбой: сбой задачи 236.3 на этапе 0.0 (TID 287, сервер, исполнитель 17): org.apache .hadoop.security.AccessControlException: В доступе отказано: пользователь = пользователь, доступ = READ, inode = "/ путь к таблице / таблица / год = 2019 / месяц = ​​2 / день = 27 / a = ж / б = х / неполный 00002" : пользователь: группа: -rw-RW ---- * * 1016

Как видите, 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 ]

2 голосов
/ 28 мая 2019

Таблица паркетных кустов в Spark может использовать следующие 2 потока считывания -

  1. Поток улья - используется, если для spark.sql.hive.convertMetastoreParquet установлено значение false.Чтобы разделение pruining работало в этом случае, вы должны установить spark.sql.hive.metastorePartitionPruning=true.

    spark.sql.hive.metastorePartitionPruning: при значении true некоторые предикаты будут отправлены в метасторское хранилище Hive, чтобы не было совпаденийразделы могут быть устранены ранее.Это влияет только на таблицы Hive, не преобразованные в отношения файловых источников (дополнительные сведения см. В разделах HiveUtils.CONVERT_METASTORE_PARQUET и HiveUtils.CONVERT_METASTORE_ORC

  2. Поток источника данных - в этом потоке по умолчанию отключение раздела включено.

1 голос
/ 28 мая 2019

Это может произойти, если в metastore нет значений раздела для столбца раздела.Можем ли мы запустить из Spark

ALTER TABLE db.table RECOVER PARTITIONS

, а затем повторить тот же запрос.

0 голосов
/ 28 мая 2019

Вы не сможете прочитать специальный раздел в таблице, к которой у вас нет доступа ко всем ее разделам с помощью Spark-Hive API. Spark использует разрешение на доступ к таблице Hive, а в Hive необходимо получить полный доступ к таблице.

Причина, по которой вы не можете рассматривать искривление как доступ Unix. Если вам нужно сделать это, используйте spark.csv (или любой другой формат). Затем прочитайте данные в виде файла.

Вы можете просто использовать spark.csv.read("/path-to-table/table/year=2019/month=2/day=27/a=w/b=x/part-")

Если вам нужно проверить мой ответ, игнорируйте spark и попробуйте выполнить тот же запрос в оболочке Hive, он не будет работать как часть конфигурации улья.

...