Nous avons une base de données d'entreprise à très grande échelle. Dans le cadre de notre modèle commercial, tous les utilisateurs Web accèdent à nos serveurs Web en même temps chaque mois, ce qui, à son tour, martèle notre boîte sql. Le trafic est très dense et continue de croître à mesure que l'entreprise grandit. l'optimisation sql proc a été effectuée et le matériel a déjà été étendu à un niveau très élevé.
Nous cherchons à partager la base de données maintenant pour nous assurer que nous pouvons gérer la croissance de l'entreprise et les charges futures.
Nous avons décidé quelles données particulières doivent être partagées. Il s'agit d'un sous-ensemble de notre base de données qui est très utilisé.
Cependant, ma question concerne les données non partagées qui sont communes / universelles. Un exemple de données comme celle-ci peut être une table d'inventaire par exemple ou éventuellement une table Employé, une table utilisateur, etc.
Je vois deux options pour gérer ces données communes / universelles:
1) conception 1 - Placer les données communes / universelles dans une base de données externe. Toutes les écritures auront lieu ici. Ces données seront ensuite répliquées dans chaque fragment, permettant à chaque fragment de lire ces données et de se joindre à ces données dans les procs t-sql.
2) conception 2 - Donnez à chaque fragment sa propre copie de toutes les données communes / universelles. Laissez chaque partition écrire localement dans ces tables et utilisez la réplication de fusion SQL pour mettre à jour / synchroniser ces données sur toutes les autres partitions.
préoccupations concernant la conception # 1
1) Problèmes transactionnels: si vous avez une situation dans laquelle vous devez écrire ou mettre à jour des données dans un fragment puis écrire / mettre à jour une table commune / universelle dans 1 proc stocké par exemple, vous ne pourrez plus le faire facilement. Les données existent désormais sur des instances et bases de données SQL séparées. Vous devrez peut-être impliquer MS DTS pour voir si vous pouvez encapsuler ces écritures dans une transaction car elles se trouvent dans une base de données distincte. Les performances sont une préoccupation ici et des réécritures possibles peuvent être impliquées pour les procs qui écrivent sur des données fragmentées et communes.
2) une perte d'intégrité référentielle. Impossible de réaliser l'intégrité référentielle croisée de la base de données.
3) Recodage de grandes zones du système afin qu'il sache écrire des données communes dans la nouvelle base de données universelle mais lire les données communes des fragments.
4). augmentation des déplacements dans la base de données. Comme n ° 1 ci-dessus, lorsque vous rencontrez une situation dans laquelle vous devez mettre à jour des données fragmentées et des données communes, vous allez effectuer plusieurs allers-retours pour y parvenir, car les données sont désormais dans des bases de données distinctes. Une certaine latence du réseau ici, mais je ne suis pas autant préoccupé par ce problème que ci-dessus 3.
préoccupations concernant la conception # 2
Dans la conception # 2, chaque fragment obtient sa propre instance de toutes les données communes / universelles. Cela signifie que tout le code qui joint ou met à jour les données communes continue de fonctionner / s'exécuter comme il le fait aujourd'hui. Il y a très peu de recodage / réécriture nécessaire de la part de l'équipe de développement. Cependant, cette conception dépend complètement de la réplication de fusion pour garder les données synchronisées sur tous les fragments. les dbas sont hautement qualifiés et sont très préoccupés par le fait que la réplication de fusion ne puisse pas gérer cela et que la réplication de fusion échoue, que la récupération à partir de cet échec ne soit pas importante et puisse nous affecter très négativement.
Je suis curieux de savoir si quelqu'un a opté pour l'option de conception # 2. Je suis également curieux de savoir si je néglige une troisième ou une quatrième option de conception que je ne vois pas.
Merci d'avance.
la source
Réponses:
Votre question était centrée sur ceci:
Lorsque vous effectuez un partitionnement et que vous disposez de données que tous les fragments doivent voir, vous devez classer ces données avec quelques attributs:
Cela change-t-il fréquemment? Dans vos exemples, vous avez répertorié l'inventaire, l'employé et l'utilisateur. Généralement, l'inventaire change très rapidement, mais les enregistrements Employés ne changent que périodiquement (par exemple, quelques centaines de mises à jour par jour).
Combien de retard chaque fragment peut-il tolérer?Même si l'inventaire peut être en constante évolution, vous pouvez généralement tolérer une grande quantité de retard (minutes ou même heures) sur une table comme celle-ci. Si vous vendez des articles uniques avec une quantité très limitée que vous ne pouvez jamais réapprovisionner (pensez aux œuvres d'art originales), vous ne divisez pas ces données du tout - vous interrogez uniquement la base de données d'origine. Cependant, dans la plupart des magasins en ligne, vous ne vendez pas tous les articles tous les jours, et vous allez de toute façon réapprovisionner rapidement les choses, de sorte que vous n'avez pas vraiment besoin d'un inventaire à la milliseconde près. En fait, dans la plupart des cas, vous n'avez besoin que d'un indicateur In-Stock égal à 0 ou 1, et un processus central met à jour cet indicateur. De cette façon, vous n'avez pas à pousser chaque décompte d'élément vers le haut / vers le bas pour chaque fragment. Les données des employés ou utilisateurs, d'autre part,
Serez-vous joignant des tables partagées aux tables non partagées? Idéalement, la réponse est non - vous devez effectuer deux requêtes distinctes pour obtenir les données, puis les joindre du côté de l'application. Cela devient beaucoup plus difficile du point de vue d'une application, mais cela vous donne la possibilité d'obtenir les données les plus récentes de chaque source.
Ces données sont-elles originales ou copiées?Une autre façon de penser à cette question: que devez-vous sauvegarder et à quelle fréquence? Généralement, dans un environnement de partitionnement à volume élevé, vous souhaitez que les sauvegardes soient aussi rapides et aussi petites que possible. (Après tout, vous devez protéger chaque nœud et vous voulez que tous les fragments basculent vers DR au même moment - ne pas avoir certains fragments avec des données plus récentes que d'autres.) Cela signifie que les données fragmentées et les données non les données partagées doivent se trouver dans des bases de données complètement distinctes, même si elles se trouvent sur le même serveur. Il se peut que j'aie besoin de sauvegardes constantes du journal des transactions de mes données fragmentées (originales), mais je n'ai peut-être pas du tout besoin de sauvegarder les données non partagées. Il est probablement plus facile pour moi de simplement actualiser ma table Employés ou Utilisateurs à partir de la seule source de vérité plutôt que de la sauvegarder sur chaque fragment. Si toutes mes données sont dans une seule base de données, cependant,
Maintenant, à propos de vos préoccupations:
"Les problèmes de transaction ... vous ne pourrez plus le faire facilement." Correct. Dans des scénarios fragmentés, jetez le concept d'une transaction par la fenêtre. Cela empire également - pour les données fragmentées, vous pouvez avoir un fragment en ligne et un autre fragment temporairement en raison d'un basculement ou d'un redémarrage d'instance de cluster. Vous devez planifier la défaillance de n'importe quelle partie du système, à tout moment.
"Impossible de faire de l'intégrité référentielle entre bases de données." Correct. Lorsque vous divisez une seule table sur plusieurs serveurs, vous enfilez votre pantalon et dites au serveur de base de données que vous prenez le relais pour des tâches difficiles comme les sauvegardes ponctuelles, les relations entre les tables et la combinaison des données de Plusieurs sources. C'est sur vous et votre code maintenant.
"Recodage de grandes zones du système afin qu'il sache écrire des données communes dans la nouvelle base de données universelle mais lire les données communes des fragments." Corrigez ici aussi. Il n'y a pas de bouton facile pour cela, mais une fois que vous avez intégré cela dans l'application, vous pouvez évoluer comme un fou. Je dirais que la façon la plus simple de le faire est de diviser les connexions de l'application par des lectures .
"Augmentation des voyages de base de données." - Oui, si vous divisez les données en plusieurs serveurs, l'application devra davantage atteindre le réseau. La clé est d'implémenter également la mise en cache afin que certaines de ces données puissent être stockées dans des systèmes moins coûteux, à plus haut débit et sans verrouillage. La requête la plus rapide est celle que vous ne faites jamais.
J'ai également présenté plus d'avantages et d'inconvénients à la division des bases de données multi-locataires ici , telles que l'optimisation des performances sur les fragments individuels, les différentes stratégies de sauvegarde / récupération par partition et les défis de déploiement de schéma.
la source
À un niveau élevé, la manière typique de partager (ou de partitionner horizontalement) des données consiste à partager les tables transactionnelles et à répliquer les tables de niveau maître. Comme la plupart des solutions technologiques, cela résout bien sûr un ensemble de problèmes et crée un nouvel ensemble de problèmes ... mais nous y sommes tous habitués, n'est-ce pas? ;-)
Je me demande cependant si SQLServer est votre meilleure solution. La charge de travail ressemble-t-elle plus à OLTP ou plus à DW / BI?
À la vôtre, Dave Sisk
la source
Une 3ème option possible. En utilisant le partage relationnel (au lieu du partage de boîte noire), vous devriez être en mesure de partager et de distribuer l'intégralité de votre base de données. Parce qu'elle est construite à partir d'un modèle de données relationnel traditionnel, la base de données sait quelles données sont stockées sur quels serveurs et donc où les trouver, de sorte que toutes vos données peuvent être considérées comme «communes / universelles». Découvrez dbShards comme une possibilité de rendre le processus de partitionnement plus facile.
la source