Actuellement, nous utilisons le format de données Avro en production. Sur plusieurs bons points utilisant Avro, nous savons qu'il est bon dans l'évolution des schémas.
Nous évaluons maintenant le format de parquet en raison de son efficacité lors de la lecture de colonnes aléatoires. Donc, avant d'aller de l'avant, notre préoccupation est toujours l'évolution du schéma .
Est-ce que quelqu'un sait si l'évolution du schéma est possible dans le parquet, si oui Comment est-il possible, si non alors Pourquoi non.
Certains ressources prétendent que c'est possible mais il ne peut ajouter que des colonnes à la fin .
Qu'est-ce que ça veut dire?
L'évolution du schéma peut être (très) chère.
Pour comprendre le schéma, vous devez essentiellement lire tous vos fichiers parquet et réconcilier/fusionner leurs schémas pendant le temps de lecture, ce qui peut être coûteux en fonction du nombre de fichiers ou/et du nombre de colonnes dans l'ensemble de données.
Ainsi, depuis Spark 1.5 , ils ont désactivé fusion de schéma par défaut. Vous pouvez toujours le réactiver).
Étant donné que la fusion de schémas est une opération relativement coûteuse et n'est pas une nécessité dans la plupart des cas, nous l'avons désactivée par défaut à partir de 1.5.0.
Sans évolution de schéma, vous pouvez lire le schéma à partir d'un fichier parquet, et pendant la lecture du reste des fichiers, supposez qu'il reste le même.
L'évolution du schéma de parquet dépend de l'implémentation.
Hive par exemple a un bouton parquet.column.index.access=false
que vous pouvez définir pour mapper le schéma par nom de colonne plutôt que par index de colonne.
Ensuite, vous pouvez également supprimer des colonnes, pas seulement en ajouter.
Comme je l'ai dit ci-dessus, cela dépend de l'implémentation, par exemple, Impala ne lirait pas correctement ces tables de parquet (corrigé dans la récente version d'Impala 2.6) [ Référence ].
Apache Spark, à partir de la version 2.0.2, semble toujours ne prendre en charge que ajout de colonnes: [ Référence ]
Les utilisateurs peuvent commencer avec un schéma simple et ajouter progressivement plus de colonnes au schéma selon les besoins. De cette façon, les utilisateurs peuvent se retrouver avec plusieurs fichiers Parquet avec des schémas différents mais mutuellement compatibles. La source de données Parquet est désormais capable de détecter automatiquement ce cas et de fusionner les schémas de tous ces fichiers.
PS: Ce que j'ai vu certaines personnes faire pour avoir plus d'agilité sur les changements de schéma, c'est qu'elles créent une vue au-dessus de tables de parquet réelles qui associent deux (ou plus) schémas différents mais compatibles à un schéma commun.
Supposons que vous ayez ajouté un nouveau champ (registration_date
) et a supprimé une autre colonne (last_login_date
) dans votre nouvelle version, cela ressemblerait à ceci:
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
;
Vous avez l'idée. Heureusement, cela fonctionnerait de la même manière dans tous les sql sur les dialectes Hadoop (comme je l'ai mentionné ci-dessus Hive, Impala et Spark), et aurait toujours tous les avantages des tables Parquet (stockage en colonnes, Push-down de prédicat, etc.).
P.P.S: en ajoutant quelques informations concernant common_metadata
fichiers de résumé que Spark peut créer pour rendre cette réponse plus complète.
Jetez un oeil à SPARK-15719
Les fichiers de résumé de parquet ne sont pas particulièrement utiles de nos jours car
- 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.
Donc, certains points sont contre l'activation de common_metadata
:
Lorsqu'un répertoire est composé de fichiers Parquet avec un mélange de schémas différents, _common_metadata permet aux lecteurs de trouver un schéma raisonnable pour l'ensemble du répertoire sans lire le schéma de chaque fichier individuel. Étant donné que Hive et Impala peuvent accéder à un schéma SQL pour lesdits fichiers à partir de la métastore Hive, ils peuvent immédiatement commencer à traiter les fichiers individuels et les comparer chacun avec le schéma SQL lors de la lecture au lieu d'explorer leur schéma commun au préalable. Cela rend la fonction de métadonnées commune inutile pour Hive et Impala.
Même si Spark traite les fichiers Parquet sans schéma SQL (à moins d'utiliser SparkSQL) et que, par conséquent, en théorie, il pourrait bénéficier de _common_metadata, cette fonctionnalité a toujours été jugée inutile et a donc été désactivée par défaut dans SPARK -15719.
Même si cette fonctionnalité était utile pour les requêtes, elle reste un fardeau lors de l'écriture. Les métadonnées doivent être maintenues, ce qui est non seulement lent, mais également sujet aux conditions de course et à d'autres problèmes de concurrence, souffre du manque de garanties d'atomicité et conduit facilement à des problèmes d'exactitude des données en raison de métadonnées périmées ou incohérentes.
La fonctionnalité n'est pas documentée et semble être considérée comme obsolète (uniquement "semble l'être" car elle ne semble jamais avoir été prise en charge officiellement du tout en premier lieu, et une fonctionnalité non prise en charge ne peut pas non plus être déconseillée).
De l'un des ingénieurs de Cloudera: "Je ne sais pas si le comportement a changé en lecture pour éviter de regarder chaque pied de page si le common_metadata
le fichier est présent. Mais quoi qu'il en soit, l'écriture de ce fichier en premier lieu est un énorme goulot d'étranglement et a causé beaucoup de problèmes à nos clients. Je vous recommande vivement de ne pas prendre la peine d'essayer de générer ce fichier de métadonnées. "
Les fichiers "_common_metadata" et "_metadata" sont Spark spécifiques et ne sont pas écrits par Impala et Hive par exemple, et peut-être d'autres moteurs.
Les fichiers de métadonnées récapitulatifs dans Spark peut toujours avoir ses cas d'utilisation - quand il n'y a pas de concurrence et d'autres problèmes décrits ci-dessus - par exemple, certains cas d'utilisation de streaming - je suppose que c'est pourquoi cette fonctionnalité n'était pas complètement retiré de Spark.
En plus de la réponse ci-dessus, une autre option consiste à définir
"spark.hadoop.parquet.enable.summary-metadata" to "true"
Cela crée des fichiers récapitulatifs avec le schéma lorsque vous écrivez des fichiers. Lorsque vous enregistrez, vous verrez les fichiers récapitulatifs des fichiers '_metadata'
et '_common_metadata'
. _common_metadata
est le schéma compressé qui est lu chaque fois que vous lisez le fichier parquet. Cela rend la lecture très rapide car vous avez déjà le schéma. Spark recherche ces fichiers de schéma, s'ils sont présents, pour obtenir le schéma.
Notez que cela rend les écritures très lentes car Spark doit fusionner le schéma de tous les fichiers et créer ces fichiers de schéma.
Nous avons eu une situation similaire où le schéma du parquet a changé. Ce que nous avons fait est de définir la configuration ci-dessus sur true
pendant un certain temps après le changement de schéma afin que les fichiers de schéma soient générés, puis de la redéfinir sur false
. Nous avons dû faire des compromis sur les écritures lentes pendant un certain temps, mais une fois les fichiers de schéma générés, le définir sur false
a servi le but. Et avec un bonus de lecture plus rapide des fichiers.