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?
la source
Réponses:
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:
la source
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.
la source
Scalability is all about how you manage global state and data inter-dependence.
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.
la source
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…
la source
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.
la source