Utilisation d'Athena pour interroger des jeux de données Apache Hudi - Amazon Athena

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Utilisation d'Athena pour interroger des jeux de données Apache Hudi

Apache Hudi est un cadre de gestion de données open source qui simplifie le traitement progressif des données. Les actions d'insertion, de mise à jour, d'insertion ascendante et de suppression au niveau des registres sont traitées de manière beaucoup plus granulaire, ce qui réduit les frais généraux. Upsert désigne la possibilité d'insérer des registres dans un jeu de données existant s'ils n'existent pas encore ou de les mettre à jour s'ils existent déjà.

Hudi traite les événements d'insertion et de mise à jour des données sans créer de nombreux petits fichiers qui peuvent entraîner des problèmes de performance pour les analyses. Apache Hudi suit automatiquement les modifications et fusionne les fichiers afin qu'ils conservent une taille optimale. Cela évite de devoir créer des solutions personnalisées qui contrôlent et réécrivent de nombreux petits fichiers en un nombre réduit de gros fichiers.

Les jeux de données Hudi sont adaptés pour les cas d'utilisation suivants :

Les jeux de données gérés par Hudi sont stockés dans Amazon S3 en utilisant des formats de stockage ouverts. Actuellement, Athena peut lire des jeux de données Hudi compactés, mais pas écrire des données Hudi. Athena prend en charge jusqu'à la version 0.8.0 de Hudi avec la version 2 du moteur Athena, et la version 0.14.0 de Hudi avec la version 3 du moteur Athena. Cela est susceptible de changer. Athena ne peut garantir la compatibilité de lecture avec les tables créées avec des versions ultérieures de Hudi. Pour plus d'informations sur la gestion des versions du moteur Athena, voir Gestion des versions du moteur Athena. Pour plus d’informations sur les fonctions et la gestion des versions de Hudi, voir la documentation Hudi sur le site Web Apache.

Types de table de jeux de données Hudi

Un jeu de données Hudi peut être l'un des types suivants :

  • Copie sur écriture (CoW) – Les données sont stockées dans un format en colonnes (Parquet) et chaque mise à jour crée une nouvelle version des fichiers lors d'une écriture.

  • Fusion sur lecture (MoR) – Les données sont stockées en utilisant une combinaison de formats en colonnes (Parquet) et en lignes (Avro). Les mises à jour sont enregistrées dans les fichiers delta en lignes et sont compactées si nécessaire pour créer de nouvelles versions des fichiers en colonnes.

Avec les ensembles de données CoW, chaque fois qu'une mise à jour est apportée à un enregistrement, le fichier qui contient l'enregistrement est réécrit avec les valeurs mises à jour. Avec un jeu de données MoR, chaque fois qu'une mise à jour a lieu, Hudi écrit uniquement la ligne du registre modifié. Le type de stockage MoR est mieux adapté aux charges de travail donnant lieu à de nombreuses écritures ou modifications avec moins de lectures. Le type de stockage CoW est mieux adapté aux charges de travail lourdes en lecture sur des données qui changent moins fréquemment.

Hudi propose trois types de requêtes pour accéder aux données :

  • Requêtes d'instantané – Requêtes qui affichent le dernier instantané de la table à partir d'une action de validation ou de compactage donnée. Pour les tables MoR, les requêtes d'instantané exposent l'état le plus récent de la table en fusionnant les fichiers de base et delta de la dernière tranche de fichiers au moment de la requête.

  • Requête progressives – Les requêtes ne portent que sur les nouvelles données écrites dans la table, depuis une validation/un compactage donné. Cela fournit efficacement des flux de modifications pour activer les pipelines de données (Data Pipelines) progressives.

  • Requêtes à lecture optimisée – Pour les tables MoR, les requêtes portent sur les dernières données compactées. Pour les tables CoW, les requêtes portent sur les dernières données validées.

La table suivante montre les types de requêtes Hudi possibles pour chaque type de table.

Type de table Types de requêtes Hudi possibles
Copie sur écriture instantané, progressif
fusion sur lecture instantané, progressif, lecture optimisée

Actuellement, Athena prend en charge les requêtes d'instantané et les requêtes à lecture optimisée, mais pas les requêtes progressives. Sur les tables MoR, toutes les données exposées aux requêtes à lecture optimisée sont compactées . Cela procure de bonnes performances, mais n'inclut pas les dernières validations delta. Les requêtes d'instantané contiennent les données les plus récentes mais entraînent une surcharge de calcul, ce qui rend ces requêtes moins performantes.

Pour plus d'informations sur les compromis entre les types de tables et de requêtes, consultez Types de tables et de requêtes dans la documentation d'Apache Hudi.

Changement de terminologie Hudi : les vues sont désormais des requêtes

À partir de la version 0.5.1, Apache Hudi a modifié une partie de sa terminologie. Les anciennes vues sont appelées requêtes dans les versions ultérieures. La table suivante résume les anciens et les nouveaux termes.

Ancien terme Nouveau terme

CoW : vue à lecture optimisée

MoR : vue en temps réel

Requêtes d'instantané

Vue progressive Requête progressive
Vue à lecture optimisée MoR Requête à lecture optimisée

Tables de l'opération d'amorçage

À partir de la version 0.6.0 d'Apache Hudi, la fonction d'opération d'amorçage offre de meilleures performances avec les jeux de données Parquet existants. Au lieu de réécrire le jeu de données, une opération d'amorçage ne peut générer que des métadonnées, laissant le jeu de données en place.

Vous pouvez utiliser Athena pour interroger des tables à partir d'une opération d'amorçage, comme d'autres tables basées sur des données dans Simple Storage Service (Amazon S3). Dans votre instruction CREATE TABLE, spécifiez le chemin d'accès de la table Hudi dans votre clause LOCATION.

Pour plus d'informations sur la création de tables Hudi à l'aide de l'opération bootstrap dans Amazon EMR, consultez l'article Nouvelles fonctionnalités d'Apache Hudi disponibles sur Amazon EMR sur le Big Data Blog. AWS

Listage des métadonnées Hudi

Apache Hudi possède une table de métadonnées qui contient des fonctionnalités d'indexation pour améliorer les performances, telles que le listage des fichiers, le saut de données à l'aide de statistiques de colonnes et un index basé sur un filtre Bloom.

Parmi ces fonctionnalités, Athena ne prend actuellement en charge que l'index de listage des fichiers. L'index de listage des fichiers élimine les appels au système de fichiers tels que les « list files » en récupérant les informations d'un index qui gère un mappage d'une partition à des fichiers. Cela élimine le besoin de répertorier de manière récursive chaque partition sous le chemin de la table pour obtenir une vue du système de fichiers. Lorsque vous travaillez avec de grands jeux de données, cette indexation réduit considérablement la latence qui se produirait sinon lors de l'obtention de la liste des fichiers durant les écritures et les requêtes. Cela permet également d'éviter les goulots d'étranglement tels que la limitation des limites de demandes lors des appels LIST Amazon S3.

Note

Athena ne prend actuellement pas en charge le saut de données ni l'indexation par filtre Bloom.

Activation de la table de métadonnées Hudi

Le listage des fichiers basé sur les tables de métadonnées est désactivée par défaut. Pour activer la table de métadonnées Hudi et la fonctionnalité de listage des fichiers associée, définissez la propriété de table hudi.metadata-listing-enabled sur TRUE.

Exemple

L'exemple ALTER TABLE SET TBLPROPERTIES suivant active la table de métadonnées dans la table partition_cow d'exemple.

ALTER TABLE partition_cow SET TBLPROPERTIES('hudi.metadata-listing-enabled'='TRUE')

Considérations et restrictions

  • Athena ne prend pas en charge les requêtes progressives.

  • Athena ne prend pas en charge CTAS ou INSERT INTO sur les données Hudi. Si vous souhaitez qu'Athena prenne en charge l'écriture des jeux de données Hudi, envoyez vos commentaires à .

    Pour plus d'informations sur l'écriture des données Hudi, consultez les ressources suivantes :

  • L'utilisation de MSCK REPARATION TABLE sur les tables Hudi dans Athena n'est pas prise en charge. Si vous devez charger une table Hudi qui n'a pas été créée dans AWS Glue, utilisezALTER TABLE ADD PARTITION.

  • Omission d'objets S3 Glacier non prise en charge : si les objets de la table Apache Hudi appartiennent à une classe de stockage Amazon S3 Glacier, la définition de la propriété de la table read_restored_glacier_objects sur false n'a aucun effet.

    Par exemple, supposons que vous exécutiez la commande suivante :

    ALTER TABLE table_name SET TBLPROPERTIES ('read_restored_glacier_objects' = 'false')

    Pour les tables Iceberg et Delta Lake, la commande produit l'erreur Unsupported table property key: read_restored_glacier_objects. Pour les tables Hudi, la commande ALTER TABLE ne produit pas d'erreur, mais les objets Amazon S3 Glacier ne sont toujours pas ignorés. L'exécution de requêtes SELECT après la commande ALTER TABLE continue de renvoyer tous les objets.

Ressources supplémentaires

Pour des ressources supplémentaires sur l'utilisation d'Apache Hudi avec Athena, consultez les ressources suivantes.

Vidéo

La vidéo suivante montre comment utiliser Amazon Athena pour interroger un jeu de données Apache Hudi à lecture optimisée dans votre lac de données basé sur Simple Storage Service (Amazon S3).

Billets de blogs

Les articles suivants du blog AWS Big Data décrivent comment vous pouvez utiliser Apache Hudi avec Athena.

Création de tables Hudi

Cette section fournit des exemples d'instructions CREATE TABLE dans Athena pour les tables partitionnées et non partitionnées de données Hudi.

Si vous avez déjà créé des tables Hudi dans AWS Glue, vous pouvez les interroger directement dans Athena. Lorsque vous créez des tables Hudi partitionnées dans Athena, vous devez exécuter ALTER TABLE ADD PARTITION pour charger les données Hudi afin de pouvoir les interroger.

Exemples de création de table par copie sur écriture (CoW)

Table CoW non partitionnée

L'exemple suivant crée une table CoW non partitionnée dans Athena.

CREATE EXTERNAL TABLE `non_partition_cow`( `_hoodie_commit_time` string, `_hoodie_commit_seqno` string, `_hoodie_record_key` string, `_hoodie_partition_path` string, `_hoodie_file_name` string, `event_id` string, `event_time` string, `event_name` string, `event_guests` int, `event_type` string) ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' STORED AS INPUTFORMAT 'org.apache.hudi.hadoop.HoodieParquetInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat' LOCATION 's3://DOC-EXAMPLE-BUCKET/folder/non_partition_cow/'

Table CoW partitionnée

L'exemple suivant crée une table CoW partitionnée dans Athena.

CREATE EXTERNAL TABLE `partition_cow`( `_hoodie_commit_time` string, `_hoodie_commit_seqno` string, `_hoodie_record_key` string, `_hoodie_partition_path` string, `_hoodie_file_name` string, `event_id` string, `event_time` string, `event_name` string, `event_guests` int) PARTITIONED BY ( `event_type` string) ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' STORED AS INPUTFORMAT 'org.apache.hudi.hadoop.HoodieParquetInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat' LOCATION 's3://DOC-EXAMPLE-BUCKET/folder/partition_cow/'

L'exemple ALTER TABLE ADD PARTITION suivant ajoute deux partitions à la table partition_cow en exemple.

ALTER TABLE partition_cow ADD PARTITION (event_type = 'one') LOCATION 's3://DOC-EXAMPLE-BUCKET/folder/partition_cow/one/' PARTITION (event_type = 'two') LOCATION 's3://DOC-EXAMPLE-BUCKET/folder/partition_cow/two/'

Exemples de création de table par fusion sur lecture (MoR)

Hudi crée deux tables dans le métastore pour MoR : une table pour les requêtes d'instantané et une table pour les requêtes à lecture optimisée. Les deux tables peuvent être interrogées. Dans les versions de Hudi antérieures à 0.5.1, la table pour les requêtes à lecture optimisée avait le nom que vous aviez spécifié lorsque vous avez créé la table. À partir de la version 0.5.1 de Hudi, le nom de la table est suffixé par défaut par le suffixe _ro. Le nom de la table pour les requêtes d'instantané est le nom que vous avez spécifié, suivi de _rt.

Table non partitionnée à fusion sur lecture (MoR)

L'exemple suivant crée une table MoR non partitionnée dans Athena pour les requêtes à lecture optimisée. Notez que les requêtes à lecture optimisée utilisent le format d'entrée HoodieParquetInputFormat.

CREATE EXTERNAL TABLE `nonpartition_mor`( `_hoodie_commit_time` string, `_hoodie_commit_seqno` string, `_hoodie_record_key` string, `_hoodie_partition_path` string, `_hoodie_file_name` string, `event_id` string, `event_time` string, `event_name` string, `event_guests` int, `event_type` string) ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' STORED AS INPUTFORMAT 'org.apache.hudi.hadoop.HoodieParquetInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat' LOCATION 's3://DOC-EXAMPLE-BUCKET/folder/nonpartition_mor/'

L'exemple suivant crée une table MoR non partitionnée dans Athena pour les requêtes d'instantané. Pour les requêtes d'instantané, utilisez le format d'entrée HoodieParquetRealtimeInputFormat.

CREATE EXTERNAL TABLE `nonpartition_mor_rt`( `_hoodie_commit_time` string, `_hoodie_commit_seqno` string, `_hoodie_record_key` string, `_hoodie_partition_path` string, `_hoodie_file_name` string, `event_id` string, `event_time` string, `event_name` string, `event_guests` int, `event_type` string) ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' STORED AS INPUTFORMAT 'org.apache.hudi.hadoop.realtime.HoodieParquetRealtimeInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat' LOCATION 's3://DOC-EXAMPLE-BUCKET/folder/nonpartition_mor/'

Table partitionnée à fusion sur lecture (MoR)

L'exemple suivant crée une table MoR partitionnée dans Athena pour les requêtes à lecture optimisée.

CREATE EXTERNAL TABLE `partition_mor`( `_hoodie_commit_time` string, `_hoodie_commit_seqno` string, `_hoodie_record_key` string, `_hoodie_partition_path` string, `_hoodie_file_name` string, `event_id` string, `event_time` string, `event_name` string, `event_guests` int) PARTITIONED BY ( `event_type` string) ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' STORED AS INPUTFORMAT 'org.apache.hudi.hadoop.HoodieParquetInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat' LOCATION 's3://DOC-EXAMPLE-BUCKET/folder/partition_mor/'

L'exemple ALTER TABLE ADD PARTITION suivant ajoute deux partitions à la table partition_mor en exemple.

ALTER TABLE partition_mor ADD PARTITION (event_type = 'one') LOCATION 's3://DOC-EXAMPLE-BUCKET/folder/partition_mor/one/' PARTITION (event_type = 'two') LOCATION 's3://DOC-EXAMPLE-BUCKET/folder/partition_mor/two/'

L'exemple suivant crée une table MoR partitionnée dans Athena pour les requêtes d'instantané.

CREATE EXTERNAL TABLE `partition_mor_rt`( `_hoodie_commit_time` string, `_hoodie_commit_seqno` string, `_hoodie_record_key` string, `_hoodie_partition_path` string, `_hoodie_file_name` string, `event_id` string, `event_time` string, `event_name` string, `event_guests` int) PARTITIONED BY ( `event_type` string) ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' STORED AS INPUTFORMAT 'org.apache.hudi.hadoop.realtime.HoodieParquetRealtimeInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat' LOCATION 's3://DOC-EXAMPLE-BUCKET/folder/partition_mor/'

De même, l'exemple ALTER TABLE ADD PARTITION suivant ajoute deux partitions à la table partition_mor_rt en exemple.

ALTER TABLE partition_mor_rt ADD PARTITION (event_type = 'one') LOCATION 's3://DOC-EXAMPLE-BUCKET/folder/partition_mor/one/' PARTITION (event_type = 'two') LOCATION 's3://DOC-EXAMPLE-BUCKET/folder/partition_mor/two/'

Ressources supplémentaires