Ответ 1
Эволюция схемы может быть (очень) дорогой.
Чтобы выяснить схему, вам, в основном, нужно прочитать все ваши файлы паркета и согласовать/объединить их схемы во время чтения, что может быть дорогостоящим в зависимости от того, сколько файлов или/и сколько столбцов находится в наборе данных.
Таким образом, начиная с Spark 1.5, они по умолчанию отключили объединение схем. Вы всегда можете включить его снова.
Поскольку объединение схем является относительно дорогой операцией, а не необходимость в большинстве случаев, мы отключили его по умолчанию, начиная с 1.5.0.
Без эволюции схемы вы можете читать схему из одного файла паркета, а во время чтения остальных файлов предполагать, что она останется прежней.
Эволюция схемы паркета зависит от реализации.
У улья, например, есть ручка parquet.column.index.access=false
что вы можете настроить отображение схемы по именам столбцов, а не по индексам столбцов.
Тогда вы можете удалить столбцы, а не просто добавить.
Как я уже говорил выше, это зависит от реализации, например, Impala не будет правильно читать такие паркетные таблицы (исправлено в недавнем выпуске Impala 2.6) [Ссылка].
Apache Spark, начиная с версии 2.0.2, поддерживает только добавление столбцов: [ссылка]
Пользователи могут начать с простой схемы и постепенно добавлять столбцы к схеме по мере необходимости. Таким образом, пользователи могут в конечном итоге с несколькими Паркетные файлы с разными, но взаимно совместимыми схемами. Источник данных для паркета теперь может автоматически обнаруживать этот случай и объединить схемы всех этих файлов.
PS: Я видел, что некоторые люди делают более гибкими изменения схемы, поскольку они создают представление поверх фактических таблиц паркета, которое отображает две (или более) разные, но совместимые схемы, в одну общую схему.
Допустим, вы добавили одно новое поле (registration_date
) и удалили другой столбец (last_login_date
) в своем новом выпуске, тогда это будет выглядеть следующим образом:
CREATE VIEW datamart.unified_fact_vw
AS
SELECT f1..., NULL as registration_date
FROM datamart.unified_fact_schema1 f1
UNION ALL
SELECT f2..., NULL as last_login_date
FROM datamart.unified_fact_schema2 f2
;
У тебя есть идея. Приятно, что он будет работать одинаково на всех sql на диалектах Hadoop (как я уже упоминал выше, Hive, Impala и Spark) и при этом будет иметь все преимущества таблиц Parquet (хранение в столбцах, push-down и т.д.).
P.P.S: добавление некоторой информации относительно сводных файлов common_metadata
, которые Spark может создать, чтобы сделать этот ответ более полным.
Посмотрите на SPARK-15719
Сводные файлы паркета в настоящее время не особенно полезны, так как
- when schema merging is disabled, we assume
schema of all Parquet part-files are identical,
thus we can read the footer from any part-files.
- when schema merging is enabled, we need to read footers
of all files anyway to do the merge.
On the other hand, writing summary files can be expensive,
because footers of all part-files must be read and merged.
This is particularly costly when appending a small dataset
to a large existing Parquet dataset.
Так что некоторые моменты против включения common_metadata
:
Когда каталог состоит из файлов Parquet со смесью различных схем, _common_metadata позволяет читателям выяснить разумную схему для всего каталога, не читая схемы каждого отдельного файла. Поскольку Hive и Impala могут получить доступ к схеме SQL для указанных файлов из метастаза Hive, они могут сразу же начать обработку отдельных файлов и сопоставлять каждый из них со схемой SQL при чтении, вместо того, чтобы предварительно изучить их общую схему. Это делает функцию общих метаданных ненужной для Hive и Impala.
Несмотря на то, что Spark обрабатывает файлы Parquet без схемы SQL (если только не использует SparkSQL) и, следовательно, теоретически может извлечь выгоду из _common_metadata, эта функция все еще считается бесполезной и, следовательно, по умолчанию отключена в SPARK-15719.
Даже если эта функция была полезна для запросов, она все еще является бременем во время написания. Необходимо поддерживать метаданные, которые не только медленны, но и подвержены гоночным условиям и другим проблемам параллелизма, страдают от отсутствия гарантий атомарности и легко приводят к проблемам с правильностью данных из-за устаревших или несовместимых метаданных.
Эта функция недокументирована и, по-видимому, считается устаревшей (во-первых, "кажется, что она есть", потому что, во-первых, она вообще никогда не поддерживалась официально, а не поддерживаемая функция также не может устареть).
От одного из инженеров Cloudera: "Я не знаю, изменилось ли поведение на стороне чтения, чтобы не смотреть на каждый нижний колонтитул, если присутствует файл
common_metadata
. Но независимо от того, запись этого файла в первую очередь является ОГРОМНЫМ узким местом"., и вызвало много проблем для наших клиентов. Я действительно настоятельно рекомендую, чтобы они не пытались сгенерировать этот файл метаданных. "Файлы "_common_metadata" и "_metadata" являются специфичными для Spark и не пишутся, например, Impala и Hive и, возможно, другими движками.
Сводные файлы метаданных в Spark могут по-прежнему иметь свои варианты использования, хотя - когда нет параллелизма и других проблем, описанных выше - например, некоторые потоковые сценарии использования - я думаю, поэтому эта функция не была полностью удалена из Spark.