ewolucja Schema można (bardzo) drogie, bo dowiedzieć się schemat trzeba po prostu czytać wszystkie pliki parkietem reconsile/scalić swoje schematy w czasie odczytu, które mogą być kosztowne w zależności ile plików/ile kolumn w zbiorze danych.
Dlatego w wersji Spark 1.5 wyłączono ewolucję schematu (domyślnie można go ponownie włączyć). http://spark.apache.org/docs/latest/sql-programming-guide.html:
Od schematu scalania jest stosunkowo kosztowna operacja, a nie jest koniecznością w większości przypadków możemy go wyłączył domyślnie począwszy od 1.5.0.
Bez ewolucji schematu można odczytać schemat z jednego pliku parkietu, a podczas czytania pozostałych plików założyć, że pozostaje taki sam.
Ewolucja schematu parkietu zależy od implementacji.
Hive na przykład posiada pokrętło
parquet.column.index.access = false
że można ustawić do mapowania schematu przez nazwy kolumn, a nie przez indeks kolumny. Następnie możesz również usunąć kolumny, a nie tylko dodać.
Jak powiedziałem, jest zależna od implementacji, na przykład, Impala nie będzie czytać takie tabele parkietem poprawnie (ustalony w ostatniej Impala 2.6 release): http://community.cloudera.com/t5/Interactive-Short-cycle-SQL/external-table-stored-as-parquet-can-not-use-field-inside-a/m-p/36012
Spark od wersji 2.0.2 wydaje się jeszcze tylko wsparcia kolumny dodając: http://spark.apache.org/docs/latest/sql-programming-guide.html#schema-merging
Użytkownicy mogą zacząć od prostego schematu i stopniowo dodać więcej kolumn do schematu, ile potrzeba. W ten sposób użytkownicy mogą otrzymać wiele plików parkietu z różnymi, ale wzajemnie zgodnymi schematami. Źródło danych Parquet jest teraz w stanie automatycznie wykryć ten przypadek i scalić schematy wszystkich tych plików.
PS. To, co widziałem, niektórzy robią, aby mieć większą elastyczność w zmianie schematu, jest to, że tworzą widok na prawdziwych tabelach parkietowych, które mapują dwa (lub więcej) różne, ale kompatybilne schematy do jednego wspólnego schematu. Załóżmy, że dodałem jedno nowe pole (registration_date
) i spadł innej kolumny (last_login_date
) w nowej wersji, to będzie wyglądać:
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
;
masz pomysł .. Nicea rzeczą byłoby to działa tak samo w całej wszystkie sql na dialektach Hadoop (jak wspomniałem powyżej Hive, Impala i Spark), i nadal mają wszystkie zalety tabel parkietu (przechowywanie kolumnowe, wypychanie predykatów itp.).
Tak, jest to możliwe. Zobacz na przykład [Spark docs] (https://spark.apache.org/docs/latest/sql-programming-guide.html#schema-merging) – zero323
Ale po prostu pokazuje dodanie nowego pola, nie kasowanie pola – ToBeSparkShark