La fonctionnalité de DB est-elle un obstacle à l'évolutivité?

17

Je ne pourrai peut-être pas donner le bon titre à la question. Mais le voici,

Nous développons un portail financier pour la gestion de patrimoine. Nous nous attendons à ce que plus de 10000 clients utilisent l'application. Le portail calcule diverses analyses de performance basées sur l'analyse technique de la bourse.

Nous avons développé de nombreuses fonctionnalités via des procédures stockées, des fonctions définies par l'utilisateur, des déclencheurs, etc. via Database. Nous pensions que nous pouvions gagner énormément en performances en faisant des trucs directement dans la base de données que grâce au code C #. Et nous avons en fait obtenu une énorme amélioration des performances.

Lorsque j'ai essayé de me vanter de la réussite de notre CTO, il a remis en question ma décision d'avoir implémenté des fonctionnalités dans la base de données plutôt que dans le code. Selon lui, ces applications souffrent de problèmes d'évolutivité. Selon ses mots: «De nos jours, les choses sont conservées en mémoire / cache. Les données en cluster sont difficiles à gérer au fil du temps. Facebook, Google n'ont rien dans la base de données. C'est l'ère des serveurs légers et des clients lourds. La base de données est utilisée uniquement pour stocker des données simples et la fonctionnalité doit être complètement découplée de la base de données. "

Pouvez-vous me donner quelques suggestions pour savoir si ce qu'il dit est juste? Comment s'y prendre pour l'architecte d'une telle application?

Estefany Velez
la source
3
"et nous avons en fait obtenu une énorme amélioration des performances" par rapport à quoi? Lorsque vous n'avez jamais implémenté la même fonctionnalité sur un client, comment le savez-vous?
Doc Brown
3
Je pense que ce sera l'habituel - cela dépend du projet, de la mise en œuvre des données et des compétences de l'équipe.
Daniel Iankov
1
Vous devriez demander à votre CTO ce qui lui fait penser que les bases de données n'utilisent pas ses techniques préférées et pourquoi les procédures stockées ne sont pas qualifiées de «code».
Blrfl
3
Facebook et Google ont des problèmes à une échelle entièrement différente de la plupart des applications - il peut y avoir un problème avec la quantité de données que vous devez traiter en termes de données du marché, mais les bases de données SQL contemporaines sont conçues pour faire face à des quantités stupéfiantes de données.
Murph
1
Je penserais probablement de la même manière que votre CTO, à moins que vous ne puissiez prouver que les performances de sa solution étaient insuffisantes et qu'il n'y avait pas d'autres moyens de la gérer. Les procédures stockées, en particulier lorsque leur nombre augmente, entraînent une barrière énorme pour passer à d'autres bases de données si nécessaire ... ne peut pas prédire l'avenir.
Rig

Réponses:

23

En bref, je serais d'accord avec votre CTO. Vous avez probablement gagné en performances au détriment de l'évolutivité (si ces termes prêtent à confusion, je vais clarifier ci-dessous). Mes deux plus gros soucis seraient la maintenabilité et le manque d'options pour évoluer horizontalement (en supposant que vous en aurez besoin).

Proximité des données: prenons du recul. Il y a de bonnes raisons de pousser du code dans une base de données. Je dirais que le plus important serait la proximité des données - par exemple, si vous vous attendez à ce qu'un calcul renvoie une poignée de valeurs, mais ce sont des agrégations de millions d'enregistrements, envoyant les millions d'enregistrements (à la demande) sur le réseau à agréger ailleurs est extrêmement coûteux et pourrait tuer facilement votre système. Cela dit, vous pouvez atteindre cette proximité des données par d'autres moyens, essentiellement en utilisant des caches ou des bases de données d'analyse où une partie de l'agrégation est effectuée en amont.

Performance du code dans la base de données:Les effets secondaires sur les performances, tels que la «mise en cache des plans d'exécution», sont plus difficiles à argumenter. Parfois, les plans d'exécution mis en cache peuvent être très négatifs si le mauvais plan d'exécution a été mis en cache. En fonction de votre SGBDR, vous pouvez tirer le meilleur parti de ceux-ci, mais vous n'obtiendrez pas beaucoup sur SQL paramétré, dans la plupart des cas (ces plans sont généralement mis en cache aussi). Je dirais également que la plupart des langages compilés ou JIT fonctionnent généralement mieux que leurs équivalents SQL (tels que T-SQL ou PL / SQL) pour les opérations de base et la programmation non relationnelle (manipulation de chaînes, boucles, etc.), vous ne le feriez donc pas ne perdez rien là-bas, si vous avez utilisé quelque chose comme Java ou C # pour faire le calcul des nombres. L'optimisation à grain fin est également assez difficile - sur la base de données, vous ' Nous sommes souvent coincés avec un arbre B générique (index) comme seule structure de données. Pour être juste, une analyse complète, y compris des choses comme des transactions plus longues, l'escalade des verrous, etc., pourrait remplir les livres.

Maintenabilité: SQL est un langage merveilleux pour ce qu'il a été conçu pour faire. Je ne suis pas sûr que ce soit un bon choix pour la logique d'application. La plupart des outils et des pratiques qui rendent nos vies supportables (TDD, refactoring, etc.) sont difficiles à appliquer à la programmation de bases de données.

Performance versus évolutivité:Pour clarifier ces termes, je veux dire ceci: la performance est la vitesse à laquelle vous vous attendez à ce qu'une seule demande passe par votre système (et revienne à l'utilisateur), pour le moment en supposant une faible charge. Cela sera souvent limité par des choses comme le nombre de couches physiques traversées, la façon dont ces couches sont optimisées, etc. L'évolutivité est la façon dont les performances changent avec l'augmentation du nombre d'utilisateurs / charge. Vous pouvez avoir des performances moyennes / faibles (disons, 5 secondes + pour une demande), mais une évolutivité impressionnante (capable de prendre en charge des millions d'utilisateurs). Dans votre cas, vous obtiendrez probablement de bonnes performances, mais votre évolutivité sera limitée par la taille d'un serveur que vous pouvez construire physiquement. À un moment donné, vous atteindrez cette limite et serez obligé de vous tourner vers des choses comme le partage, ce qui peut ne pas être possible selon la nature de l'application.

Optimisation prématurée: En fin de compte, je pense que vous avez fait l'erreur d'optimiser prématurément. Comme d'autres l'ont souligné, vous n'avez pas vraiment de mesures montrant comment les autres approches fonctionneraient. Eh bien, nous ne pouvons pas toujours construire des prototypes à grande échelle pour prouver ou réfuter une théorie ... Mais en général, j'hésiterais toujours à choisir une approche qui échange la maintenabilité (probablement la qualité la plus importante d'une application) pour la performance .

EDIT: Sur une note positive, la mise à l'échelle verticale peut s'étendre assez loin dans certains cas. Autant que je sache, SO a fonctionné sur un seul serveur pendant un certain temps. Je ne sais pas comment cela correspond à vos 10 000 utilisateurs (je suppose que cela dépend de la nature de ce qu'ils font dans votre système), mais cela vous donne une idée de ce qui peut être fait (en fait, il y a loin des exemples plus impressionnants, il se trouve que c'est un populaire que les gens peuvent facilement comprendre).

EDIT 2: Pour clarifier et commenter quelques points soulevés ailleurs:

  • Re: Cohérence atomique - La cohérence ACID pourrait bien être une exigence du système. Ce qui précède ne contredit pas vraiment cela, et vous devez vous rendre compte que la cohérence ACID ne vous oblige pas à exécuter toute votre logique métier à l'intérieur de la base de données. En déplaçant du code qui n'a pas besoin d'être présent dans la base de données, vous le contraignez à s'exécuter dans l'environnement physique du reste de la base de données - il est en concurrence pour les mêmes ressources matérielles que la partie de gestion des données réelle de votre base de données. En ce qui concerne la mise à l'échelle uniquement du code vers d'autres serveurs de base de données (mais pas les données réelles) - bien sûr, cela peut être possible , mais que gagnez-vous exactement ici, à part les coûts de licence supplémentaires dans la plupart des cas? Gardez les choses qui n'ont pas besoin d'être sur la base de données, hors de la base de données.
  • Re: Performances SQL / C # - puisque cela semble être un sujet d'intérêt, ajoutons un peu à la discussion. Vous pouvez certainement exécuter du code natif / Java / C # à l'intérieur des bases de données, mais pour autant que je sache, ce n'est pas ce qui a été discuté ici - nous comparons l'implémentation du code d'application typique dans quelque chose comme T-SQL à quelque chose comme C #. Il y a un certain nombre de problèmes qui ont été difficiles à résoudre avec le code relationnel dans le passé - par exemple, considérez le problème du "nombre maximal de connexions simultanées", où vous avez des enregistrements indiquant une connexion ou une déconnexion, et l'heure, et vous devez déterminer ce que le le nombre maximum d'utilisateurs connectés à un moment donné était. La solution la plus simple possible consiste à parcourir les enregistrements et à continuer à incrémenter / décrémenter un compteur lorsque vous rencontrez des connexions / déconnexions, et à garder une trace du maximum de cette valeur.mai, Je ne sais pas), le mieux que vous puissiez faire est un CURSEUR (les solutions purement relationnelles sont toutes sur des ordres de complexité différents, et tenter de le résoudre en utilisant une boucle while entraîne des performances moins bonnes). Dans ce cas, oui, la solution C # est en fait plus rapide que ce que vous pouvez obtenir en T-SQL, point. Cela peut sembler farfelu, mais ce problème peut facilement se manifester dans les systèmes financiers, si vous travaillez avec des lignes représentant des changements relatifs et devez calculer des agrégations fenêtrées sur ceux-ci. Les invocations de proc stockées ont également tendance à être plus coûteuses - invoquez un SP trivial un million de fois et voyez comment cela se compare à l'appel d'une fonction C #. J'ai fait allusion à quelques autres exemples ci-dessus - je n'ai encore rencontré personne implémenter une table de hachage appropriée en T-SQL (une qui donne en fait certains avantages), alors que c'est assez facile à faire en C #. Encore une fois, il y a des choses dans lesquelles les bases de données sont géniales et des choses qui ne le sont pas. Tout comme je ne voudrais pas faire de JOIN, SUM et GROUP BY en C #, je ne veux rien écrire de particulièrement gourmand en CPU dans T-SQL.
Daniel B
la source
L'une des raisons pour lesquelles j'ai tendance à pousser les fonctionnalités vers la base de données est qu'il est beaucoup moins bogué que le code au niveau de l'application. SQL est déclaratif et ne souffre pas de la plupart des problèmes rencontrés par les langages impératifs.
wobbily_col
En ce qui concerne la maintenabilité, l'utilisation de la maintenabilité de SQL Server Data Tools est un jeu d'enfant. En fait, pour toute base de données non triviale (une contenant plus de 5 tables), je considérerais cela comme une exigence.
Jon49
4

L'évolutivité n'a rien à voir avec l'emplacement des données ou la façon dont le calcul se déroule. L'évolutivité concerne la façon dont vous gérez l'interdépendance globale des états et des données. Si votre architecture est alambiquée avec toutes sortes d'interdépendances de données, peu importe où vous placez le code pour transformer ces données. Les interdépendances vont forcer votre main et réduire tout potentiel d'échelle. Si, d'autre part, vos données sont faiblement couplées et qu'il y a très peu ou pas d'état global, alors encore une fois, peu importe où se déroule le calcul. La mise à l'échelle des choses va être beaucoup plus facile.

Je ne sais pas où votre CTO obtient ses informations sur les problèmes d'évolutivité, mais d'après ce que vous avez dit, il ne semble pas qu'il ait de vraies raisons de remettre en question la décision architecturale actuelle autre que les tendances de la mode logicielle. Baser les décisions architecturales sur de telles tendances est généralement une mauvaise idée.

davidk01
la source
1
+1 pourScalability is all about how you manage global state and data inter-dependence.
Estefany Velez
2

Et nous avons en fait obtenu une énorme amélioration des performances.

Je pense que vous devez définir un référence de performances et commencer à construire votre prototype en premier. Garder toute la logique dans la base de données est une vieille école (à mon humble avis, je n'ai rien contre) pour gérer l'architecture client-serveur. Bien qu'il présente ses avantages, il existe un certain nombre d'inconvénients qui doivent être pris en compte.

L'approche habituelle pour ce type d'applications vendables se fait via SOA . Parce qu'à long terme, c'est le moyen le plus simple d'ajouter de nouvelles applications client à votre projet.

Vous avez également mentionné les déclencheurs. L'utilisation du déclencheur pourrait devenir un gros problème plus tard dans le cycle de vie du support de l'application, je ferais double attention avec elle, et j'essaierais même de sauter son utilisation.

Yusubov
la source
2

Votre CTO est 100% erroné.

Vos numéros financiers DOIVENT s'additionner en tout temps. Cela signifie que vous avez besoin d' ACID et de bases de données relationnelles pour assurer cela. Les gains de performances de NoSql DB sont généralement au détriment de l' ACID et c'est OK pour Google et Facebook MAIS PAS pour un système contenant des données financières.

Dire que C # fonctionne mieux que le code SQL est aussi idiot…

Crétins
la source
Dire que C # fonctionne mieux que le code SQL est aussi une idiotie… - Mais vous ne niez pas que le code C # est plus évolutif, n'est-ce pas?
Jim G.
Non, ce n'est pas plus évolutif, car ce n'est pas là où se trouve le col de la bouteille, je peux mettre à l'échelle le code Sql (pas les données) horizontalement aussi facilement que je peux mettre à l'échelle horizontalement le code C #.
Morons
@JimG. Juste pour clarifier: "Je peux mettre à l'échelle le code SQL (et non les données) horizontalement aussi facilement que je peux mettre à l'échelle horizontalement le code C #" s'il a été conçu pour le faire ... Comme C #, il doit être conçu pour être mis à l'échelle. Vous ne pouvez pas simplement dire que les échelles C # sont meilleures, c'est une question de planification et non de langage.
Morons
@JimG .: Les logiciels qui ne sont pas à l'échelle peuvent être écrits dans n'importe quelle langue, y compris C #. Toute base de données digne de ce nom peut avoir des procédures stockées écrites dans des langages autres que leur implémentation SQL native, et les personnes qui se déchaînent avec NoSQL dans des situations qui nécessitent ACID finissent généralement par réinventer la plupart des roues qui ont été bien mis en œuvre par le SGBD.
Blrfl
@Morons: Je pense que nous sommes d'accord. J'étais en fait amalgamant les données avec « SQL ». Il est beaucoup plus coûteux de faire évoluer la base de données.
Jim G.
2

Chaque fois que quelqu'un mentionne l'évolutivité et Google / Facebook / Twitter / etc, c'est un hareng rouge. À moins que vous ne fournissiez essentiellement le même service, ce qui fonctionne pour eux peut ne pas vous convenir. En général, si vous pouvez passer d'une seule machine à un cluster de huit machines, vous avez probablement couvert toutes vos bases. Sauf si vous avez une exigence commerciale difficile pour afficher 20 millions de pages vues par jour, ne vous inquiétez pas de l'hyper-évolutivité. Faites ce qui a du sens pour les besoins réels de votre application et craignez de passer à l'échelle lorsque cela devient évident. Et n'oubliez pas que la plupart des serveurs de bases de données peuvent également être mis en cluster, donc ce n'est pas parce qu'ils sont tous dans une seule base de données qu'ils sont sur un seul serveur.

TMN
la source