Es posible que no pueda dar el título correcto a la pregunta. Pero aquí está
Estamos desarrollando un portal financiero para la gestión del patrimonio. Esperamos que más de 10000 clientes usen la aplicación. El portal calcula varios análisis de rendimiento basados en el análisis técnico del mercado de valores.
Desarrollamos gran parte de la funcionalidad a través de procedimientos almacenados, funciones definidas por el usuario, disparadores, etc. a través de la base de datos. Pensamos que podemos obtener un gran aumento del rendimiento haciendo cosas directamente en la base de datos que a través del código C #. Y en realidad obtuvimos un gran aumento de rendimiento.
Cuando traté de presumir sobre el logro de nuestro CTO, él cuestionó mi decisión de tener la funcionalidad implementada en la base de datos en lugar del código. Según él, tales aplicaciones sufren problemas de escalabilidad. En sus palabras "Hoy en día las cosas se guardan en la memoria / caché. Los datos agrupados son difíciles de administrar con el tiempo. Facebook, Google no tienen nada en la base de datos. Es la era de los servidores delgados y los clientes gruesos. DB se usa solo para almacenar datos simples y la funcionalidad debe estar completamente desacoplada de la base de datos ".
¿Pueden ustedes, por favor, darme algunas sugerencias sobre si lo que dice es correcto? ¿Cómo ir sobre arquitecto tal aplicación?
fuente
Respuestas:
En resumen, estaría de acuerdo con su CTO. Probablemente haya ganado algo de rendimiento a expensas de la escalabilidad (si esos términos son confusos, lo aclararé a continuación). Mis dos mayores preocupaciones serían la mantenibilidad y la falta de opciones para escalar horizontalmente (suponiendo que va a necesitar eso).
Proximidad a los datos: demos un paso atrás. Hay algunas buenas razones para insertar código en una base de datos. Yo diría que el más grande sería la proximidad a los datos, por ejemplo, si espera que un cálculo arroje un puñado de valores, pero estas son agregaciones de millones de registros, enviando los millones de registros (a pedido) la red que se agregará en otro lugar es muy derrochadora y podría matar fácilmente su sistema. Dicho esto, puede lograr esta proximidad de datos de otras maneras, esencialmente usando cachés o bases de datos de análisis donde parte de la agregación se realiza por adelantado.
Rendimiento del código en la base de datos:Los efectos de rendimiento secundarios, como el "almacenamiento en caché de los planes de ejecución" son más difíciles de argumentar. A veces, los planes de ejecución en caché pueden ser algo muy negativo, si se almacenó en caché el plan de ejecución incorrecto. Dependiendo de su RDBMS, puede obtener el máximo provecho de estos, pero no obtendrá mucho sobre SQL parametrizado, en la mayoría de los casos (esos planes generalmente también se almacenan en caché). También diría que la mayoría de los lenguajes compilados o JIT generalmente funcionan mejor que sus equivalentes SQL (como T-SQL o PL / SQL) para operaciones básicas y programación no relacional (manipulación de cadenas, bucles, etc.), por lo que no No perderás nada allí, si usaste algo como Java o C # para hacer el cálculo de números. La optimización de grano fino también es bastante difícil: en la base de datos, usted ' a menudo se queda atascado con un árbol B genérico (índice) como su única estructura de datos. Para ser justos, un análisis completo, que incluye cosas como transacciones más largas, escalada de bloqueo, etc., podría llenar libros.
Mantenibilidad: SQL es un lenguaje maravilloso para lo que fue diseñado para hacer. No estoy seguro de que sea una buena opción para la lógica de la aplicación. La mayoría de las herramientas y prácticas que hacen soportable nuestra vida (TDD, refactorización, etc.) son difíciles de aplicar a la programación de bases de datos.
Rendimiento versus escalabilidad:Para aclarar estos términos, quiero decir esto: el rendimiento es lo rápido que esperaría que una sola solicitud pasara por su sistema (y volviera al usuario), por el momento suponiendo una carga baja. Esto a menudo estará limitado por cosas como la cantidad de capas físicas que atraviesa, qué tan bien optimizadas están esas capas, etc. La escalabilidad es cómo cambia el rendimiento con el aumento del número de usuarios / carga. Es posible que tenga un rendimiento medio / bajo (por ejemplo, 5 segundos + para una solicitud), pero una escalabilidad increíble (capaz de admitir millones de usuarios). En su caso, probablemente experimentará un buen rendimiento, pero su escalabilidad estará limitada por el tamaño de un servidor que pueda construir físicamente. En algún momento, alcanzará ese límite y se verá obligado a recurrir a cosas como el fragmentación, que puede no ser factible dependiendo de la naturaleza de la aplicación.
Optimización prematura: en última instancia, creo que ha cometido el error de optimizar prematuramente. Como otros han señalado, realmente no tiene mediciones que muestren cómo funcionarían los otros enfoques. Bueno, no siempre podemos construir prototipos a gran escala para probar o refutar una teoría ... Pero, en general, siempre dudaría en elegir un enfoque que intercambie la capacidad de mantenimiento (probablemente la calidad más importante de una aplicación) por el rendimiento .
EDITAR: en una nota positiva, la escala vertical puede extenderse bastante en algunos casos. Hasta donde yo sé, SO se ejecutó en un solo servidor durante bastante tiempo. No estoy seguro de cómo coincide con sus 10 000 usuarios (supongo que dependerá de la naturaleza de lo que estén haciendo en su sistema), pero le da una idea de lo que se puede hacer (en realidad, hay mucho ejemplos más impresionantes, esto resulta ser uno popular que la gente puede entender fácilmente).
EDITAR 2: Para aclarar y comentar algunas cosas planteadas en otro lugar:
fuente
La escalabilidad no tiene nada que ver con dónde se encuentran los datos o cómo ocurre el cálculo. La escalabilidad se trata de cómo gestiona el estado global y la interdependencia de datos. Si su arquitectura está enrevesada con todo tipo de interdependencias de datos, no importa dónde coloque el código para transformar esos datos. Las interdependencias van a forzar su mano y reducir cualquier potencial para escalar cosas. Si, por otro lado, sus datos están débilmente acoplados y hay muy poco o ningún estado global, una vez más, no importa dónde ocurra el cálculo. Escalar cosas va a ser mucho más fácil.
No estoy seguro de dónde está obteniendo su CTO su información sobre los problemas de escalabilidad, pero por lo que ha dicho, no parece que tenga ningún motivo real para cuestionar la decisión arquitectónica actual, aparte de las tendencias de la moda del software. Basar las decisiones arquitectónicas en tales tendencias suele ser una mala idea.
fuente
Scalability is all about how you manage global state and data inter-dependence.
Creo que debe establecer un punto de referencia de rendimiento y comenzar a construir su prototipo primero. Mantener toda la lógica en DB es una vieja escuela (en mi opinión, no tengo nada en contra) de tratar con la arquitectura cliente-servidor. Aunque tiene sus ventajas, hay varios inconvenientes que deben considerarse.
El enfoque habitual para este tipo de aplicaciones vendibles se realiza a través de SOA . Porque a largo plazo, esta es la forma más fácil de agregar nuevas aplicaciones cliente a su proyecto.
También has mencionado los desencadenantes. El uso del disparador podría convertirse en un gran problema más adelante en el ciclo de vida de soporte de la aplicación, sería doblemente cuidadoso con él e incluso trataría de omitir su uso.
fuente
Su CTO es 100% incorrecto.
Sus números financieros DEBEN sumarse en todo momento. Eso significa que necesita ACID y DB relacional son el mejor lugar para asegurar eso. Las ganancias de rendimiento de NoSql DB generalmente son a expensas de ACID y eso está bien para Google y Facebook, PERO NO para un sistema que contiene datos financieros.
Decir que C # funciona mejor que el código SQL también es idiotez ...
fuente
Cada vez que alguien menciona la escalabilidad y Google / Facebook / Twitter / etc., es una pista falsa. A menos que esté proporcionando esencialmente el mismo servicio, lo que funciona para ellos puede no ser apropiado para usted. En general, si puede escalar de una sola máquina a un grupo de ocho máquinas, probablemente haya cubierto todas sus bases. A menos que tenga un requisito comercial difícil de servir 20 millones de visitas al día, no se preocupe por la hiper-escala. Haga lo que tenga sentido para los requisitos reales de su aplicación , y preocúpese por escalar cuando sea obvio que necesita hacerlo. Y no olvide que la mayoría de los servidores de bases de datos también se pueden agrupar, por lo que el hecho de que esté todo en una base de datos no significa que esté en un solo servidor.
fuente