2009-09-21 13 views
24

Estoy a cargo de desarrollar y mantener un grupo de aplicaciones web que se centran en datos similares. La arquitectura que decidí en ese momento era que cada aplicación tendría su propia base de datos y aplicación web raíz. Cada aplicación mantiene un grupo de conexión a su propia base de datos y una base de datos central para datos compartidos (inicios de sesión, etc.)Estrategia de grupo de conexión: bueno, malo o feo?

Un compañero de trabajo ha postulado que esta estrategia no se ampliará porque no habrá tantos grupos de conexiones diferentes escalable y que deberíamos refactorizar la base de datos para que todas las diferentes aplicaciones usen una única base de datos central y que cualquier modificación que pueda ser exclusiva de un sistema deba reflejarse desde esa única base de datos y luego utilizar un único grupo con tecnología de Tomcat. Él ha postulado que hay una gran cantidad de "metadatos" que van y vienen en la red para mantener un grupo de conexiones.

Mi entendimiento es que con el ajuste adecuado para utilizar solamente tantas conexiones como sea necesario a través de las diferentes piscinas (aplicaciones de bajo volumen cada vez menos conexiones, aplicaciones de alto volumen cada vez más, etc.) que el número de piscinas no lo hace En comparación con el número de conexiones o más formalmente, la diferencia en la sobrecarga requerida para mantener 3 grupos de 10 conexiones es insignificante en comparación con 1 grupo de 30 conexiones.

El razonamiento detrás de romper inicialmente los sistemas en un diseño de una aplicación de una sola base de datos es que probablemente habrá diferencias entre las aplicaciones y que cada sistema podría hacer modificaciones en el esquema según sea necesario. Del mismo modo, eliminó la posibilidad de que los datos del sistema se desbordaran a otras aplicaciones.

Desafortunadamente no hay un liderazgo fuerte en la empresa para tomar una decisión difícil. Aunque mi compañero de trabajo respalda sus preocupaciones solo con vaguedad, quiero asegurarme de que entiendo las ramificaciones de múltiples pequeñas bases de datos/conexiones frente a una gran base de datos/grupo de conexiones.

+0

No estoy de acuerdo con su compañero de trabajo. Si tiene n webapps, use n pools, incluso si usan el mismo servidor de base de datos. Esto te ofrece una mejor separación de preocupaciones, opciones de ajuste más finas, mejor aislamiento (si una aplicación web come todas las conexiones, ¿por qué debería afectar a la otra), etc. Además, realmente no veo por qué una agrupación única escalaría mejor? . Esto es IMO simplemente no es cierto. –

Respuesta

10

Su diseño original se basa en principios sólidos. Si ayuda a su caso, esta estrategia se conoce como horizontal partitioning or sharding. Proporciona:

1) Mayor escalabilidad, ya que cada fragmento puede vivir en hardware separado si es necesario.

2) Una mayor disponibilidad - debido a que el fallo de un solo fragmento no afecta los otros fragmentos

3) Mayor rendimiento - porque las tablas que se busca tener un menor número de filas y, por tanto, los índices más pequeñas que los rendimientos de búsquedas más rápidas.

La sugerencia de su colega lo traslada a un punto único de configuración de falla.

En cuanto a su pregunta sobre 3 grupos de conexiones de tamaño 10 vs 1 grupo de conexiones de tamaño 30, la mejor manera de resolver ese debate es con un punto de referencia. Configure su aplicación en todos los sentidos, luego realice algunas pruebas de resistencia con ab (Apache Benchmark) y vea de qué manera funciona mejor. Sospecho que no habrá una diferencia significativa, pero hago el punto de referencia para probarlo.

+0

Gracias! No soy DBA, desafortunadamente, pero no se me había ocurrido que esta configuración era en realidad una estratagema fragmentada. Desafortunadamente, a menos que haya más magias para permitir que MySQL actúe como un entorno fragmentado de forma automática, las diferentes bases de datos sirven también como distinciones comerciales, lo que dificultaría la correcta evaluación comparativa. Tampoco son los poderes que probablemente nos den el tiempo para ejecutar puntos de referencia. : \ – Drew

2

Excelente pregunta. No sé qué camino es mejor, pero ¿ha considerado diseñar el código de tal manera que pueda cambiar de una estrategia a la otra con la menor cantidad de dolor posible? Tal vez algunos objetos proxy de base de datos livianos se podrían usar para enmascarar esta decisión de diseño del código de nivel superior. Por si acaso.

+0

Podría ser factible. No soy DBA, desafortunadamente. Sé que MySQL tiene un manejo nativo de sharding, pero no sé mucho al respecto. Si intentáramos hacer esto programáticamente, necesitaríamos agregar columnas discriminatorias y toda esa diversión. Afortunadamente, solo ciertas tablas los necesitarían. Lo mantendré en la parte posterior de la cabeza si los problemas reales de rendimiento se ciernen sobre sus cabezas. – Drew

1

La base de datos y los gastos generales, 1 grupo con 30 conexiones y 3 grupos con 10 conexiones son prácticamente iguales, suponiendo que la carga sea la misma en ambos casos.

En cuanto a la aplicación, la diferencia entre tener todos los datos en un solo punto (por ejemplo, la capa de servicio) frente a tener un punto de acceso por aplicación puede ser bastante drástica; tanto en términos de rendimiento como de facilidad de implementación/mantenimiento (considere tener que usar caché distribuida, por ejemplo).

+0

La memoria caché distribuida es un punto que no había considerado. Sin embargo, en la actualidad, todo el código de persistencia se abstrae en una sola biblioteca que se incluye en cada aplicación web, dejando solo la configuración para que se haga por aplicación web. La intención, sin embargo, siempre ha sido reemplazar este código de persistencia (construido en JDBC) con un ORM más completo. ORM se adapta muy bien a muchos de nuestros datos. Los problemas de tiempo nos impidieron usarlo desde el principio. – Drew

4

Si tiene una única base de datos y dos grupos de conexiones, con 5 conexiones cada una, tiene 10 conexiones a la base de datos. Si tiene 5 grupos de conexiones con 2 conexiones cada uno, tiene 10 conexiones a la base de datos. Al final, tienes 10 conexiones a la base de datos. La base de datos no tiene idea de que existe tu grupo, no hay conciencia.

Cualquier metadato intercambiado entre el grupo y el DB va a suceder en cada conexión. Cuando se inicia la conexión, cuando se desconecta la conexión, etc. Por lo tanto, si tiene 10 conexiones, este tráfico ocurrirá 10 veces (como mínimo, suponiendo que todos se mantengan sanos durante toda la vida útil del grupo). Esto sucederá ya sea que tenga 1 grupo o 10 grupos.

En cuanto a "1 DB por aplicación", si no está hablando con una instancia separada de la base de datos para cada DB, entonces básicamente no importa.

Si tiene un servidor de bases de datos que aloja 5 bases de datos y tiene conexiones con cada base de datos (por ejemplo, 2 conexiones), consumirá más gastos generales y más memoria que la misma base de datos. Pero esa sobrecarga es marginal en el mejor de los casos, y absolutamente insignificante en máquinas modernas con memorias intermedias de datos de tamaño GB. Más allá de cierto punto, lo único que le importa a la base de datos es mapear y copiar páginas de datos del disco a la RAM y viceversa.

Si tenía una gran tabla redundante duplicada a través de los DB, entonces eso podría ser un desperdicio.

Finalmente, cuando uso la palabra "base de datos", me refiero a la entidad lógica que el servidor utiliza para unir las tablas. Por ejemplo, a Oracle realmente le gusta tener una "base de datos" por servidor, dividida en "esquemas". Postgres tiene varios DB, cada uno de los cuales puede tener esquemas. Pero, en cualquier caso, todos los servidores modernos tienen límites lógicos de datos que pueden usar. Solo estoy usando la palabra "base de datos" aquí.

Por lo tanto, mientras conecte con una sola instancia del servidor de bases de datos para todas sus aplicaciones, las agrupaciones de conexiones no importan en absoluto, ya que el servidor compartirá toda la memoria y recursos a través de los clientes según sea necesario.

+0

Todos estamos accediendo a un único servidor de base de datos que ejecuta Mysql con los datos de cada aplicación en una "base de datos" (estamos usando el término de la misma manera) mientras que otra base de datos central almacena datos compartidos. Por su cuenta, mi comprensión es correcta. :) – Drew

0

Bueno, excelente pregunta, pero no es fácil de discutir el uso de un enfoque de varias bases de datos (A) o el grande (B):

  1. Depende de la propia base de datos. Oracle, p. se comporta de manera diferente a Sybase ASE con respecto a la estrategia LOG (y, por lo tanto, LOCK). Es posible que sea mejor utilizar varias bases de datos pequeñas & para mantener baja la tasa de contención de bloqueo, si hay muchas escrituras en paralelo y el DB está utilizando una estrategia de bloqueo pesimista (Sybase).
  2. Si el espacio de tablas de las bases de datos pequeñas no está distribuido en varios discos, podría ser mejor utilizar una gran base de datos para usar la memoria (buffer/caché) solo para uno. Creo que esto rara vez es el caso.
  3. El uso de (A) es mejor por una razón diferente al rendimiento. Puede mover una base de datos de puntos calientes en un hardware diferente (más nuevo/más rápido) cuando sea necesario sin tocar las otras bases de datos. En mi empresa anterior, este enfoque siempre fue más barato que la variante (B) (sin nuevas licencias).

Personalmente prefiero (A) por razón 3.

+0

Principalmente somos una tienda de código abierto y para la base de datos utilizamos MySQL con InnoDB. ¿Esto cambia tu respuesta? – Drew

0

El diseño, la arquitectura, los planes y las grandes ideas son insuficientes cuando no hay sentido común o una simple matemática detrás de. Algo más de práctica y/o experiencia ayuda ... Aquí hay un cálculo simple de por qué 10 grupos con 5 conexiones no es lo mismo que 1 grupo con 50 conexiones: cada grupo está configurado con mín. & conexiones máx. Abiertas, de hecho es que usualmente usará (99% del tiempo) 50% del número mínimo (2-3 en caso de 5 min) si usa más que este grupo está mal configurado ya que está abriendo y cerrando conexiones todo el tiempo (costoso) ... entonces 10 grupos con 5 conexiones mín. cada uno = 50 conexiones abiertas ... significan 50 conexiones TCP; 50 conexiones JDBC encima de ellas ... (¿ha depurado una conexión JDBC? Se sorprenderá de cuánto metadatos fluyen en ambos sentidos ...) Si tenemos 1 grupo (que sirve la misma infraestructura anterior) podemos configurar el mínimo a 30 simple porque podrá equilibrar los extras de manera más eficiente ... esto significa 20 conexiones JDBS menos. No sé ustedes, pero para mí esto es mucho ... El diablo está en los detalles: las 2-3 conexiones que deja en cada grupo para asegurarse de que no se abren/cierran todo el tiempo. .. Ni siquiera quiero entrar en la sobrecarga de la administración de 10 grupos ... (No quiero mantener 10 piscinas cada una tan diferente que la otra, ¿verdad?) Ahora que me enciendes si fuera yo, "envolvería" el DB (la fuente de datos) con una sola aplicación (capa de servicio ¿alguien?) que proporcionaría servicios de diferencia (REST/SOAP/WS/JSON - elige tu veneno) y mis aplicaciones se ganarían ' ni siquiera sé sobre JDBC, TCP etc. etc. oh, espere que google lo tenga - GAE ...

+0

Afortunadamente, el servidor de aplicaciones (Tomcat en este caso) mantiene los grupos de conexiones y nos brinda controles de ajuste. Además, no sigo tus cálculos. Suponiendo que todos los grupos están sintonizados correctamente, si estamos usando el 50%, ¿por qué los 10 grupos necesitarían 50 conexiones abiertas? ¿No solo necesitaría 20-30? – Drew

Cuestiones relacionadas