Bonnes pratiques pour le chargement groupé

Cette page fournit des consignes pour effectuer efficacement le chargement groupé de grandes quantités de données. dans Spanner.

Vous disposez de plusieurs options pour charger des données de façon groupée dans Spanner:

Bien que vous puissiez également Insérer des lignes à l'aide de la Google Cloud CLI nous vous déconseillons d'utiliser la gcloud CLI pour le chargement groupé.

Consignes relatives aux performances pour le chargement groupé

Optimisez votre utilisation du partitionnement pour optimiser les performances de chargement groupé pour répartir l'écriture des données entre les tâches de nœud de calcul.

Spanner utilise la répartition basée sur la charge pour répartir équitablement vos données sur les ressources de calcul de l'instance. Après quelques minutes de charge élevée, Spanner lance les limites de division entre les lignes. En règle générale, si votre charge de données est bien distribuée et que vous suivez les bonnes pratiques relatives à la conception de schémas et au chargement groupé, votre débit en écriture devrait doubler toutes les quelques minutes jusqu'à ce que les ressources de processeur de l'instance soient saturées.

Partitionner les données par clé primaire

Spanner partitionne dynamiquement les tables en plages plus petites. L'instance principale d'une ligne détermine l'emplacement où elle est partitionnée.

Pour obtenir un débit en écriture optimal pour les chargements groupés, partitionnez vos données par clé primaire selon ce modèle :

  • Chaque partition contient une plage de lignes consécutives, déterminée par les colonnes de clé.
  • Chaque commit contient des données pour une seule partition.

Nous recommandons que le nombre de partitions soit 10 fois supérieur au nombre de nœuds votre instance Spanner. Pour affecter des lignes aux partitions, procédez comme suit :

  • Triez vos données par clé primaire.
  • Divisez les données en 10 * (nombre de nœuds) partitions distinctes de taille égale.
  • Créez et affectez une tâche de nœud de calcul distincte à chaque partition. La création des tâches de nœud de calcul s'effectue dans votre application. Il ne s'agit pas d'une fonctionnalité de Spanner.

En suivant ce schéma, vous devriez constater un débit en écriture groupé global atteignant jusqu'à 10 à 20 Mo par seconde par nœud pour les charges importantes.

À mesure que vous chargez des données, Spanner crée et met à jour des divisions pour équilibrer sur les nœuds de votre instance. Pendant ce processus, des baisses temporaires du débit peuvent survenir.

Exemple

Vous avez une configuration régionale avec trois nœuds. Vous disposez d'une table non entrelacée contenant 90 000 lignes. Les clés primaires de la table vont de 1 à 90 000.

  • Lignes : 90 000
  • Nœuds : 3
  • Partitions : 10 * 3 = 30
  • Lignes par partition : 90 000 / 30 = 3 000.

La première partition comprend la plage de clés 1 à 3 000. La deuxième partition comprend la plage de clés 3 001 à 6 000. La 30e partition comprend la plage de clés 87 001 à 90 000. (Il est déconseillé d'utiliser des clés séquentielles dans une grande table. Cet exemple n'est présenté qu'à des fins de démonstration.)

Chaque tâche de nœud de calcul envoie les écritures pour une partition. Dans chaque partition, vous devez écrire les lignes de manière séquentielle par clé primaire. L'écriture aléatoire de lignes en fonction de la clé primaire devrait également fournir un débit raisonnablement élevé. Vous pouvez exécuter des tests pour déterminer l'approche offrant les meilleures performances pour votre ensemble de données.

Si vous décidez de ne pas utiliser de partitions

L'écriture de lignes aléatoires dans un commit peut être plus lente que l'écriture d'une de lignes contiguës dans un commit, et probablement sur des données touchées dans différentes des partitions. La latence du commit et les frais généraux sont plus élevés lorsque davantage de divisions sont en cours. écrit dans un commit, en raison d'une meilleure coordination entre les serveurs. Multiples les divisions sont probablement impliquées, car chaque ligne aléatoire peut appartenir à une division différente. Dans le pire des cas chaque écriture concerne toutes les divisions de votre instance Spanner. En tant que mentionné ci-dessus, le débit en écriture est réduit lorsque davantage de divisions sont impliquées.

Chargement groupé sans partitionnement

Écrire un ensemble de lignes contigus dans un commit peut être plus rapide que l'écriture aléatoire lignes. Les lignes aléatoires incluent également probablement des données provenant de différentes partitions.

Plus il y a de partitions écrites dans un commit, plus la coordination est requise, ce qui augmente la latence et les frais généraux du commit.

Plusieurs partitions sont probablement impliquées car chaque ligne aléatoire pourrait appartenir vers une autre partition. Dans le pire des cas, chaque écriture implique chaque partition de votre instance Spanner. Comme indiqué ci-dessus, écrivez le débit est réduit lorsque davantage de partitions sont impliquées.

Éviter la surcharge

Il est possible d'envoyer plus de requêtes d'écriture que Spanner ne peut en gérer. Spanner gère la surcharge en annulant les transactions, ce qui est appelé refus. Pour les transactions en écriture seule, Spanner relance automatiquement la transaction. Dans ce cas, le refus de transaction se traduit par une latence élevée. Lors de charges importantes, ce phénomène peut durer jusqu'à une minute. Lors de charges extrêmement lourdes, il peut durer plusieurs minutes. Pour éviter les refus de transaction, il est conseillé de limiter les requêtes d'écriture afin de maintenir l'utilisation du processeur dans des limites raisonnables. Les utilisateurs peuvent également augmenter le nombre de nœuds pour que l'utilisation du processeur reste dans les limites.

Commit entre 1 et 5 Mo de mutations à la fois

Chaque écriture sur Spanner entraîne une surcharge, que l'écriture soit volumineuse ou petits. Pour optimiser le débit, optimisez la quantité de données stockées par écriture. Les écritures de grande taille réduisent le ratio de surcharge par écriture. Une bonne technique consiste à appliquer des commits mutant des centaines de lignes. Lors de l'écriture de lignes relativement grandes, une taille de commit comprise entre 1 et 5 Mo offre généralement des performances optimales. Lors de l'écriture de petites valeurs ou de valeurs indexées, il est généralement préférable d'écrire au plus quelques centaines de lignes dans un même commit. Indépendamment de la taille du commit et du nombre de lignes, notez que la limite de 80 000 mutations par commit Pour déterminer les performances optimales, vous devez tester et mesurer le débit.

Les commits de plus de 5 Mo ou ceux de quelques centaines de lignes ne présentent des avantages supplémentaires et risquent de dépasser les limites de Spanner. sur la taille du commit et le nombre de mutations par commit.

Consignes relatives aux index secondaires

Si votre base de données contient des index secondaires, vous devez choisir d'ajouter les index au schéma de base de données avant ou après le chargement des données de la table.

  • L'ajout de l'index avant le chargement des données permet de terminer immédiatement la modification du schéma. Cependant, chaque écriture affectant l'index prend plus de temps, car il doit également mettre à jour l'index. Une fois le chargement des données terminé, la base de données est immédiatement utilisable avec tous les index en place. Pour créer une table et ses index en même temps, envoient les instructions LDD de la nouvelle table, de nouveaux index en une seule requête adressée à Spanner.

  • L'ajout de l'index après le chargement des données signifie que chaque écriture est efficace. Cependant, la modification du schéma de chaque remplissage de l'index peut prendre beaucoup de temps. La base de données n'est pas entièrement utilisable et les requêtes ne peuvent pas utiliser les index tant que que toutes les modifications du schéma sont terminées. La base de données peut toujours diffuser et des requêtes, mais à un rythme plus lent.

Nous vous recommandons d'ajouter les index essentiels à votre application métier. avant de charger les données. Pour tous les index non critiques, ajoutez-les après le sont migrées.

Tester et mesurer le débit

Il peut s'avérer difficile de prédire le débit. C'est pourquoi nous vous recommandons de tester votre stratégie de chargement groupé avant d'exécuter le chargement final. Pour obtenir un exemple détaillé d'utilisation du partitionnement et de surveillance des performances, consultez la page relative à l'optimisation du débit de chargement de données.

Bonnes pratiques relatives au chargement groupé périodique dans une base de données existante

Si vous mettez à jour une base de données existante contenant des données, mais ne disposant d'aucun index secondaire, les recommandations décrites sur cette page s'appliquent toujours.

Si vous disposez d'index secondaires, ces instructions peuvent quand même conduire à des performances raisonnables. Celles-ci dépendent du nombre moyen de divisions impliquées dans vos transactions. Si le débit est trop faible, vous pouvez essayer les solutions suivantes :

  • Incluez moins de mutations dans chaque commit pour tenter d'augmenter le débit.
  • Si la taille de l'importation est supérieure à la taille totale actuelle de la table mise à jour, supprimez les index secondaires, puis rajoutez-les une fois l'opération terminée. Cette étape n'est généralement pas indispensable, mais elle peut améliorer le débit.