Concevoir et implémenter un schéma de partitionnement de données
Conseil / Astuce
Pour plus d’informations, consultez l’onglet Texte et images !
Le partitionnement des données affecte directement l’exécution efficace de vos requêtes et la quantité de ressources de calcul que vous consommez. Lorsque vous partitionnez une table, vous divisez les données en segments discrets en fonction des valeurs de colonne, ce qui permet au moteur de requête de lire uniquement les parties pertinentes de votre jeu de données. Cette approche, appelée élagage de partition, peut réduire considérablement les balayages des données lorsque les filtres correspondent aux limites des partitions.
Considérez une entreprise de vente au détail traitant des millions de transactions de ventes quotidiennes. Les analystes interrogent fréquemment les données par plage de dates pour générer des rapports hebdomadaires, comparer les tendances mensuelles sur mois et analyser les modèles saisonniers. Sans partitionner, chaque requête analyse l’intégralité de l’historique des transactions. Avec le partitionnement approprié par date, les requêtes d’une semaine spécifique ne touchent qu’une fraction des fichiers stockés.
Déterminer quand le partitionnement s’applique
Databricks recommande de ne pas partitionner les tables contenant moins de 1 To de données. Pour les tables plus petites, la surcharge de gestion des métadonnées de partition et le potentiel de création de nombreux petits fichiers l’emporte sur les avantages de performances des requêtes. Les tables Delta non partitionnées dans les versions récentes de Databricks Runtime bénéficient automatiquement du clustering au moment de l'ingestion, ce qui offre des avantages de requête similaires sans configuration explicite.
Lorsque vos tables dépassent 1 To, le partitionnement devient une technique d’optimisation précieuse. À cette échelle, les avantages de la lecture uniquement des segments de données pertinents ont considérablement compensé les coûts de gestion des partitions. Le partitionnement active également le traitement parallèle, car Spark peut distribuer différentes partitions entre les nœuds de cluster pour une exécution simultanée.
Important
Chaque partition doit contenir au moins 1 Go de données. Cette directive vous permet d’éviter le sur-partitionnement, ce qui crée des fichiers trop petits et dégrade les performances des requêtes.
Pour les tables très volumineuses dans l'ordre de centaines de téraoctets, le partitionnement offre encore plus d’avantages. À cette échelle, l'élimination des partitions réduit considérablement la quantité de données que le moteur de requête doit traiter, améliorant à la fois les performances et l'efficacité des coûts.
Choisir des clés de partition effectives
La sélection de clé de partition vous oblige à comprendre vos caractéristiques de données et modèles de requête. Les clés de partition efficaces partagent des caractéristiques communes qui optimisent les avantages en matière de performances tout en évitant les pièges courants.
Les colonnes de cardinalité faible fonctionnent mieux
Choisissez des colonnes avec un nombre limité de valeurs distinctes. Les colonnes de date, les régions géographiques, les catégories de produits et les champs d’état constituent d’excellentes clés de partition, car elles créent un nombre gérable de partitions. Une colonne avec des milliers ou des millions de valeurs uniques, telles que l’ID client ou l’ID de transaction, entraîne un sur-partitionnement et des performances médiocres.
Par exemple, partitionner une table des ventes par sale_date au niveau quotidien peut créer 365 partitions par an. Si chaque jour contient un volume de données suffisant, cette granularité fonctionne bien. Toutefois, le partitionnement au sale_timestamp deuxième niveau créerait des millions de partitions, chacun contenant des données minimales.
Aligner avec les modèles de requête
Votre clé de partition doit correspondre aux colonnes que les utilisateurs filtrent le plus fréquemment. Si les analystes interrogent régulièrement les données de ventes par plage de dates, le partitionnement par date permet de réduire efficacement l'ensemble des données. Si les requêtes filtrent principalement par région, considérez plutôt la région comme clé de partition.
Lorsque plusieurs modèles de filtre existent, hiérarchiser les requêtes les plus courantes ou les plus critiques en matière de performances. Vous pouvez définir un schéma de partitionnement par table. Choisissez donc les colonnes qui bénéficient de la majorité de votre charge de travail. Pour des modèles de requête considérablement différents, envisagez de créer des vues matérialisées ou des tables récapitulatives optimisées distinctes pour des cas d’usage spécifiques.
Prendre en compte la croissance des données au fil du temps
Sélectionnez un schéma de partition qui s’adapte de manière appropriée à mesure que vos données augmentent. Le partitionnement par année fonctionne bien initialement, mais peut créer des partitions trop volumineuses au fil du temps. À l’inverse, le partitionnement par heure peut fonctionner pour des données à volume élevé, mais crée trop de petites partitions pour des volumes modérés.
Évaluez votre taux de croissance des données attendu lors du choix de la granularité de partition. Un équilibre entre la taille de partition et le nombre de partitions permet de maintenir des performances de requête cohérentes à mesure que votre jeu de données se développe.
Tenez également compte de la distribution des données entre les partitions. Des tailles de partition fortement inégales peuvent créer des goulots d'étranglement de traitement, car les nœuds qui gèrent les partitions plus grandes mettent plus de temps à se terminer tandis que les autres restent inactifs.
Implémenter des partitions dans Azure Databricks
Vous définissez des partitions lors de la création d’une table à l’aide de la PARTITIONED BY clause dans SQL ou de la partitionBy méthode dans PySpark. Une fois que vous avez établi des partitions, Azure Databricks achemine automatiquement les données entrantes vers les répertoires de partition appropriés en fonction des valeurs de colonne.
Créer une table partitionnée avec SQL
L’exemple suivant crée une table de transactions de vente partitionnée par la date de transaction :
CREATE TABLE sales.transactions (
transaction_id STRING,
customer_id STRING,
product_id STRING,
quantity INT,
unit_price DECIMAL(10,2),
total_amount DECIMAL(12,2),
transaction_date DATE
)
PARTITIONED BY (transaction_date);
Lorsque vous interrogez cette table avec un filtre de date, le moteur de requête lit uniquement les partitions qui correspondent à vos critères de filtre :
SELECT product_id, SUM(total_amount) AS revenue
FROM sales.transactions
WHERE transaction_date BETWEEN '2024-01-01' AND '2024-01-31'
GROUP BY product_id;
Créer une table partitionnée avec PySpark
Lors de l’utilisation de PySpark, spécifiez le partitionnement pendant l’opération d’écriture :
df.write.format("delta") \
.partitionBy("transaction_date") \
.saveAsTable("sales.transactions")
Pour les écritures suivantes, conservez la cohérence en incluant la même spécification de partition :
new_transactions_df.write.format("delta") \
.mode("append") \
.partitionBy("transaction_date") \
.saveAsTable("sales.transactions")
Utiliser des colonnes générées pour la flexibilité de la partition
Les colonnes générées permettent de dériver des valeurs de partition à partir de colonnes existantes sans stocker de données redondantes. Cette approche est utile lorsque vos données sources contiennent des horodatages, mais que vous souhaitez partitionner par date :
CREATE TABLE sales.transactions (
transaction_id STRING,
customer_id STRING,
product_id STRING,
quantity INT,
unit_price DECIMAL(10,2),
total_amount DECIMAL(12,2),
transaction_timestamp TIMESTAMP,
transaction_date DATE GENERATED ALWAYS AS (CAST(transaction_timestamp AS DATE))
)
PARTITIONED BY (transaction_date);
Conseil / Astuce
Avec cette configuration, Delta Lake génère automatiquement des filtres de partition lorsque vous interrogez à l’aide de la colonne timestamp de base. Une requête filtrant sur transaction_timestamp bénéficie de l'élimination de partitions sans nécessiter de filtres de date explicites.
Éviter les erreurs de partitionnement courantes
Comprendre ce qu’il faut éviter est aussi important que de savoir ce qu’il faut faire. Plusieurs erreurs courantes peuvent dégrader considérablement les performances et compliquer la gestion des données.
Le sur-partitionnement crée de petits problèmes de fichier
La création d’un trop grand nombre de partitions, chacune contenant des données insuffisantes, entraîne de petits problèmes de fichiers. Lorsque les partitions contiennent des fichiers plus petits que la taille de fichier cible, les performances des requêtes souffrent d’opérations de métadonnées excessives et réduisent l’efficacité de lecture. Visez les partitions avec au moins 1 Go de données.
Les signes de sur-partitionnement incluent des performances lentes des requêtes malgré l'élagage des partitions, un grand nombre de petits fichiers dans les répertoires de partition, et de longs temps d'optimisation des tables. Si vous observez ces symptômes, envisagez de choisir une granularité de partition plus grossière.
Le partitionnement sur les colonnes à cardinalité élevée échoue
Les colonnes avec de nombreuses valeurs uniques servent mal de clés de partition. Le partitionnement par ID client, ID de transaction ou d’autres colonnes à cardinalité élevée crée des millions de partitions qui se dégradent plutôt que d’améliorer les performances. Réservez l’optimisation des colonnes à cardinalité élevée pour d’autres techniques conçues à cet effet.
La modification des partitions nécessite la réécriture des données
Les colonnes de partition font partie de la structure de la table. La modification de votre stratégie de partitionnement nécessite la réécriture de la table entière vers un nouvel emplacement avec différentes limites de partition. Cette opération consomme des ressources de calcul importantes et du temps pour les tables volumineuses.
Planifiez soigneusement votre stratégie de partitionnement avant de charger des données à grande échelle. Envisagez les futurs modèles de requête et la croissance des données pour éviter une restructuration coûteuse ultérieurement.
Documenter les décisions de partitionnement
Enregistrez vos choix de clé de partition et le raisonnement derrière eux. Cette documentation aide les membres de l’équipe à comprendre les opportunités d’optimisation des requêtes et à empêcher les modifications accidentelles susceptibles d’avoir un impact sur les performances. Incluez des informations sur les tailles de partition attendues, les modèles de requête qui bénéficient du schéma et toutes les contraintes qui ont influencé vos décisions.
Considérer Liquid Clustering comme une alternative
Lorsque vous rencontrez des problèmes de partitionnement, en particulier avec des colonnes à cardinalité élevée comme les horodatages ou lorsque les modèles de requête sont incertains, le clustering liquide offre une alternative moderne. Contrairement au partitionnement traditionnel, les offres de clustering liquide sont les suivantes :
- Flexibilité pour ajuster les stratégies d’optimisation sans réécrire des données
- Maintenance automatique à mesure que les tables croissent
- Réduction de la surcharge de gestion des partitions
Le clustering liquide est l’approche recommandée pour les nouvelles tables où les contraintes de partitionnement limitent les performances ou créent une charge de maintenance excessive. Il est particulièrement efficace pour les tables qui dépassent 1 To et nécessitent un filtrage sur des colonnes qui créeraient trop de partitions à l’aide d’approches traditionnelles.
Note
Le clustering liquide n’est pas compatible avec les tables partitionnées. Choisissez une approche basée sur vos besoins lors de la conception de nouvelles tables.
Pour plus d’informations sur l’implémentation, la syntaxe et les stratégies d’optimisation, reportez-vous à la conception et implémentez une unité de stratégie de clustering plus loin dans ce module.