Todos los proyectos con los que he tenido que lidiar hasta ahora solo han requerido una única base de datos en un solo servidor. Estoy interesado en aprender más sobre cómo los proyectos que necesitan escalar se mueven a múltiples bases de datos y / o servidores para ayudar a administrar la carga. Soy consciente de la alta escalabilidad , pero estoy particularmente interesado en algunos ejemplos de código o recursos adicionales donde podría leer más sobre el tema.
Por ejemplo:
- ¿Cómo se construyen las uniones entre dos tablas en múltiples bases de datos? (Un ejemplo de código aquí sería útil).
- ¿Existen estrategias especiales para rastrear qué tablas están en qué base de datos?
- ¿El código de la aplicación necesita saber que una o más bases de datos están distribuidas en varios servidores? Si no, ¿a qué nivel se filtran las solicitudes?
- ¿Cuándo es el momento de ir más allá de una configuración de 1 base de datos / 1 servidor? ¿Qué tan común es tener que hacer esto?
Respuestas:
Ok, vamos a desglosarlo:
Esto es bastante sencillo. Los objetos SQL tienen desde una convención de nomenclatura de una a cuatro partes:
Servername.databasename.schemaname.tablename
Si todas sus tablas están en el mismo servidor en la misma base de datos, con el mismo propietario / esquema, puede ignorar las tres primeras partes y usar lo que está más acostumbrado a:
Si una de sus tablas está en una base de datos diferente y ambas usan el esquema predeterminado para sus bases de datos, simplemente agregue la base de datos a la segunda tabla:
Si se encuentra en una tercera base de datos diferente de cualquiera de las que está consultando, use ambos nombres de base de datos explícitamente:
Si termina utilizando diferentes esquemas y / o propietarios, puede agregarlos en:
Y, por último, si tiene mucho cuidado y tiene una muy buena razón, puede unirse a una tabla (generalmente pequeña) en otro servidor:
Combinaré estos dos porque van juntos. En general, casi siempre está bien comenzar con la suposición de que una base de datos de un servidor es suficiente hasta que sus limitaciones técnicas / comerciales / de diseño lo obliguen a usar más.
Entonces, para responder a su segunda pregunta primero, dado que generalmente tiene una razón para tener bases de datos separadas, debería ser bastante obvio saber el diseño de su sistema donde está algo.
En cuanto a cuándo / por qué es necesario ir más allá de una sola base de datos. Por lo general, es una combinación de reglas comerciales, políticas y / o razones técnicas.
Por ejemplo, donde trabajo tenemos 16 bases de datos repartidas en 4 servidores. Tenemos MainDB, ImageDB, referencetableDB, HighvolumeTransactionDB, ReportingDB, StagingDB, ProcessingDB, ArchiveDB, FinancialDB. Para dar algunos ejemplos de por qué son diferentes:
• ¿El código de la aplicación necesita saber que una o más bases de datos están distribuidas en múltiples servidores? Si no, ¿a qué nivel se filtran las solicitudes?
En un sentido amplio, probablemente lo hagan. Como mínimo, necesitan saber a qué servidor apuntan en la cadena de conexión de la base de datos. Procesamiento, Informes, Principal, etc.
A partir de ahí, necesitan un contexto de base de datos para ejecutar. En general, ese sería el más utilizado para la aplicación, tal vez incluso el original de la base de datos / un servidor días de la aplicación. PUEDE hacer que la aplicación cambie explícitamente el contexto de la base de datos en cada llamada, pero eso hace que sea muy difícil ajustar la base de datos sin cambiar la aplicación.
El enfoque habitual (o al menos MI habitual) es acceder siempre a través de una o quizás dos bases de datos principales.
Luego, cree vistas en otras bases de datos según sea necesario combinadas con la interfaz con la base de datos a través de procedimientos almacenados.
Entonces para ilustrar:
Supongamos que desea obtener la información demográfica, los datos de ventas y el saldo de crédito de un Cliente, y eso se distribuye en tres tablas originalmente todas en MainDB.
Entonces escribes una llamada desde tu aplicación:
Increíble. Sin embargo, ahora cada vez que cambiemos el nombre de una columna, o cambiemos el nombre / muevamos una tabla, debe actualizar el código de la aplicación. Entonces, en su lugar, hacemos dos cosas:
crear clientes, ventas, vistas de cuentas por cobrar (no usaría Select * pero estoy haciendo una demostración aquí)
Luego también creamos un procedimiento almacenado, spGetClientSalesAR
Y que tu aplicación llame así.
Ahora, siempre y cuando no cambie la interfaz en ese proceso almacenado, puedo hacer casi cualquier cosa que necesite hacer en la base de datos de back-end para escalar o escalar.
En el extremo, incluso podría hacer que mi viejo MainDB fuera solo un montón de procedimientos almacenados y vistas almacenadas de forma tal que debajo de esas vistas que creamos se veía así:
Y su aplicación nunca notaría la diferencia (suponiendo entregas rápidas y datos bien organizados, entre otras cosas).
Obviamente, eso es extremo y estaría mintiendo si dijera que todo fue planeado de esta manera, pero el uso de procedimientos / vistas almacenados, incluso si lo hace durante la refactorización, le permitirá mucha flexibilidad a medida que su aplicación crezca desde su humilde base de datos / servidor comenzando.
fuente
La forma principal en la que me he encontrado con múltiples servidores de bases de datos en el mundo web (dado que la pregunta está etiquetada como PHP) es configuraciones donde había una base de datos 'maestra' (escritura), y luego una o más bases de datos 'esclavas' replicadas (leídas) . Las escrituras de la base de datos se realizan contra la base de datos 'maestra'. El contenido de esa base de datos se replica en los servidores 'esclavos' en tiempo casi real. Las consultas, especialmente los informes intensivos, se ejecutan en una de las bases de datos 'esclavas' para transferir la carga a esos servidores. Tenga en cuenta que esa configuración particular es mejor para aplicaciones que tienen muchas lecturas, pero no mucha escritura. De ninguna manera es la única forma de organizar las cosas.
fuente
Ellos no están. Las bases de datos NoSQL no hacen "uniones" en absoluto, e incluso si pudiera hacer una unión SQL a través de servidores RDBMS, no desearía hacerlo si valora el rendimiento (consulte las falacias de la computación distribuida ).
En una base de datos relacional / SQL, la partición normalmente se realiza dentro de los límites de un único servidor / base de datos, utilizando diferentes archivos colocados en diferentes discos. Casi por definición, una solución de escala horizontal significa que todas las bases de datos tienen todas las tablas y usted tiene algún tipo de reflejo transaccional, replicación o solución personalizada de consistencia eventual para asegurarse de que todos los datos lleguen a donde se supone que deben hacerlo.
Si en realidad está dividiendo la base de datos de manera lógica y no solo física, entonces las asignaciones definidas en su DAL u ORM declararán qué tablas están en qué base de datos.
Las bases de datos NoSQL son una mezcla de soluciones de particionamiento. A veces son las "tablas" (o más comúnmente, "colecciones") las que se particionan. Otras veces son las "filas" (o "documentos"). En algunos casos, en realidad son las columnas , como en una base de datos orientada a columnas como HBase. Depende totalmente de la tecnología que esté utilizando. Lo único que todos tienen en común es que el motor mismo realiza un seguimiento de todo, por lo que todo lo que tiene que hacer es solicitar un documento o fila.
Eso, por supuesto, supone que en realidad está utilizando las funciones de fragmentación y no solo está creando un montón de bases de datos diferentes. Si estás haciendo lo último, entonces estás solo.
Si son bases de datos lógicas diferentes , sí. Si solo se distribuyen físicamente, entonces no, suponiendo que su base de datos específica sea compatible de forma nativa con sharding o que use una solución de equilibrio de carga (para bases de datos SQL). Suponiendo también que todas sus operaciones no tienen estado; si quieres una escala horizontal, tendrás que renunciar a ACID.
Es hora de que haya optimizado todo lo que pueda en un servidor y aún no pueda exprimir el rendimiento suficiente debido a las restricciones en la carga de E / S. Si tiene que hacer la pregunta, entonces es demasiado temprano.
Tenga en cuenta que los problemas de rendimiento en un producto RDBMS decente (Oracle, SQL Server) se deben con mayor frecuencia a un diseño deficiente, indexación deficiente, consultas deficientes, contención de bloqueo, etc. Estos productos pueden escalar verticalmente hasta un grado ridículo. De nuevo, debería considerar "ir más allá de una configuración de 1 base de datos / 1 servidor" cuando esté absolutamente seguro de que sus problemas de rendimiento se deben a limitaciones de hardware y no solo a un diseño / implementación deficiente.
O, supongo, otra razón por la que algunas personas cambian a bases de datos distribuidas es cuando no están preparadas para pagar mucho (o ningún) dinero en tarifas de licencia y quieren deshacerse de SQL como una opción consciente para cambiar el bajo costo por una mayor complejidad de la aplicación. Razón totalmente válida si eres un startup de software pero generalmente no es aplicable en el sector corporativo.
fuente
Existen tres tipos principales de configuraciones de replicación para bases de datos:
Ejemplo de maestro-esclavo: maestro MySQL + esclavos MySQL, MongoDB
Ejemplo maestro-maestro: CouchDB, Cassandra, Riak
Ejemplo de consenso: ScalienDB
...para nombrar unos pocos.
Estos tienen diferentes características. Las configuraciones maestro-esclavo permiten que los nodos esclavos alcancen al maestro a su velocidad máxima mientras atienden solicitudes de lectura muy rápidamente, mientras que el servidor maestro es responsable de la integridad de los datos. Debido a que todas las escrituras van al maestro, nunca hay contención de bloqueo porque un solo escritor relativamente lento está bloqueando a muchos lectores, pero por otro lado, los servidores esclavos son eventualmente consistentes y no obtienes las garantías de aislamiento de transacción que tendrías de leer solo del maestro. (lectura adicional; ACID vs BASE, niveles de aislamiento de transacción, replicación de base de datos, MVCC / aislamiento: instantánea, replicación transaccional)
Master-Master siempre permite escrituras, por lo que tendría múltiples autoridades sobre lo que es cierto. Esto puede o no ser un problema, dependiendo de lo que esté haciendo su aplicación, pero si escribe datos contradictorios, puede obtener múltiples resultados la próxima vez que lea esa clave / fila / columna que deberá fusionar con la lógica de la aplicación y guardar de nuevo en la base de datos. (lectura adicional: teorema CAP, replicación CouchDB, replicación Riak, hashing consistente, Bitcask & StormDB, Quorum- con MongoDB en división de red, estrategias de resolución de fusión)
Las bases de datos basadas en el consenso con replicación a través de nodos, como Scalien, siempre serían consistentes en las escrituras, pero a costa de intercambiar múltiples mensajes antes de ACK la escritura. Esto no es un gran problema si tiene un ethernet rápido y no necesita escribir en el disco antes de ACKing, lo cual no necesitará si su mínimo de tres servidores están en bastidores de servidores diferentes con fuentes de alimentación separadas (una muere; los otros dos se aseguran de que hayan guardado en el disco). (lectura adicional; PAXOS, PAXOS COMMIT, compromiso de dos fases con transacciones distribuidas, compromiso de tres fases)
Otras lecturas adicionales: (libro: 'Elementos de computación distribuida', relojes vectoriales, vectores de versión, vectores de matriz, relojes lógicos, algoritmo de panadería, relojes de árbol de intervalo, actores y programación reactiva y reactores, memoria transaccional de software, transactores, AKKA, Stact, falacias de computación distribuida, protocolos de chismes, extensiones de protocolo de chismes anti-entropía de Cassandra, tablas de hash distribuidas, documentos sobre la fusión de datos en un entorno distribuido, arquitectura ZooKeeper, presentación de InfoQ sobre "protocolo asincrónico", arquitectura HBase, papel MapReduce, papel Amazon Dynamo que comenzó todo el material NoSQL, colas, clustering de alta disponibilidad rabbitmq)
Espero haber pensado en algo :). También puedes seguirme en Twitter @henrikfeldt si quieres tuits sobre estas cosas.
fuente
Bien, aquí hay otro punto de vista sobre la escalabilidad.
Analicemos lo que significa que las cosas sean datos, lo que significa tener comportamiento y lo que significa tener lógica de aplicación.
Normalmente, cuando uno se aventura en la tierra de las aplicaciones empresariales y similares, uno estaría expuesto a la idea de estratificación. Por supuesto, las capas están en todas partes en las computadoras, como en la pila de red (modelo ISO), o en gráficos (Photoshop) o en SOA (los servicios pueden llamar a hermanos o hijos, pero nunca a padres).
Sin embargo, el tipo específico de capas que se ha abusado sin importar lo que sea es la 'GUI', 'Business Logic Layer' y luego 'Data Access Layer'. Quiero decir, sí, la idea es buena en principio, como el comunismo es bueno en principio, pero en realidad no lo es.
Echemos un vistazo a por qué. El argumento que voy a usar es sobre el acoplamiento; puntos de una capa que toca puntos en otra capa. Cada vez que comienzas a crear una aplicación en capas de n niveles en el modo empresarial predeterminado en el que las personas entran, crean tantos puntos de contacto entre las capas.
En esencia, la idea es que las capas son intercambiables; pero no lo son! ¿Por qué? Debido a todo el acoplamiento del sitio de llamada.
En cambio, eche un vistazo a por qué la red está desacoplada. ¡Porque la interfaz es una secuencia de bytes sobre un único puntero de archivo que apunta a un socket abierto! ¡Todas las capas en los modelos ISO son como lo que el patrón de diseño llamado 'cadena de responsabilidad' es la orientación a objetos! Cada capa envuelve la capa subyacente, sin conocer la semántica de los datos en esa capa subyacente.
A medida que un paquete de datos se dirige hacia Ethernet y señales eléctricas sin procesar en la parte inferior, se envuelve continuamente por capas que solo conocen su propio sobre de mensaje específico, su propio "lote de bytes" específico que puede enviar; y nada más. No es necesario alterar las rutas de llamadas en función del contenido del paquete.
Compare esto con el n-tier donde tendría que alterar la ruta de llamada en las capas de su aplicación en una 'llamada' que atraviesa sus capas en su camino a la base de datos; por ejemplo, los 'clientes de oro' son polimórficamente un superconjunto de 'clientes normales' y, como usamos 'tabla por subclase', necesitamos saber sobre esto ahora que los datos (entidad) están atravesando las capas; tanto en la llamada 'capa de lógica de negocios' como en la capa de datos que realmente está guardando.
No es escalable ni óptimo desde una perspectiva informática.
¿Por qué no es escalable? ¡Debido a que la arquitectura está acoplada, y aún está dentro del mismo DB antiguo que estaba tratando de escalar a muchos nodos! Pero, debido a que necesita ACID para esto, ¡eso y una tercera entidad (objeto de datos) necesita tenerlos en una única base de datos que realice transacciones!
Correcto, así que con ese despotricar fuera del camino; ¿Qué otras formas hay?
Bueno, existe el acrónimo odiado llamado 'SOA', es decir, arquitectura orientada a servicios. Por supuesto, el Tomas Erls del mundo , tendría que implementar todas sus capas pero con XML y SOAP.
Por todas las razones anteriores, esta es la manera incorrecta de hacerlo, ya que te estarías acoplando a esos proxies XML al igual que te unirías a las capas de la aplicación como se explicó anteriormente.
En su lugar, use la mensajería y deje que lo que implemente la funcionalidad para ellos, escúchelos. Su superficie de servicio se convierte en una lista de mensajes que puede enviar y no ha acoplado sus operaciones a su fachada de servicio; y ni siquiera necesita saber qué aplicación o punto final implementan estas operaciones, ¡porque todo lo que está haciendo es publicar un mensaje de que algún otro mecanismo de enrutamiento se enrutará al consumidor correcto!
Debido a que ha desacoplado las fachadas de servicios de las operaciones reales que desea realizar, ahora puede agregar múltiples servicios; de hecho, así es como lo hace Netflix. Eche un vistazo a estas presentaciones: http://www.slideshare.net/adrianco/global-netflix-platform . http://www.slideshare.net/adrianco/global-netflix-platform . ¡Ellos son buenos!
fuente
Hay una nueva base de datos SQL (ACID) en beta que se afirma que tiene propiedades de escalado elástico. Ahora hay un programa beta gratuito y le sugiero que eche un vistazo, se llama NuoDB.
Aparentemente, supera fácilmente a MySQL incluso en una sola máquina de subprocesos, pero se escala felizmente a más de 70 instancias en ciertos puntos de referencia.
fuente