Entender la fragmentación de la base de datos

Introducción

Cualquier aplicación o sitio web que experimente un crecimiento significativo necesitará eventualmente escalar para acomodar los aumentos de tráfico. Para las aplicaciones y sitios web basados en datos, es fundamental que el escalado se realice de forma que garantice la seguridad e integridad de sus datos. Puede ser difícil predecir la popularidad que alcanzará un sitio web o una aplicación o el tiempo que mantendrá esa popularidad, por lo que algunas organizaciones optan por una arquitectura de base de datos que les permita escalar sus bases de datos de forma dinámica.

En este artículo conceptual, hablaremos de una de esas arquitecturas de bases de datos: las bases de datos fragmentadas. La fragmentación ha recibido mucha atención en los últimos años, pero muchos no tienen una comprensión clara de lo que es o de los escenarios en los que podría tener sentido fragmentar una base de datos. Vamos a repasar lo que es la fragmentación, algunos de sus principales beneficios y desventajas, y también algunos métodos comunes de fragmentación.

¿Qué es la fragmentación?

La fragmentación es un patrón de arquitectura de base de datos relacionado con el particionamiento horizontal – la práctica de separar las filas de una tabla en múltiples tablas diferentes, conocidas como particiones. Cada partición tiene el mismo esquema y columnas, pero también filas totalmente diferentes. Asimismo, los datos contenidos en cada una son únicos e independientes de los datos contenidos en otras particiones.

Puede ser útil pensar en el particionamiento horizontal en términos de cómo se relaciona con el particionamiento vertical. En una tabla con partición vertical, se separan columnas enteras y se colocan en tablas nuevas y distintas. Los datos de una partición vertical son independientes de los datos de todas las demás, y cada una contiene filas y columnas distintas. El siguiente diagrama ilustra cómo se puede particionar una tabla tanto horizontal como verticalmente:

Ejemplos de tablas que muestran la partición horizontal y vertical

La partición implica dividir los datos en dos o más trozos más pequeños, llamados fragmentos lógicos. Los fragmentos lógicos se distribuyen en nodos de base de datos separados, denominados fragmentos físicos, que pueden contener múltiples fragmentos lógicos. A pesar de ello, los datos contenidos en todos los fragmentos representan colectivamente un conjunto de datos lógicos completo.

Los fragmentos de la base de datos ejemplifican una arquitectura de no compartir nada. Esto significa que los fragmentos son autónomos; no comparten ninguno de los mismos datos o recursos informáticos. En algunos casos, sin embargo, puede tener sentido replicar ciertas tablas en cada fragmento para que sirvan como tablas de referencia. Por ejemplo, digamos que hay una base de datos para una aplicación que depende de tipos de conversión fijos para las medidas de peso. Al replicar una tabla que contenga los datos necesarios de la tasa de conversión en cada fragmento, ayudaría a garantizar que todos los datos necesarios para las consultas se mantienen en cada fragmento.

A menudo, la fragmentación se implementa a nivel de aplicación, lo que significa que la aplicación incluye código que define a qué fragmento transmitir las lecturas y las escrituras. Sin embargo, algunos sistemas de gestión de bases de datos tienen capacidades de fragmentación incorporadas, lo que le permite implementar la fragmentación directamente en el nivel de la base de datos.

Dada esta visión general de la fragmentación, vamos a repasar algunos de los aspectos positivos y negativos asociados a esta arquitectura de base de datos.

Beneficios de la fragmentación

El principal atractivo de la fragmentación de una base de datos es que puede ayudar a facilitar el escalado horizontal, también conocido como escalado. El escalado horizontal es la práctica de añadir más máquinas a una pila existente para repartir la carga y permitir más tráfico y un procesamiento más rápido. Esto se suele contrastar con el escalado vertical, también conocido como escalado hacia arriba, que implica la actualización del hardware de un servidor existente, normalmente añadiendo más RAM o CPU.

Es relativamente sencillo tener una base de datos relacional que se ejecuta en una sola máquina y escalarla según sea necesario mediante la actualización de sus recursos informáticos. En última instancia, sin embargo, cualquier base de datos no distribuida estará limitada en términos de almacenamiento y potencia de cálculo, por lo que tener la libertad de escalar horizontalmente hace que su configuración sea mucho más flexible.

Otra razón por la que algunos podrían elegir una arquitectura de base de datos fragmentada es para acelerar los tiempos de respuesta de las consultas. Cuando se envía una consulta a una base de datos que no ha sido fragmentada, es posible que tenga que buscar en cada fila de la tabla que está consultando antes de encontrar el conjunto de resultados que está buscando. Para una aplicación con una base de datos grande y monolítica, las consultas pueden volverse prohibitivamente lentas. Sin embargo, al fragmentar una tabla en varias, las consultas tienen que pasar por menos filas y sus conjuntos de resultados se devuelven mucho más rápidamente.

La fragmentación también puede ayudar a que una aplicación sea más fiable al mitigar el impacto de las interrupciones. Si su aplicación o sitio web depende de una base de datos no fragmentada, una interrupción tiene el potencial de hacer que toda la aplicación no esté disponible. Sin embargo, con una base de datos fragmentada, es probable que una interrupción afecte sólo a un fragmento. Aunque esto podría hacer que algunas partes de la aplicación o del sitio web no estuvieran disponibles para algunos usuarios, el impacto global seguiría siendo menor que si toda la base de datos se cayera.

Desventajas de la fragmentación

Aunque la fragmentación de una base de datos puede facilitar el escalado y mejorar el rendimiento, también puede imponer ciertas limitaciones. Aquí, discutiremos algunas de ellas y por qué podrían ser razones para evitar la fragmentación por completo.

La primera dificultad que la gente encuentra con la fragmentación es la enorme complejidad de implementar adecuadamente una arquitectura de base de datos fragmentada. Si se hace de forma incorrecta, existe un riesgo significativo de que el proceso de fragmentación pueda conducir a la pérdida de datos o a la corrupción de las tablas. Sin embargo, incluso cuando se hace correctamente, la fragmentación puede tener un gran impacto en los flujos de trabajo de su equipo. En lugar de acceder y gestionar los datos propios desde un único punto de entrada, los usuarios deben gestionar los datos a través de múltiples ubicaciones de shard, lo que podría ser potencialmente perturbador para algunos equipos.

Un problema que a veces encuentran los usuarios después de haber fragmentado una base de datos es que los fragmentos acaban desequilibrándose. A modo de ejemplo, digamos que tiene una base de datos con dos fragmentos separados, uno para los clientes cuyos apellidos comienzan con las letras A a M y otro para aquellos cuyos nombres comienzan con las letras N a Z. Sin embargo, su aplicación sirve una cantidad excesiva de personas cuyos apellidos comienzan con la letra G. En consecuencia, el fragmento A-M acumula gradualmente más datos que el N-Z, lo que hace que la aplicación se ralentice y se detenga para una parte significativa de sus usuarios. El fragmento A-M se ha convertido en lo que se conoce como un punto caliente de la base de datos. En este caso, cualquier beneficio de la fragmentación de la base de datos se ve anulado por la ralentización y las caídas. La base de datos probablemente tendría que ser reparada y reagrupada para permitir una distribución de datos más uniforme.

Otro inconveniente importante es que una vez que una base de datos ha sido fragmentada, puede ser muy difícil devolverla a su arquitectura no fragmentada. Cualquier copia de seguridad de la base de datos realizada antes de ser fragmentada no incluirá los datos escritos desde la partición. En consecuencia, la reconstrucción de la arquitectura original sin fragmentar requeriría la fusión de los nuevos datos particionados con las copias de seguridad antiguas o, alternativamente, la transformación de la base de datos particionada de nuevo en una única base de datos, ambas cosas serían esfuerzos costosos y que llevarían mucho tiempo.

Una última desventaja a tener en cuenta es que la fragmentación no es soportada de forma nativa por todos los motores de bases de datos. Por ejemplo, PostgreSQL no incluye la fragmentación automática como una característica, aunque es posible fragmentar manualmente una base de datos PostgreSQL. Hay una serie de bifurcaciones de Postgres que sí incluyen la fragmentación automática, pero a menudo van por detrás de la última versión de PostgreSQL y carecen de otras características. Algunas tecnologías de bases de datos especializadas – como MySQL Cluster o ciertos productos de bases de datos como servicio como MongoDB Atlas – incluyen la fragmentación automática como una característica, pero las versiones de estos sistemas de gestión de bases de datos no lo hacen. Por este motivo, la fragmentación suele requerir un enfoque «a tu medida». Esto significa que la documentación para la fragmentación o los consejos para la solución de problemas son a menudo difíciles de encontrar.

Estos son, por supuesto, sólo algunas cuestiones generales a considerar antes de la fragmentación. Puede haber muchos más inconvenientes potenciales para fragmentar una base de datos dependiendo de su caso de uso.

Ahora que hemos cubierto algunos de los inconvenientes y beneficios de la fragmentación, vamos a repasar algunas arquitecturas diferentes para las bases de datos fragmentadas.

Arquitecturas de fragmentación

Una vez que haya decidido fragmentar su base de datos, lo siguiente que debe averiguar es cómo lo hará. Cuando se ejecutan consultas o se distribuyen los datos entrantes a las tablas o bases de datos fragmentadas, es crucial que vayan al fragmento correcto. De lo contrario, podría resultar en la pérdida de datos o en consultas dolorosamente lentas. En esta sección, repasaremos algunas arquitecturas de fragmentación comunes, cada una de las cuales utiliza un proceso ligeramente diferente para distribuir los datos entre los fragmentos.

Grupos basados en claves

Los fragmentos basados en claves, también conocidos como fragmentos basados en hash, implican el uso de un valor tomado de los datos recién escritos -como el número de identificación de un cliente, la dirección IP de una aplicación cliente, un código postal, etc.- y su introducción en una función hash para determinar a qué fragmento deben ir los datos. Una función hash es una función que toma como entrada un dato (por ejemplo, el correo electrónico de un cliente) y da como resultado un valor discreto, conocido como valor hash. En el caso de la fragmentación, el valor hash es un ID de fragmentación utilizado para determinar en qué fragmentación se almacenarán los datos entrantes. En conjunto, el proceso tiene el siguiente aspecto:

Diagrama de ejemplo de fragmentación basada en claves

Para garantizar que las entradas se colocan en los fragmentos correctos y de forma coherente, los valores introducidos en la función hash deben proceder todos de la misma columna. Esta columna se conoce como clave de shard. En términos sencillos, las claves de fragmentos son similares a las claves primarias, ya que ambas son columnas que se utilizan para establecer un identificador único para las filas individuales. En términos generales, una clave de fragmento debe ser estática, es decir, no debe contener valores que puedan cambiar con el tiempo. De lo contrario, aumentaría la cantidad de trabajo que se realiza en las operaciones de actualización, y podría ralentizar el rendimiento.

Aunque la fragmentación basada en claves es una arquitectura de fragmentación bastante común, puede complicar las cosas cuando se intenta añadir o eliminar dinámicamente servidores adicionales a una base de datos. A medida que se añaden servidores, cada uno de ellos necesitará un valor hash correspondiente y muchas de las entradas existentes, si no todas, tendrán que ser reasignadas a su nuevo valor hash correcto y luego migradas al servidor apropiado. Cuando empiece a reequilibrar los datos, ni las nuevas ni las antiguas funciones hash serán válidas. En consecuencia, su servidor no podrá escribir ningún dato nuevo durante la migración y su aplicación podría estar sujeta a un tiempo de inactividad.

El principal atractivo de esta estrategia es que se puede utilizar para distribuir uniformemente los datos con el fin de evitar los puntos calientes. Además, como distribuye los datos de forma algorítmica, no es necesario mantener un mapa de dónde se encuentran todos los datos, como es necesario con otras estrategias como el sharding basado en rangos o directorios.

Sharding basado en rangos

El sharding basado en rangos implica el sharding de datos basado en rangos de un valor determinado. Para ilustrar, digamos que tiene una base de datos que almacena información sobre todos los productos dentro del catálogo de un minorista. Podrías crear unos cuantos shards diferentes y dividir la información de cada producto en función del rango de precios al que pertenezcan, de la siguiente manera:

Diagrama de ejemplo de sharding basado en rangos

La principal ventaja del sharding basado en rangos es que es relativamente sencillo de implementar. Cada fragmento contiene un conjunto diferente de datos, pero todos tienen un esquema idéntico entre sí, así como la base de datos original. El código de la aplicación sólo lee en qué rango caen los datos y los escribe en el fragmento correspondiente.

Por otro lado, la fragmentación basada en rangos no protege los datos de ser distribuidos de forma desigual, lo que lleva a los mencionados puntos calientes de la base de datos. Si nos fijamos en el diagrama de ejemplo, aunque cada fragmento contenga la misma cantidad de datos, lo más probable es que determinados productos reciban más atención que otros. Sus respectivos shards recibirán, a su vez, un número desproporcionado de lecturas.

Directory Based Sharding

Para implementar la fragmentación basada en directorios, se debe crear y mantener una tabla de búsqueda que utilice una clave de fragmento para realizar un seguimiento de qué fragmento contiene qué datos. En pocas palabras, una tabla de búsqueda es una tabla que contiene un conjunto estático de información sobre dónde se pueden encontrar datos específicos. El siguiente diagrama muestra un ejemplo simplista de fragmentación basada en directorios:

Diagrama de ejemplo de fragmentación basada en directorios

Aquí, la columna Zona de entrega se define como una clave de fragmentación. Los datos de la clave del fragmento se escriben en la tabla de búsqueda junto con el fragmento en el que debe escribirse cada fila. Esto es similar a la fragmentación basada en rangos, pero en lugar de determinar en qué rango caen los datos de la clave del fragmento, cada clave está vinculada a su propio fragmento específico. La fragmentación basada en directorios es una buena opción frente a la fragmentación basada en rangos en los casos en los que la clave del fragmento tiene una cardinalidad baja y no tiene sentido que un fragmento almacene un rango de claves. Ten en cuenta que también se diferencia de la fragmentación basada en claves en que no procesa la clave del fragmento a través de una función hash; sólo comprueba la clave contra una tabla de búsqueda para ver dónde se deben escribir los datos.

El principal atractivo de la fragmentación basada en directorios es su flexibilidad. Las arquitecturas de fragmentación basadas en rangos te limitan a especificar rangos de valores, mientras que las basadas en claves te limitan a utilizar una función hash fija que, como se ha mencionado anteriormente, puede ser extremadamente difícil de cambiar más adelante. La fragmentación basada en directorios, por otro lado, permite utilizar cualquier sistema o algoritmo que se desee para asignar entradas de datos a los fragmentos, y es relativamente fácil añadir fragmentos de forma dinámica utilizando este enfoque.

Aunque la fragmentación basada en directorios es el más flexible de los métodos de fragmentación que se discuten aquí, la necesidad de conectarse a la tabla de búsqueda antes de cada consulta o escritura puede tener un impacto perjudicial en el rendimiento de una aplicación. Además, la tabla de consulta puede convertirse en un único punto de fallo: si se corrompe o falla de alguna manera, puede afectar a la capacidad de escribir nuevos datos o acceder a los datos existentes.

¿Debo fragmentar?

Si se debe o no implementar una arquitectura de base de datos fragmentada es casi siempre una cuestión de debate. Algunos ven el sharding como un resultado inevitable para las bases de datos que alcanzan un cierto tamaño, mientras que otros lo ven como un dolor de cabeza que debe evitarse a menos que sea absolutamente necesario, debido a la complejidad operativa que añade el sharding.

Debido a esta complejidad añadida, la fragmentación sólo suele realizarse cuando se trata de cantidades muy grandes de datos. Estos son algunos escenarios comunes en los que puede ser beneficioso fragmentar una base de datos:

  • La cantidad de datos de la aplicación crece hasta superar la capacidad de almacenamiento de un único nodo de la base de datos.
  • El volumen de escrituras o lecturas en la base de datos supera lo que un único nodo o sus réplicas de lectura pueden manejar, lo que provoca tiempos de respuesta lentos o tiempos de espera.
  • El ancho de banda de la red requerido por la aplicación supera el ancho de banda disponible para un solo nodo de la base de datos y cualquier réplica de lectura, lo que resulta en tiempos de respuesta lentos o tiempos de espera.
  • Antes de la fragmentación, debe agotar todas las demás opciones para optimizar su base de datos. Algunas optimizaciones que podría considerar incluyen:

    • Configurar una base de datos remota. Si está trabajando con una aplicación monolítica en la que todos sus componentes residen en el mismo servidor, puede mejorar el rendimiento de su base de datos trasladándola a su propia máquina. Esto no añade tanta complejidad como la fragmentación, ya que las tablas de la base de datos permanecen intactas. Sin embargo, todavía le permite escalar verticalmente su base de datos aparte del resto de su infraestructura.
    • Implementar el almacenamiento en caché. Si el rendimiento de lectura de su aplicación es lo que le está causando problemas, el almacenamiento en caché es una estrategia que puede ayudar a mejorarlo. El almacenamiento en caché consiste en guardar temporalmente en memoria los datos que ya han sido solicitados, lo que le permite acceder a ellos mucho más rápidamente más adelante.
    • Crear una o más réplicas de lectura. Otra estrategia que puede ayudar a mejorar el rendimiento de la lectura, consiste en copiar los datos de un servidor de base de datos (el servidor primario) a uno o más servidores secundarios. A continuación, cada nueva escritura va al primario antes de copiarse a los secundarios, mientras que las lecturas se realizan exclusivamente en los servidores secundarios. Distribuir las lecturas y las escrituras de este modo evita que una sola máquina asuma demasiada carga, lo que ayuda a evitar ralentizaciones y caídas. Tenga en cuenta que la creación de réplicas de lectura implica más recursos informáticos y, por lo tanto, cuesta más dinero, lo que podría ser una limitación importante para algunos.
    • Actualización a un servidor más grande. En la mayoría de los casos, la ampliación del servidor de bases de datos a una máquina con más recursos requiere menos esfuerzo que la fragmentación. Al igual que con la creación de réplicas de lectura, un servidor actualizado con más recursos probablemente costará más dinero. En consecuencia, sólo debería seguir adelante con el redimensionamiento si realmente acaba siendo su mejor opción.
      • Tenga en cuenta que si su aplicación o sitio web crece más allá de un determinado punto, ninguna de estas estrategias será suficiente para mejorar el rendimiento por sí sola. En estos casos, el sharding sí puede ser la mejor opción para ti.

        Conclusión

        El sharding puede ser una gran solución para aquellos que buscan escalar su base de datos horizontalmente. Sin embargo, también añade una gran complejidad y crea más puntos de fallo potenciales para su aplicación. La fragmentación puede ser necesaria para algunos, pero el tiempo y los recursos necesarios para crear y mantener una arquitectura fragmentada podrían superar los beneficios para otros.

        Al leer este artículo conceptual, debería tener una comprensión más clara de los pros y los contras de la fragmentación. En el futuro, puede utilizar esta visión para tomar una decisión más informada sobre si una arquitectura de base de datos fragmentada es adecuada para su aplicación o no.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *