¿Tener funcionalidad en DB es un obstáculo para la escalabilidad?

17

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?

Estefany Velez
fuente
3
"¿y en realidad obtuvimos un gran aumento de rendimiento" en comparación con qué? Cuando nunca implementó la misma funcionalidad en un cliente, ¿cómo lo sabe?
Doc Brown
3
Creo que será lo habitual: depende del proyecto, la implementación de los datos y la habilidad del equipo.
Daniel Iankov
1
Debe preguntarle a su CTO qué le hace pensar que las bases de datos no están usando sus técnicas preferidas y por qué los procedimientos almacenados no califican como "código".
Blrfl
3
Facebook y Google tienen problemas en una escala completamente diferente a la mayoría de las aplicaciones: puede haber un problema con la cantidad de datos con los que tiene que lidiar en términos de datos del mercado, pero las bases de datos SQL contemporáneas están diseñadas para hacer frente a cantidades asombrosas de datos.
Murph
1
Probablemente piense lo mismo que su CTO, a menos que pueda probar que el rendimiento de su solución fue insuficiente y no había otras formas de administrarlo. Los procedimientos almacenados, especialmente cuando sus números aumentan, causan una tremenda barrera para pasar a otros DB si es necesario ... no se puede predecir el futuro.
Aparejo

Respuestas:

23

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:

  • Re: Consistencia atómica: la consistencia de ACID puede ser un requisito del sistema. Lo anterior realmente no argumenta en contra de eso, y debe darse cuenta de que la consistencia de ACID no requiere que ejecute toda su lógica de negocios dentro de la base de datos. Al mover el código que no necesita estar allí en la base de datos, lo está restringiendo para que se ejecute en el entorno físico del resto de la base de datos: está compitiendo por los mismos recursos de hardware que la porción de administración de datos real de su base de datos. En cuanto a escalar solo el código a otros servidores de base de datos (pero no los datos reales), claro, esto puede ser posible , pero ¿qué está ganando exactamente aquí, aparte de los costos de licencia adicionales en la mayoría de los casos? Mantenga las cosas que no necesitan estar en la base de datos, fuera de la base de datos.
  • Re: rendimiento de SQL / C #: dado que esto parece ser un tema de interés, agreguemos un poco a la discusión. Ciertamente, puede ejecutar código nativo / Java / C # dentro de las bases de datos, pero que yo sepa, eso no es lo que se discutió aquí: estamos comparando la implementación de código de aplicación típico en algo como T-SQL versus algo como C #. Hay una serie de problemas que han sido difíciles de resolver con el código relacional en el pasado, por ejemplo, considere el problema de "inicio de sesión máximo concurrente", donde tiene registros que indican un inicio de sesión o cierre de sesión, y el tiempo, y necesita averiguar qué el número máximo de usuarios conectados en cualquier momento fue. La solución más simple posible es iterar a través de los registros y seguir incrementando / decrementando un contador a medida que encuentre inicios de sesión / salidas de sesión, y realizar un seguimiento del máximo de este valor.mayo, No sé), lo mejor que puede hacer es un CURSOR (las soluciones puramente relacionales están en diferentes órdenes de complejidad, e intentar resolverlo usando un bucle while resulta en un peor rendimiento). En este caso, sí, la solución C # es realmente más rápida de lo que puede lograr en T-SQL, punto. Eso puede parecer exagerado, pero este problema puede manifestarse fácilmente en los sistemas financieros, si está trabajando con filas que representan cambios relativos y necesita calcular agregaciones en ventanas en ellas. Las invocaciones de proceso almacenadas también tienden a ser más caras: invoque un SP trivial un millón de veces y vea cómo eso se compara con llamar a una función C #. Insinué algunos otros ejemplos anteriores: aún no he encontrado a nadie que implemente una tabla hash adecuada en T-SQL (una que realmente brinde algunos beneficios), mientras que es bastante fácil de hacer en C #. Una vez más, hay cosas en las que los DB son geniales, y cosas en las que no lo son tanto. Al igual que no quisiera estar haciendo JOINs, SUMs y GROUP BYs en C #, no quiero escribir nada particularmente intensivo de CPU en T-SQL.
Daniel B
fuente
Una de las razones por las que tiendo a impulsar la funcionalidad a la base de datos es que es mucho menos defectuoso que el código de nivel de aplicación. SQL es declarativo y no sufre muchos de los problemas que tienen los lenguajes imperativos.
wobbily_col
En cuanto a la capacidad de mantenimiento, el uso de herramientas de datos de SQL Server es muy sencillo. De hecho, para cualquier base de datos no trivial (una con más de 5 tablas) lo consideraría un requisito.
Jon49
4

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.

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

Y en realidad obtuvimos un gran aumento de rendimiento.

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.

Yusubov
fuente
2

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 ...

Imbéciles
fuente
Decir que C # funciona mejor que el código SQL también es idiotez ... - Pero no estás negando que el código C # sea más escalable, ¿correcto?
Jim G.
No, no es más escalable, porque no es donde está el cuello de la botella, puedo escalar el código SQL (no los datos) horizontalmente tan fácilmente como puedo escalar horizontalmente el código C #.
Morons
@JimG. Solo para aclarar, "puedo escalar el código SQL (no los datos) horizontalmente tan fácilmente como puedo escalar horizontalmente el código C #" si fue diseñado para hacerlo ... Igual que C # debe ser diseñado para escalar. No se puede simplemente decir que C # escala mejor, es una cuestión de planificación, no del lenguaje.
Morons
@JimG .: El software que no escala puede escribirse en cualquier idioma, incluido C #. Cualquier base de datos que valga la pena puede tener procedimientos almacenados escritos en otros idiomas además de su implementación nativa de SQL-ish, y las personas que se vuelven locas con NoSQL en situaciones que requieren ACID generalmente terminan reinventando la mayoría de las ruedas que han sido bien implementado por el DBMS.
Blrfl
@ Morons: creo que estamos de acuerdo. Yo estaba en el hecho de confundir con los datos "SQL". Es mucho más costoso escalar la base de datos.
Jim G.
2

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.

TMN
fuente