Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Divisez un magasin de données en un ensemble de partitions horizontales ou de shards. Cette approche peut améliorer la scalabilité lorsque vous stockez et accédez à de grands volumes de données.
Contexte et problème
Un magasin de données sur un serveur unique présente les limitations suivantes :
Espace de stockage : Un magasin de données pour une application cloud à grande échelle peut contenir un grand volume de données qui augmente au fil du temps. Un serveur fournit une quantité limitée de stockage sur disque, et vous pouvez remplacer les disques existants par des disques plus volumineux ou ajouter d’autres disques à mesure que les volumes de données augmentent. Le système atteint finalement une limite où vous ne pouvez pas augmenter la capacité de stockage sur un seul serveur.
Ressources informatiques : Une application cloud doit prendre en charge un grand nombre d’utilisateurs simultanés qui exécutent chacune des requêtes sur le magasin de données. Un seul serveur peut ne pas fournir suffisamment de puissance de calcul pour cette charge, entraînant des temps de réponse prolongés et des expirations. Vous pouvez ajouter de la mémoire ou mettre à niveau des processeurs, mais le système atteint une limite où vous ne pouvez plus augmenter les ressources de calcul.
Bande passante réseau : Le taux auquel un serveur unique peut recevoir des demandes et envoyer des réponses limite les performances du magasin de données. Le volume du trafic réseau peut dépasser la capacité de la connexion réseau, ce qui entraîne des échecs de requêtes.
Géographie: Les exigences légales, de conformité ou de performances peuvent vous obliger à stocker des données utilisateur dans la même région géographique que les utilisateurs. Si les utilisateurs s’étendent sur plusieurs pays/régions, il se peut que vous ne puissiez pas stocker toutes les données de l’application dans un magasin de données unique.
Pour reporter ces limitations temporairement, vous pouvez effectuer une mise à l’échelle verticalement en ajoutant une capacité de disque, une puissance de traitement, une mémoire et des connexions réseau. Une application cloud qui doit prendre en charge un grand nombre d’utilisateurs et de volumes de données élevés doit être mise à l’échelle horizontalement.
Solution
Divisez le magasin de données en partitions horizontales ou en shards. Chaque fragment a le même schéma, mais contient son propre sous-ensemble distinct des données. Chaque fragment est une base de données complète qui peut contenir des données pour de nombreuses entités de différents types. Une partition s’exécute sur un serveur qui fonctionne comme un nœud de stockage.
Ce modèle permet de bénéficier des avantages suivants :
Vous pouvez augmenter la capacité du système en ajoutant davantage de partitions sur des nœuds de stockage supplémentaires.
Un système peut utiliser du matériel prédéfini plutôt que des ordinateurs spécialisés et coûteux pour chaque nœud de stockage.
Vous pouvez réduire la concurrence et améliorer les performances en équilibrant la charge de travail entre les fragments.
Dans le cloud, les partitions peuvent résider physiquement près des utilisateurs qui accèdent aux données.
Lorsque vous divisez un magasin de données en partitions, choisissez les données à placer dans chaque partition. Chaque fragment contient généralement des éléments regroupés par un ou plusieurs attributs de données. Ces attributs forment la clé de partition, parfois appelée clé de partition.
Le partitionnement organise physiquement les données. Lorsqu’une application stocke et récupère des données, la logique de partitionnement le dirige vers la partition appropriée. Vous pouvez implémenter cette logique dans le code d’accès aux données de l’application ou dans le système de stockage de données s’il prend en charge de manière transparente le partitionnement.
L’abstraction de l’emplacement physique des données dans la logique de partitionnement permet de contrôler les partitions qui contiennent les données. Vous pouvez également migrer des données entre des shards sans modifier la logique métier de l'application lorsque vous devez redistribuer ces données, par exemple lorsque les shards deviennent déséquilibrées. Le compromis est la surcharge d’accès aux données supplémentaire pour déterminer l’emplacement de chaque élément de données lors de la récupération.
Sélection de la clé de partition
La clé de partition est la décision de conception la plus critique dans un système partitionné. Pour modifier une clé de partition après l’avoir choisie, vous devez généralement migrer toutes les données vers une nouvelle disposition de partition, qui est une opération coûteuse et risquée sur un système actif. Prenez cette décision avec soin avant d’écrire du code.
Une clé de partition efficace est immuable, a une cardinalité élevée, distribue des données et charge uniformément, et s’aligne sur vos modèles de requête dominants afin que la plupart des requêtes soient résolues par rapport à une seule partition. Évitez d’augmenter de façon monotonique les valeurs (entiers autoincrément et horodatages séquentiels), les attributs de faible cardinalité (jeux booléens et petits enums) et les attributs volatiles qui changent fréquemment. Ces attributs entraînent des points chauds ou un déplacement coûteux des données entre fragments.
Si aucun attribut unique ne répond à ces critères, définissez une clé de partition composite en combinant deux attributs ou plus. Si les requêtes doivent récupérer des données par attributs qui ne font pas partie de la clé de partition, utilisez un modèle tel que le modèle table d’index pour fournir des recherches secondaires.
Pour plus d’informations sur la façon de choisir des clés de partition dans les services Azure, consultez les instructions de partitionnement des données et les stratégies de partitionnement des données.
Stratégies de partitionnement
Utilisez l'une des stratégies suivantes lorsque vous sélectionnez la clé de fragmentation et décidez comment distribuer les données entre fragments. Vous n’avez pas besoin d’une correspondance un-à-un entre les partitions et les serveurs qui les hébergent. Un seul serveur peut héberger plusieurs partitions.
Stratégie de partitionnement de recherche
Dans la stratégie de recherche, également appelée stratégie basée sur le répertoire, la logique de partitionnement implémente une carte qui route une demande de données vers la partition qui contient ces données à l’aide de la clé de partition. Dans une application mutualisée, vous pouvez stocker toutes les données d’un locataire ensemble dans une partition à l’aide de l’ID de locataire comme clé de partition. Plusieurs locataires peuvent partager la même partition, mais les données d’un seul locataire ne sont pas réparties sur plusieurs partitions. Le diagramme suivant montre le sharding des données des locataires effectué selon les ID de locataire.
Le mappage entre les valeurs de clé de partition et le stockage physique peut être direct, où chaque valeur de clé de partition est mappée à une partition physique. Une technique plus flexible est le partitionnement virtuel, où les valeurs de clé de partition sont mappées aux partitions virtuelles, et le système mappe ensuite ces partitions virtuelles à moins de partitions physiques. Une application localise les données à l’aide d’une valeur de clé de partition qui fait référence à une partition virtuelle, et le système mappe de manière transparente les partitions virtuelles aux partitions physiques. Le mappage entre une partition virtuelle et une partition physique peut changer sans nécessiter de modifications de code d’application.
Stratégie de partitionnement par plages
La stratégie basée sur les plages regroupe les éléments associés dans le même fragment et les ordonne par clé de fragment séquentielle. Cette stratégie prend en charge les applications qui récupèrent fréquemment des ensembles d’éléments à l’aide de requêtes de plage. Les requêtes de plage retournent un ensemble d’éléments de données pour une clé de partition qui se trouve dans une plage donnée.
Par exemple, si une application doit régulièrement rechercher toutes les commandes passées dans un mois donné, vous pouvez récupérer les données plus rapidement si vous stockez toutes les commandes d’un mois dans l’ordre de date et d’heure dans la même partition. Si vous stockez chaque commande dans une partition différente, l’application doit les extraire individuellement en effectuant un grand nombre de requêtes ponctuelles. Le diagramme suivant montre des ensembles séquentiels ou des plages de données stockées dans des fragments.
Dans cet exemple, la clé de partition est une clé composite qui contient le mois de commande comme élément le plus significatif, suivi du jour et de l'heure de la commande. Les nouvelles commandes sont triées de manière naturelle au fur et à mesure de leur création et de leur ajout à un shard.
Certains magasins de données prennent en charge les clés de partition en deux parties. Une clé de partition identifie la partition et une clé de ligne identifie de manière unique un élément dans la partition. La partition stocke généralement les données dans l’ordre de clé de ligne. Pour les éléments qui ont besoin de requêtes de plage et qui doivent être regroupés, vous pouvez utiliser une clé de fragment qui a la même valeur pour la clé de partition, mais une valeur unique pour la clé de ligne.
Stratégie de partitionnement basée sur le hachage
La stratégie basée sur le hachage réduit le risque de points chauds, qui sont des fragments recevant une charge disproportionnée. Cette stratégie répartit les données entre les partitions pour équilibrer la taille de chaque partition et la charge moyenne rencontrée par chaque partition. La logique de fragmentation détermine le fragment dans lequel stocker un élément sur la base du hachage d’un ou plusieurs attributs des données. La fonction de hachage choisie doit distribuer uniformément les données entre les fragments. Le diagramme suivant montre le partitionnement des données de locataire en fonction d’un hachage d’ID de locataire.
Pour comprendre l’avantage de la stratégie de hachage par rapport à d’autres stratégies de partitionnement, réfléchissez à la façon dont une application mutualisée qui inscrit de nouveaux locataires de manière séquentielle peut affecter les locataires à des partitions dans le magasin de données. Lorsque vous utilisez la stratégie de plage, les données des locataires 1 à n sont stockées dans la partition A, les données des locataires n+1 à m sont stockées dans la partition B et les plages de locataires ultérieures sont mappées aux partitions successives. Si les locataires les plus récemment inscrits sont également les plus actifs, la plupart des activités de données se produisent dans quelques fragments, ce qui peut entraîner des points chauds. En revanche, la stratégie de hachage alloue des locataires aux partitions en fonction d’un hachage de leur identifiant de locataire. Le hachage distribue généralement des locataires séquentiels sur différentes partitions, ce qui équilibre la charge. Le diagramme précédent montre cette approche pour les locataires 55 et 56.
Stratégie de partitionnement géographique
La stratégie géographique affecte des données à des partitions en fonction de l’origine géographique ou de la région de consommation prévue de ces données. Dans de nombreuses charges de travail, les utilisateurs et les données qu’ils génèrent sont concentrés dans des régions spécifiques. Les exigences réglementaires telles que les lois sur la résidence des données peuvent exiger que des données spécifiques restent dans une juridiction spécifique. Même sans pilotes réglementaires, le fait de placer des données proches des utilisateurs qui y accèdent le plus fréquemment réduit la latence réseau pour les lectures et les écritures.
Dans cette stratégie, vous dérivez la clé de partition d’un attribut géographique tel que le pays/la région de l’utilisateur, la région du centre de données d’origine ou un identificateur de locataire régional. Vous hébergez chaque shard ou l'épinglez à l'infrastructure au sein de cette limite géographique.
Par exemple, une application qui sert des clients en Amérique du Nord, en Europe et Asia-Pacific peut gérer trois groupes de partitions, un groupe dans chaque région Azure correspondante. Une application européenne qui sert uniquement les utilisateurs européens achemine une demande vers le fragment européen. Cette approche réduit la latence et répond aux exigences de résidence des données.
Le partitionnement géographique introduit le risque de distribution de données inégale. Si la plupart de vos utilisateurs résident dans une région, la partition de cette région comporte une part disproportionnée de la charge et du stockage. Vous pouvez combiner le partitionnement géographique avec une autre stratégie, telle que le hachage ou la recherche, au sein de chaque région pour répartir uniformément la charge sur plusieurs partitions à l’intérieur de la même limite géographique.
Avantages et considérations pour chaque stratégie
Les quatre stratégies de partitionnement présentent les avantages et considérations suivants :
La stratégie de recherche offre davantage de contrôle sur la configuration des partitions. Les partitions virtuelles réduisent l’impact du rééquilibrage, car vous pouvez ajouter de nouvelles partitions physiques pour équilibrer la charge de travail. Vous pouvez modifier le mappage entre une partition virtuelle et ses partitions physiques sans affecter le code d’application. La recherche des emplacements de shards ajoute une surcharge.
La stratégie d'intervalle est facile à implémenter et fonctionne bien avec les requêtes d'intervalle. Les requêtes d'intervalles peuvent récupérer plusieurs éléments de données à partir d'une seule partition lors d'une seule opération. La gestion des données est plus simple. Par exemple, vous pouvez planifier des mises à jour par fuseau horaire en fonction des modèles de charge locaux lorsque les utilisateurs de la même région partagent une partition. Toutefois, cette stratégie n’équilibre pas uniformément la charge entre les shards. Le rééquilibrage est difficile et peut ne pas résoudre la charge inégale lorsque la plupart des activités se concentrent sur les clés de partition adjacentes.
La stratégie de hachage offre une meilleure chance de distribution uniforme des données et de la charge. Vous pouvez router les requêtes directement à l’aide de la fonction de hachage sans conserver une carte. Le calcul du hachage entraîne une surdépense. Le rééquilibrage est difficile sans hachage cohérent.
La stratégie géographique répond aux exigences de résidence et de souveraineté des données que d’autres stratégies ne répondent pas intrinsèquement. Elle réduit la latence de lecture et d’écriture lorsque les utilisateurs accèdent aux données de leur région. Toutefois, le partitionnement géographique peut créer des données et un déséquilibre de charge significatifs lorsque les populations d’utilisateurs ne sont pas réparties uniformément entre les régions. Les requêtes qui s’étendent sur des régions, telles que les rapports globaux, doivent récupérer des données à partir de toutes les partitions géographiques et entraîner une latence plus élevée. Combinez le partitionnement géographique avec une autre stratégie au sein de chaque région lorsque vous avez besoin de la conformité et même de la distribution de charge.
La plupart des systèmes de partitionnement implémentent l’une de ces approches, mais vous devez également tenir compte des besoins métier de votre application et de ses modèles d’utilisation des données. Par exemple, dans une application multilocataire :
Vous pouvez partitionner des données en fonction de la charge de travail. Séparez les données des locataires hautement volatiles dans des partitions distinctes afin d’améliorer la vitesse d’accès aux données pour les autres locataires.
Vous pouvez partitionner des données en fonction de l’emplacement du locataire. Prenez les données de locataire dans une région géographique spécifique hors connexion pour la sauvegarde et la maintenance pendant les heures creuses de cette région, tandis que les données de locataire dans d’autres régions restent en ligne pendant leurs heures d’ouverture.
Attribuez aux locataires à forte valeur leurs propres fragments dédiés et peu chargés. Les locataires à valeur inférieure peuvent partager des fragments plus denses.
Stockez des données pour les locataires qui ont besoin d’une isolation et d’une confidentialité de données fortes sur des serveurs distincts.
Opérations de mise à l’échelle et de déplacement des données pour chaque stratégie
Chaque stratégie de partitionnement offre différentes fonctionnalités et niveaux de complexité pour gérer la scalabilité, la scalabilité vers l'extérieur, le déplacement des données et le maintien de l'état.
La stratégie de recherche permet l'extension et le déplacement des données au niveau utilisateur, que ce soit en ligne ou hors ligne. Pour déplacer des données :
Suspendez une partie ou l’ensemble de l’activité utilisateur, généralement pendant les périodes creuses.
Déplacez les données vers la nouvelle partition virtuelle ou la partition physique.
Mettez à jour les mappages.
Invalidez ou actualisez les caches qui contiennent ces données.
Reprendre l’activité de l’utilisateur.
Vous pouvez souvent gérer cette opération de manière centralisée. La stratégie de recherche nécessite que l’état soit optimisé pour la mise en cache et convivial pour les répliques.
La stratégie d’intervalle limite les opérations de mise à l’échelle et de déplacement des données, car vous devez fractionner et fusionner des données sur des fragments, généralement pendant qu’une partie ou l’ensemble du magasin de données est hors ligne. Lorsque vous déplacez des données pour rééquilibrer les fragments, il se peut que vous n'éliminiez pas la charge de travail inégale si la plupart des activités se concentrent sur des clés de fragment adjacentes ou des identificateurs de données dans la même plage. La stratégie de plage peut également nécessiter un état pour mapper des plages à des partitions physiques.
La stratégie de hachage complique la mise à l’échelle et les opérations de déplacement des données. Les clés de partition sont des hachages des clés de partition ou des identificateurs de données. Avec une fonction de hachage standard, par exemple
hash(key) mod N, l’ajout ou la suppression d’une partition réaffecte la plupart des clés et déclenche une migration de données à grande échelle. Le hachage cohérent réduit cet impact en organisant l’espace de hachage de sorte que seule une petite fraction de clés se déplace lorsque le nombre de partitions change. La stratégie de hachage ne nécessite pas de maintenance d’un état de mappage distinct.La stratégie géographique lie directement les opérations de mise à l’échelle à l’approvisionnement d’infrastructures régionales. L’ajout de la capacité dans une région ne permet pas de soulager la charge dans une autre région. Les exigences réglementaires qui imposent le partitionnement géographique peuvent également restreindre le déplacement des données entre les limites géographiques. Dans chaque région, la scalabilité utilise la stratégie secondaire qui répartit les données entre les shards de cette région.
Problèmes et considérations
Tenez compte des points suivants lorsque vous décidez comment implémenter ce modèle :
Utilisez le sharding en complément d’autres formes de partitionnement, telles que le partitionnement vertical et le partitionnement fonctionnel. Par exemple, une partition unique peut contenir des entités partitionnées verticalement, et vous pouvez implémenter une partition fonctionnelle en tant que partitions multiples. Pour plus d’informations, consultez Le partitionnement horizontal, vertical et fonctionnel des données.
Conservez les fragments équilibrés afin qu’ils puissent tous gérer le même volume d’entrée/sortie (E/S). Le déséquilibrage des données s’accumule au fil du temps lorsque les enregistrements sont insérés et supprimés, ce qui crée des zones chaudes. Prévoyez de rééquilibrer régulièrement.
Le rééquilibrage déplace les données entre les shards et provoque souvent une interruption ou un débit réduit. Pour rééquilibrer moins fréquemment, utilisez des partitions virtuelles. Mappez de nombreuses partitions logiques sur un nombre réduit de fragments physiques. Lorsqu’une partition est surchargée, redistribuez ses partitions virtuelles à de nouvelles partitions physiques sans réinscrire l’intégralité du jeu de données. Azure Cosmos DB utilise cette approche pour dissocier le schéma de partition de l’infrastructure physique.
Préférez de nombreux petits fragments plutôt que quelques grands. Les partitions plus petites migrent plus rapidement, équilibrent la charge plus uniformément et offrent une plus grande flexibilité pour la redistribution des données.
Utilisez des données stables pour la clé de partition. Si la clé de partition change, vous devrez peut-être déplacer l’élément de données correspondant entre les partitions, ce qui augmente la surcharge d’opération de mise à jour. Évitez de baser la clé de partition sur des informations potentiellement volatiles. Choisissez des attributs qui sont invariants ou forment naturellement une clé.
Assurez-vous que les clés de partition sont uniques. Par exemple, évitez d’utiliser les champs incrémentés automatiquement comme clé de fragment. Dans certains systèmes, les champs autoincrémentés ne peuvent pas se coordonner entre les shards, ce qui peut entraîner des éléments dans différents shards ayant la même clé de shard.
Note
Les valeurs autoincrémentées dans d’autres champs qui ne sont pas des clés de fragmentation peuvent également entraîner des problèmes. Par exemple, si vous utilisez des champs autoincrémentés pour générer des ID uniques, deux éléments différents dans des fragments différents peuvent se voir attribuer le même ID.
Partitionner les données pour prendre en charge les requêtes les plus fréquemment effectuées. Vous ne pouvez peut-être pas concevoir une clé de découpage qui corresponde aux exigences de chaque requête sur les données. Si nécessaire, créez des tables d’index secondaires pour prendre en charge les requêtes qui récupèrent des données par attributs qui ne font pas partie de la clé de partition. Pour plus d’informations, consultez le modèle de table d’index.
Concevez votre clé de fragmentation et votre modèle de données pour que la plupart des opérations soient limitées à un seul fragment. Les requêtes qui accèdent à une seule partition sont plus efficaces que les requêtes qui récupèrent des données à partir de plusieurs partitions. Dénormalisez vos données pour conserver les entités associées qui sont couramment interrogées ensemble, telles que les clients et leurs commandes, dans la même partition pour réduire le nombre de lectures distinctes.
Les requêtes inter-shard ajoutent une latence, une consommation de ressources et une complexité. Lorsqu’une application doit récupérer des données à partir de plusieurs partitions, utilisez des requêtes de ventilateur parallèles qui s’exécutent sur chaque partition simultanément et agrègent les résultats. Même avec parallélisme, la partition la plus lente détermine la latence globale.
Conseil / Astuce
Si une entité d’une partition fait référence à une entité dans une autre partition, incluez la clé de partition pour la deuxième entité dans le cadre du schéma pour la première entité. Cette approche peut améliorer les performances des requêtes faisant référence à des données associées sur des fragments.
Reconsidérez votre clé de fragmentation ou la pertinence du partitionnement pour vos besoins si votre charge de travail nécessite une forte intégrité transactionnelle entre les limites de fragments. Les transactions entre fragments présentent des défis. Les protocoles de coordination distribuée, tels que la validation en deux phases, ajoutent la latence, introduisent des modes d’échec et réduisent le débit. La plupart des systèmes partitionnés évitent les transactions distribuées et adoptent plutôt la cohérence éventuelle. Dans ce modèle, chaque partition est mise à jour indépendamment et l’application gère les incohérences temporaires.
Assurez-vous que les ressources disponibles pour chaque nœud de stockage de partitions peuvent gérer les exigences de scalabilité en termes de taille et de débit des données. Pour plus d’informations, consultez stratégies de partitionnement des données.
Envisagez de répliquer les données de référence pour tous les shards. Si une requête sur une partition fait également référence à des données statiques ou en déplacement lent, ajoutez ces données à la partition. L’application peut ensuite extraire toutes les données de la requête sans effectuer un aller-retour vers un magasin de données distinct.
Note
Si les données de référence contenues dans plusieurs partitions changent, le système doit synchroniser ces modifications sur toutes les partitions. Un certain degré d’incohérence peut se produire pendant l’exécution de cette synchronisation. Concevez vos applications pour tolérer cette incohérence.
Les systèmes partitionnés multiplient la charge opérationnelle. Planifiez ces préoccupations :
Surveillance : Vous devez agréger des métriques et des journaux sur tous les fragments pour obtenir une vue complète de l'état de santé du système.
Sauvegarde et restauration : Vous devez sauvegarder chaque partition indépendamment et concevoir des procédures de restauration pour maintenir la cohérence entre partitions. Une restauration ponctuelle d'un shard peut créer des incohérences avec d'autres shards.
Modifications de schéma : Vous devez coordonner les modifications DDL (Data Definition Language) sur chaque partition.
Vous pouvez implémenter ces tâches à l’aide de scripts ou d’autres solutions d’automatisation.
Vous pouvez géolocaliser des shards pour placer leurs données près des instances d’application qui les utilisent. Cette approche peut améliorer les performances, mais elle nécessite une planification supplémentaire pour les opérations qui doivent accéder à différents fragments dans plusieurs localisations.
Quand utiliser ce modèle
Conseil / Astuce
Avant de concevoir une couche de partitionnement personnalisée, déterminez les responsabilités de partitionnement que votre plateforme de données gère déjà. Certains services gèrent complètement le partitionnement. Par exemple, Azure Cosmos DB distribue les données entre les partitions physiques, gère les fractionnements et route les requêtes sans intervention de l’application. D’autres services gèrent partiellement le partitionnement. Par exemple, Azure SQL Database fournit des outils de base de données élastiques pour la gestion des cartes de partitions et le routage dépendant des données, mais vous concevez la clé de partition et gérez les opérations de fractionnement. Utilisez le modèle de partitionnement lorsque vous générez et utilisez vous-même la logique de partitionnement.
Utilisez ce modèle dans les situations suivantes :
Le volume total de données dépasse la capacité de stockage d’une seule instance de base de données, et aucune option de mise à l’échelle verticale ne résout l’insuffisance.
Le débit de transaction ou la concurrence des requêtes dépasse ce qu’une seule instance peut supporter, et les réplicas en lecture seuls ne résolvent pas le goulot d’étranglement, car la charge d’écriture est également élevée.
Note
Le partitionnement améliore les performances et l’extensibilité d’un système, et peut également améliorer la disponibilité. Un échec dans une partition n’empêche pas nécessairement une application d’accéder aux données dans d’autres partitions. Et un opérateur peut effectuer une maintenance ou une récupération d’une partition sans rendre toutes les données indisponibles. Pour plus d’informations, consultez les instructions de partitionnement des données.
Les exigences réglementaires ou de conformité imposent que des sous-ensembles de données spécifiques résident dans des juridictions géographiques spécifiques, et qu’aucun déploiement à une seule région ne peut répondre à toutes les exigences.
Les locataires distincts ou les segments de clients nécessitent une isolation des données physiques pour des raisons de sécurité, de performances ou contractuelles.
Dans les scénarios comme ceux-ci, le modèle de partitionnement est parfois appliqué au-delà des magasins de données traditionnels. Par exemple, un système de gestion de zone DNS peut être partitionné par l’équipe, l’environnement ou la région pour réduire le rayon d’explosion des modifications DNS et établir des limites de propriété claires. Dans ce contexte, la motivation principale est la segmentation opérationnelle plutôt que l’extensibilité. Pour plus d’informations, consultez Partitionnement des zones DNS privées.
Le partitionnement introduit une complexité substantielle et permanente dans votre architecture de données. Cette complexité affecte le développement, les opérations, les tests, la conception des requêtes et la récupération des défaillances pour la durée de vie du système.
Ce modèle peut ne pas convenir lorsque :
Votre volume de données et votre débit correspondent à une seule instance de base de données, même avec une croissance prévue. La mise à l’échelle verticale préserve la simplicité des requêtes et l’intégrité transactionnelle.
Votre goulot d’étranglement est le volume de lecture, pas le volume d’écriture ni la capacité de stockage. Les répliques en lecture et les niveaux de cache peuvent décharger le trafic de lecture sans la complexité des requêtes entre segments introduite par le partitionnement.
Votre moteur de base de données prend en charge le partitionnement au niveau de la table qui répond à vos besoins en matière de performances. Le partitionnement au sein d’une seule instance ne nécessite pas plusieurs serveurs ou logique de routage.
Vos modèles de requête dominants nécessitent des jointures inter-entités, des transactions multientités ou des agrégations de jeux de données complètes. Le partitionnement rend ces opérations coûteuses, et la surcharge des requêtes fan-out et la coordination distribuée peuvent dépasser les avantages de la mise à l’échelle.
Conception de la charge de travail
Évaluez comment utiliser le modèle de partitionnement dans la conception d’une charge de travail pour répondre aux objectifs et principes abordés dans les piliers Azure Well-Architected Framework. Le tableau suivant fournit des conseils sur la façon dont ce modèle prend en charge les objectifs de chaque pilier.
| Pilier | Comment ce modèle soutient les objectifs des piliers. |
|---|---|
| Les décisions de conception de fiabilité aident votre charge de travail à devenir résiliente au dysfonctionnement et à s’assurer qu’elle se rétablit dans un état entièrement opérationnel après une défaillance. | Les données et le traitement sont isolés sur la partition, de sorte qu’un dysfonctionnement dans une partition reste isolé à cette partition. - Partitionnement des données - RE :07 Autopréservation |
| L’optimisation des coûts se concentre sur le maintien et l’amélioration du retour sur investissement de votre charge de travail. | Un système qui met en œuvre la fragmentation bénéficie souvent de l’utilisation de plusieurs instances de ressources de calcul ou de stockage moins coûteuses plutôt que d’une seule ressource plus coûteuse. Dans de nombreux cas, cette configuration peut vous faire économiser de l’argent. - CO :07 Coûts composants |
| L’efficacité des performances permet à votre charge de travail de répondre efficacement aux demandes par le biais d’optimisations de la mise à l’échelle, des données et du code. | Lorsque vous utilisez le partitionnement dans votre stratégie de mise à l’échelle, les données et le traitement sont isolés de chaque partition, de sorte que les demandes ne concurrencent que les ressources au sein de leur partition affectée. Vous pouvez également utiliser le partitionnement pour optimiser en fonction de la géographie. - PE :05 Mise à l’échelle et partitionnement - PE :08 Performance des données |
Si ce modèle introduit des compromis au sein d’un pilier, considérez-les contre les objectifs des autres piliers.
Exemple
Considérez un site web qui expose une vaste collection d’informations sur les livres publiés dans le monde entier. Le nombre de livres possibles catalogés dans cette charge de travail et les modèles de requête et d’utilisation classiques dépassent ce qu’une base de données relationnelle unique peut gérer. L’architecte de charge de travail décide de partitionner les données entre plusieurs instances de base de données à l’aide de l’ISBN statique des livres comme clé de partition. Plus précisément, l’architecte utilise le chiffre de vérification (0 - 10) de l’ISBN, qui fournit 11 partitions logiques possibles avec une distribution de données assez équilibrée.
Pour commencer, l'architecte place les 11 shards logiques dans trois bases de données de shards physiques. Dans cette approche de partition virtuelle, de nombreuses partitions logiques sont mappées à moins de nœuds physiques. L’architecte utilise l’approche de partitionnement de recherche et stocke le mappage clé-à-serveur dans une base de données de carte de partitions.
Azure App Service est désigné comme un site web de catalogue de livres. Il se connecte à plusieurs instances SQL Database et à une instance Azure AI Search. L’une des bases de données est étiquetée comme base de données ShardMap. Il inclut un exemple de table qui reflète une partie de la table de mappage, qui est répertoriée plus loin dans cet article. La table comprend trois instances de bases de données de partitions : bookdbshard0, bookdbshard1 et bookdbshard2. Les autres bases de données incluent des exemples identiques de listes de tables sous celles-ci. Les tables incluent Books, LibraryOfCongressCatalog et un indicateur d’autres tables. La recherche IA est utilisée pour la navigation à facettes et la recherche de site. L’identité managée est associée à App Service.
Carte de partitions de recherche
La base de données de carte de partitions contient la table et les données de carte de partitions suivantes.
SELECT ShardKey, DatabaseServer
FROM BookDataShardMap
| ShardKey | DatabaseServer |
|----------|----------------|
| 0 | bookdbshard0 |
| 1 | bookdbshard0 |
| 2 | bookdbshard0 |
| 3 | bookdbshard1 |
| 4 | bookdbshard1 |
| 5 | bookdbshard1 |
| 6 | bookdbshard2 |
| 7 | bookdbshard2 |
| 8 | bookdbshard2 |
| 9 | bookdbshard0 |
| 10 | bookdbshard1 |
Exemple de code de site web : accès à une seule partition
Le site web ne sait pas combien de bases de données de partitions physiques existent (trois dans ce cas) ou la logique qui mappe une clé de partition à une instance de base de données. Il sait uniquement que le chiffre de vérification de l’ISBN d’un livre est la clé de partition. Le site web dispose d’un accès en lecture seule à la base de données de carte de partitions et d'un accès en lecture-écriture à toutes les bases de données de partition. Dans cet exemple, le site web utilise l'identité gérée par le système pour l'autorisation, ce qui permet de garder les secrets hors des chaînes de connexion pour son hôte Azure App Service.
Le site web est configuré avec les chaînes de connexion suivantes dans un appsettings.json fichier, comme illustré dans cet exemple, ou via les paramètres d’application App Service.
{
...
"ConnectionStrings": {
"ShardMapDb": "Data Source=tcp:<database-server-name>.database.windows.net,1433;Initial Catalog=ShardMap;Authentication=Active Directory Default;App=Book Site v1.5a",
"BookDbFragment": "Data Source=tcp:SHARD.database.windows.net,1433;Initial Catalog=Books;Authentication=Active Directory Default;App=Book Site v1.5a"
},
...
}
Le code suivant montre comment le site web exécute une requête de mise à jour sur le pool de partitions de base de données de la charge de travail.
...
// All data for this book is stored in a shard based on the book's ISBN check digit,
// which is converted to an integer 0 - 10 (special value 'X' becomes 10).
int isbnCheckDigit = book.Isbn.CheckDigitAsInt;
// Establish a pooled connection to the database shard for this specific book.
using (SqlConnection sqlConn = await shardedDatabaseConnections.OpenShardConnectionForKeyAsync(key: isbnCheckDigit, cancellationToken))
{
// Update the book's Library of Congress catalog information.
SqlCommand cmd = sqlConn.CreateCommand();
cmd.CommandText = @"UPDATE LibraryOfCongressCatalog
SET ControlNumber = @lccn,
...
Classification = @lcc
WHERE BookID = @bookId";
cmd.Parameters.AddWithValue("@lccn", book.LibraryOfCongress.Lccn);
...
cmd.Parameters.AddWithValue("@lcc", book.LibraryOfCongress.Lcc);
cmd.Parameters.AddWithValue("@bookId", book.Id);
await cmd.ExecuteNonQueryAsync(cancellationToken);
}
...
Dans l’exemple de code précédent, s’il book.Isbn s’agissait de 978-8-1130-1024-6, il isbnCheckDigit doit être 6. L’appel OpenShardConnectionForKeyAsync(6) est généralement implémenté à l’aide d’une approche cache-aside. Si les informations de partition mises en cache pour la clé de partition 6 ne sont pas disponibles, la méthode interroge la base de données de carte de partitions identifiée par la ShardMapDb chaîne de connexion. La méthode récupère la valeur bookdbshard2 à partir du cache de l'application ou de la base de données de fragments et l’utilise pour remplacer SHARD dans la chaîne de connexion BookDbFragment. La méthode établit ou rétablit une connexion mise en pool vers bookdbshard2.database.windows.net, l'ouvre ensuite et la retourne au code appelant. Le code met ensuite à jour l’enregistrement existant sur cette instance de base de données.
Exemple de code de site web : accès à plusieurs partitions
Dans le cas rare où le site nécessite une requête inter-partitions directe, l’application effectue une requête parallèle en éventail sur toutes les partitions.
...
// Retrieve all shard keys.
var shardKeys = shardedDatabaseConnections.GetAllShardKeys();
// Run the query in a fan-out style against each shard in the shard list.
Parallel.ForEachAsync(shardKeys, async (shardKey, cancellationToken) =>
{
using (SqlConnection sqlConn = await shardedDatabaseConnections.OpenShardConnectionForKeyAsync(key: shardKey, cancellationToken))
{
SqlCommand cmd = sqlConn.CreateCommand();
cmd.CommandText = @"SELECT ...
FROM ...
WHERE ...";
SqlDataReader reader = await cmd.ExecuteReaderAsync(cancellationToken);
while (await reader.ReadAsync(cancellationToken))
{
// Collect the results into a thread-safe data structure.
}
reader.Close();
}
});
...
En guise d’alternative aux requêtes entre partitions, cette charge de travail peut utiliser un index géré en externe dans Recherche d’IA Azure pour la recherche de sites ou la navigation par facettes.
Ajouter des instances de shard
L’équipe de charge de travail sait que si le catalogue de données ou son utilisation simultanée augmente considérablement, il peut nécessiter plus de trois instances de base de données. L'équipe de charge de travail ne s'attend pas à ajouter dynamiquement des serveurs de base de données et accepte une interruption de service lorsqu'un nouveau shard est mis en ligne. Pour activer une nouvelle instance de shard, ils doivent déplacer des données des shards existants dans le nouveau shard et mettre à jour la table de carte de shards. Avec cette approche assez statique, l'application peut mettre en cache en toute confiance le mappage de la base de données des clés de partition dans le code du site web.
La logique de clé de partition dans cet exemple a une limite supérieure de 11 partitions physiques. Si l’équipe de charge de travail détermine par le biais de l’estimation de charge qu’elle nécessite finalement plus de 11 instances de base de données, elle doit apporter une modification invasive à la logique de clé de partition. Cette modification implique une planification minutieuse des modifications de code et de la migration des données vers la nouvelle logique clé.
Fonctionnalité SDK
Au lieu d’écrire du code personnalisé pour la gestion des partitions et le routage des requêtes vers des instances SQL Database, évaluez la bibliothèque cliente de base de données élastique. Cette bibliothèque prend en charge la gestion des cartes de partitions, le routage des requêtes dépendant des données et les requêtes interpartitions dans C# et Java.
Étape suivante
- Niveaux de cohérence dans Azure Cosmos DB : la distribution de données entre les partitions introduit des compromis de cohérence. Cet article décrit le spectre des modèles de cohérence, de forte à éventuelle, et leurs effets sur la disponibilité et la latence.
Ressources associées
- Partitionnement horizontal, vertical et fonctionnel des données : cet article décrit d’autres stratégies de partitionnement des données dans le cloud pour améliorer la scalabilité, réduire la contention et optimiser les performances.
- Modèle de table d’index : parfois, vous ne pouvez pas prendre en charge toutes les requêtes par le biais de la conception de la clé de partition seule. Une application peut utiliser le modèle Table d’index pour récupérer des données à partir d’un magasin de données volumineux en spécifiant une clé autre que la clé de partition.
- Modèle d’affichage matérialisé : pour maintenir les performances de certaines opérations de requête, vous pouvez créer des vues matérialisées qui agrègent et résument les données, en particulier si vous distribuez ces données entre des partitions.