Spark 2.3.1 AWS EMR не возвращает данные для некоторых столбцов, но работает в Афине / Престо и Спектруме
Я использую PySpark на Spark 2.3.1 на AWS EMR (Python 2.7.14)
spark = SparkSession \
.builder \
.appName("Python Spark SQL data source example") \
.config("hive.metastore.client.factory.class", "com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory") \
.config("hive.exec.dynamic.partition", "true") \
.config("hive.exec.dynamic.partition.mode", "nonstrict") \
.config("spark.debug.maxToStringFields", 100) \
.enableHiveSupport() \
.getOrCreate()
spark.sql('select `message.country` from datalake.leads_notification where `message.country` is not null').show(10)
Это не возвращает данных, 0 строк найдено. Каждое значение для каждой строки в таблице выше возвращается Null. Данные хранятся в PARQUET.
Когда я выполнял один и тот же SQL-запрос в AWS Athena/Presto или в AWs Redshift Spectrum, я получаю все данные столбца, возвращаемые правильно (большинство значений столбца не равны NULL).
Это запрос Athena SQL и Redshift SQL, который возвращает правильные данные:
select "message.country" from datalake.leads_notification where "message.country" is not null limit 10;
Я использую каталог AWS Glue во всех случаях. Столбец выше НЕ разделен, но таблица разбита на другие столбцы. Я пытался использовать ремонтный стол, это не помогло. т.е. MSCK REPAIR TABLE datalake.leads_notification
я попробовал схему слияния = True так:
spark = SparkSession \
.builder \
.appName("Python Spark SQL data source example") \
.config("hive.metastore.client.factory.class", "com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory") \
.config("hive.exec.dynamic.partition", "true") \
.config("spark.sql.parquet.mergeSchema", "true") \
.config("hive.exec.dynamic.partition.mode", "nonstrict") \
.config("spark.debug.maxToStringFields", 200) \
.enableHiveSupport() \
.getOrCreate()
Разницы нет, все же каждое значение одного столбца равно нулю, хотя некоторые не равны нулю.
Этот столбец был добавлен как последний столбец таблицы, поэтому большинство данных действительно являются нулевыми, но некоторые строки не являются нулевыми. Наконец, столбец отображается в списке столбцов в каталоге, прямо над разделенными столбцами.
Тем не менее Athena / Presto получает все ненулевые значения в порядке, как и Redshift Spectrum, но, увы, EMR Spark 2.3.1 PySpark отображает все значения для этого столбца как "нулевые". Все остальные столбцы в Spark получены правильно.
Может кто-нибудь помочь мне отладить эту проблему, пожалуйста?
Схему куста здесь трудно вырезать и вставить из-за формата вывода.
***CREATE TABLE datalake.leads_notification(
message.environment.siteorigin string,
dcpheader.dcploaddateutc string,
message.id int,
message.country string,
message.financepackage.id string,
message.financepackage.version string)
PARTITIONED BY (
partition_year_utc string,
partition_month_utc string,
partition_day_utc string,
job_run_guid string)
ROW FORMAT SERDE
'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
STORED AS INPUTFORMAT
'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat'
OUTPUTFORMAT
'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat'
LOCATION
's3://blahblah/leads_notification/leads_notification/'
TBLPROPERTIES (
'CrawlerSchemaDeserializerVersion'='1.0',
'CrawlerSchemaSerializerVersion'='1.0',
'UPDATED_BY_CRAWLER'='weekly_datalake_crawler',
'averageRecordSize'='3136',
'classification'='parquet',
'compressionType'='none',
'objectCount'='2',
'recordCount'='897025',
'sizeKey'='1573529662',
'spark.sql.create.version'='2.2 or prior',
'spark.sql.sources.schema.numPartCols'='4',
'spark.sql.sources.schema.numParts'='3',
'spark.sql.sources.schema.partCol.0'='partition_year_utc',
'spark.sql.sources.schema.partCol.1'='partition_month_utc',
'spark.sql.sources.schema.partCol.2'='partition_day_utc',
'spark.sql.sources.schema.partCol.3'='job_run_guid',
'typeOfData'='file')***
Все последние 3 столбца имеют одинаковые проблемы в Spark:
message.country string,
message.financepackage.id string,
message.financepackage.version string
Все возвращаются в Афинах / Престо и Redshift Spectrum, используя один и тот же каталог.
Я прошу прощения за мое редактирование.
благодарю вас
2 ответа
Выполните шаг 5 проверки схемы: http://www.openkb.info/2015/02/how-to-build-and-use-parquet-tools-to.html
Держу пари, что эти новые имена столбцов в определении паркета либо в верхнем регистре (в то время как другие имена столбцов в нижнем регистре), либо новые имена столбцов в определении партера в нижнем регистре (в то время как другие имена столбцов в верхнем регистре)
см. проблемы с Spark при чтении файлов паркета https://medium.com/@an_chee/why-using-mixed-case-field-names-in-hive-spark-sql-is-a-bad-idea-95da8b6ec1e0
spark = SparkSession \
.builder \
.appName("Python Spark SQL data source example") \
.config("hive.metastore.client.factory.class", "com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory") \
.config("hive.exec.dynamic.partition", "true") \
.config("spark.sql.parquet.mergeSchema", "true") \
.config("spark.sql.hive.convertMetastoreParquet", "false") \
.config("hive.exec.dynamic.partition.mode", "nonstrict") \
.config("spark.debug.maxToStringFields", 200) \
.enableHiveSupport() \
.getOrCreate()
Это решение: обратите внимание на
.config("spark.sql.hive.convertMetastoreParquet", "false")
Все столбцы схемы находятся в нижнем регистре, и схема была создана AWS Glue, а не моим пользовательским кодом, поэтому я не знаю, в чем причина проблемы, поэтому использование вышеуказанного, вероятно, является безопасной настройкой по умолчанию, когда создание схемы не находится под вашим непосредственным контролем., Это главная ловушка, ИМХО, поэтому я надеюсь, что это поможет кому-то еще в будущем. Спасибо tooptoop4, который указал на статью: