¿Qué es la fragmentación de bases de datos?

La fragmentación de bases de datos es una estrategia que se usa para resolver problemas de escalabilidad en aplicaciones que tienen una gran cantidad de datos. Implica dividir un único conjunto de datos lógico grande en partes más pequeñas y fáciles de administrar llamadas fragmentos. Cada fragmento se almacena en una instancia de servidor de base de datos independiente, lo que distribuye los datos y la carga de trabajo en varias máquinas.

La fragmentación es un método clave para el escalamiento horizontal (escalamiento externo). En lugar de actualizar un solo servidor con más CPU o RAM (escalamiento vertical), que eventualmente alcanza un límite de hardware, la fragmentación te permite agregar más servidores básicos a tu clúster. Esto permite que las aplicaciones manejen un crecimiento casi infinito en el volumen de datos y el tráfico de usuarios.

Transformación de la base de datos de Credit Karma: De MySQL fragmentado a Spanner

Si bien la fragmentación es una forma eficaz de escalar horizontalmente, es una de las tres estrategias comunes de escalamiento horizontal:

  • Réplicas de lectura: Esto implica crear copias de la base de datos principal para manejar el tráfico de solo lectura, lo que reduce la carga en el servidor principal.
  • Fragmentación: Distribuye los datos y el tráfico de escritura en varios servidores independientes.
  • Bases de datos distribuidas: Productos como Spanner manejan de forma nativa la distribución y el escalamiento dentro del motor de la base de datos, lo que quita la necesidad de fragmentación manual.

¿Cómo funciona la fragmentación de bases de datos?

La fragmentación de bases de datos funciona agrupando los datos en función de un valor específico llamado clave de fragmento. Una clave de fragmentación es una columna en tu base de datos, como un ID de usuario, una región de cliente o un número de pedido, que determina qué servidor almacenará una fila específica de datos. Cuando se escriben datos en la base de datos, el sistema busca esta clave para decidir dónde pertenecen los datos.

Para encontrar los datos más tarde, el sistema debe enrutar la consulta a la ubicación correcta. Este enrutamiento se realiza de dos formas principales:

  • Capa de enrutamiento: Las arquitecturas de fragmentación pueden usar un balanceador de cargas inteligente o una capa de proxy dedicada. Cuando una aplicación envía una consulta, la capa de enrutamiento comprueba la clave de fragmento, calcula qué fragmento contiene esos datos y dirige el tráfico a ese servidor.
  • Lógica del lado de la aplicación: En algunos casos, como en los juegos multijugador o las apps en tiempo real de alto rendimiento, el código de la aplicación en sí contiene la lógica de fragmentación. El código calcula la ubicación correcta del fragmento antes de enviar la solicitud, lo que puede reducir la latencia quitando un salto de red adicional.

Cuando se segmenta solo el fragmento pertinente, la base de datos responde a las consultas más rápido y maneja miles de solicitudes simultáneas sin ralentizarse.

Infografía sobre la fragmentación de datos

Métodos comunes de fragmentación

Las diferentes aplicaciones requieren una lógica diferente para dividir los datos. El método que elijas dicta cómo la “capa de enrutamiento” encuentra tus datos.

Este método usa una fórmula matemática (una función hash) en la clave de fragmentación para asignar datos. Por ejemplo, el sistema podría calcular el ID de usuario (mod 4) para asignar un usuario a 1 de 4 servidores.

Si bien las funciones hash ayudan a distribuir los datos de manera coherente, solo garantizan una distribución uniforme si la clave de fragmentación tiene una alta cardinalidad y un bajo sesgo de frecuencia. Si eliges una clave de fragmentación con un valor común, como un "apellido" en el que "Smith" aparece 1,000 veces más que "Pyne", la función hash enviará todos los registros de "Smith" al mismo fragmento. Esto crea un "fragmento activo" a pesar de que se usa una fórmula matemática.

Agregar servidores nuevos también es difícil con este método porque la fórmula cambia, lo que a menudo requiere que "vuelvas a fragmentar" o mover tus datos a través del nuevo clúster de servidores.

Los datos se asignan en función de los rangos de valores. Por ejemplo, podrías colocar los IDs de usuario del 1 al 1,000 en el servidor A y del 1,001 al 2,000 en el servidor B. Esto es muy intuitivo y excelente para las consultas que necesitan leer una secuencia de datos (consultas de rango). La desventaja es que se crean "puntos calientes": si todos los usuarios nuevos se asignan al servidor B, este hará todo el trabajo mientras que el servidor A estará inactivo.

Esta estrategia usa una tabla de búsqueda (un directorio) que rastrea exactamente qué fragmento contiene qué datos. Ofrece la mayor flexibilidad porque puedes mover datos entre fragmentos sin cambiar una fórmula. Sin embargo, esta tabla de búsqueda se convierte en un cuello de botella, ya que cada consulta debe verificar el directorio primero, lo que agrega latencia. Si falla el directorio, toda la base de datos se vuelve inaccesible.

La fragmentación geográfica asigna datos a servidores específicos en función de la ubicación física de un usuario. Por ejemplo, los datos de los usuarios de Francia se almacenan en servidores de la UE, mientras que los de los usuarios de EE.UU. se almacenan en servidores de Norteamérica. Esto reduce significativamente la latencia (velocidad) para los usuarios y ayuda a las empresas a cumplir con las leyes de residencia de datos como el RGPD.

A veces llamada partición funcional, esto implica dividir los datos por atributo en lugar de por fila. Por ejemplo, puedes colocar todas las tablas de "Perfil de usuario" en el servidor A y todas las tablas de "Carga de fotos" en el servidor B. Si bien esto organiza los datos de forma lógica, es funcionalmente similar a una arquitectura de datos de microservicios y no resuelve el problema si una función específica (como Fotos) crece demasiado para un solo servidor.

Cómo optimizar la fragmentación de bases de datos para una distribución uniforme de los datos

Elegir la clave de fragmento correcta es la decisión más importante en la fragmentación. Una clave incorrecta puede generar una distribución desigual de los datos (puntos calientes), mientras que una clave correcta puede garantizar que todos los servidores trabajen por igual. Para optimizar esto, debes considerar tres factores:

  1. Cardinalidad: Se refiere a la cantidad de valores únicos que puede tener una clave. Quieres una clave con alta cardinalidad (como un ID de usuario), no con baja cardinalidad (como "Género" o "Estado"), para que los datos se puedan dividir en muchos fragmentos pequeños.
  2. Frecuencia: Debes evitar las claves en las que un valor específico aparece con demasiada frecuencia. Por ejemplo, si haces una partición por "Ciudad" y el 80% de tus usuarios vive en Nueva York, la partición "Nueva York" estará sobrecargada.
  3. Cambio monótono: Evita las claves que aumentan estrictamente con el tiempo, como una marca de tiempo o un ID de incremento automático. Si particionas por fecha, todas las escrituras de datos nuevos irán a la partición "Hoy", lo que creará un hotspot de escritura mientras que las particiones más antiguas permanecerán inactivas.

Términos clave de fragmentación

Si bien estos términos suelen usarse juntos en el diseño de sistemas, resuelven problemas diferentes.

La fragmentación es un tipo específico de partición horizontal en el que las piezas de datos se distribuyen en servidores completamente diferentes. Esto resuelve los límites de capacidad de hardware (almacenamiento) y los cuellos de botella de rendimiento de escritura, ya que diferentes servidores pueden procesar escrituras simultáneamente.

  • Fragmentación manual: En un entorno de fragmentación manual, el desarrollador o el administrador de la base de datos es responsable de definir las claves de fragmento, crear la infraestructura para cada fragmento y escribir la lógica para enrutar las consultas. Esto te brinda un control detallado sobre la ubicación exacta de los datos. Sin embargo, requiere un mantenimiento significativo. Si una partición se vuelve demasiado grande, debes volver a particionar los datos de forma manual, lo que implica mover millones de filas a servidores nuevos mientras intentas minimizar el tiempo de inactividad de la aplicación.
  • Fragmentación automática: La fragmentación automática, que suele encontrarse en bases de datos NoSQL como Bigtable o bases de datos SQL distribuidas como Spanner, controla la distribución de datos y tráfico automáticamente. El sistema supervisa el tamaño de los datos y la carga en cada servidor. Si una partición específica se convierte en un "punto activo" o crece demasiado, el motor de base de datos divide automáticamente la partición y mueve los datos a un servidor menos congestionado. Esto reduce la carga operativa de tu equipo y ayuda a garantizar un rendimiento coherente a medida que se escala tu aplicación.

La partición implica dividir una tabla grande en partes más pequeñas y fáciles de administrar (como dividir una tabla de registros por mes), pero mantenerlas en la misma instancia de servidor. Esto resuelve los problemas de almacenamiento, ya que facilita el archivo o el borrado de datos antiguos sin afectar al resto de la tabla. Sin embargo, no soluciona los problemas del servidor. Como todas las particiones aún residen en una sola máquina, siguen compartiendo la misma CPU y RAM, lo que significa que la partición no puede ayudar si el servidor alcanza sus límites de rendimiento.

La replicación es el proceso de copiar toda la base de datos en varios servidores. Esta puede ser una buena opción para la disponibilidad de lectura; si un servidor falla, otro puede tomar el control. Sin embargo, no ayuda con el escalamiento de escritura, ya que cada dato escrito debe copiarse en cada réplica, lo que limita la velocidad de escritura a la capacidad de una sola máquina.

Igualmente importante, la mayoría de los modelos de replicación solo permiten un "escritor" (el nodo principal) a la vez. Si intentas permitir que varios servidores acepten escrituras simultáneamente, corres el riesgo de que se produzcan conflictos de escritura, en los que dos servidores intentan actualizar el mismo registro con información diferente. Resolver estos conflictos es técnicamente difícil y puede provocar la pérdida o la coherencia de los datos si no se maneja con un sistema distribuido sofisticado.

Una base de datos distribuida, como Spanner, proporciona los beneficios de la fragmentación sin la sobrecarga manual. Estos sistemas están diseñados para funcionar en un clúster de máquinas desde el principio. Manejan automáticamente la distribución, el reequilibrio y la replicación de datos de forma transparente. Algunos de estos sistemas tienen varios escritores y manejan automáticamente los conflictos de escritura. Esto te permite escalar horizontalmente mientras mantienes la coherencia de una base de datos relacional tradicional.

Usa la tabla que aparece a continuación para comprender las diferencias entre estos conceptos básicos de bases de datos.

Función

Fragmentación

Partición

Replicación

Base de datos distribuida

Objetivo principal

Escalamiento y almacenamiento masivos de escritura

Administración y mantenimiento

Alta disponibilidad y escalamiento de lectura


Escalamiento global automatizado

Ubicación de los datos

Diferentes fragmentos de datos en diferentes servidores

Diferentes fragmentos de datos en el mismo servidor

Copias de los mismos datos en varios servidores

Administrado en un clúster

Rendimiento de escritura

Mejora alta (las escrituras se realizan en paralelo)

Mejora menor (índices más pequeños)


Sin mejora (las escrituras deben ir a todas las copias)

Mejora alta

Complejidad

Alta

Media

Baja

Baja (administrada)

Función

Fragmentación

Partición

Replicación

Base de datos distribuida

Objetivo principal

Escalamiento y almacenamiento masivos de escritura

Administración y mantenimiento

Alta disponibilidad y escalamiento de lectura


Escalamiento global automatizado

Ubicación de los datos

Diferentes fragmentos de datos en diferentes servidores

Diferentes fragmentos de datos en el mismo servidor

Copias de los mismos datos en varios servidores

Administrado en un clúster

Rendimiento de escritura

Mejora alta (las escrituras se realizan en paralelo)

Mejora menor (índices más pequeños)


Sin mejora (las escrituras deben ir a todas las copias)

Mejora alta

Complejidad

Alta

Media

Baja

Baja (administrada)

Beneficios de la fragmentación de bases de datos

La fragmentación suele ser la única solución viable para las aplicaciones que manejan terabytes de datos o millones de transacciones por segundo.

Escalamiento horizontal

La fragmentación permite un escalamiento casi infinito agregando servidores estándar a un clúster. Esto evita el "impuesto de hardware" de las aplicaciones heredadas de escalamiento vertical. Sin la fragmentación, a menudo es necesario comprar hardware especializado y costoso que alcanza un límite de rendimiento. La fragmentación permite que la base de datos crezca junto con tu empresa usando máquinas más económicas y básicas.

Mejora del rendimiento de las consultas

La fragmentación acelera las consultas individuales porque cada servidor busca en un conjunto de datos más pequeño. En vez de buscar en un índice de 100 millones de filas, puede que una consulta necesite hacerlo solo en un fragmento con 1 millón de filas. Además, como los datos están en diferentes máquinas, puedes ejecutar varias consultas en paralelo, lo que aumenta enormemente la capacidad de procesamiento total de la aplicación.

Confiabilidad

La fragmentación limita el "radio de impacto" de las fallas. Si falla un fragmento, solo se verán afectados esos usuarios, mientras que el resto de la app permanecerá en línea. Sin embargo, más servidores implican una mayor carga administrativa. Administrar copias de seguridad, seguridad y parches en decenas de instancias aumenta la complejidad operativa en comparación con una configuración de un solo servidor.

Desafíos de la fragmentación

Si bien la fragmentación aborda los requisitos de gran escala, introduce importantes compensaciones técnicas y operativas. Debes tener en cuenta estos desafíos antes de abandonar una arquitectura de una sola instancia.

  • Puntos de acceso de datos: Incluso con una función hash, el tráfico desigual puede crear "puntos de acceso" en los que un servidor se sobrecarga debido a un pequeño grupo de usuarios muy activos, mientras que otros fragmentos permanecen subutilizados.
  • Regresión del rendimiento: Las consultas que no usan la clave de fragmentación requieren que el sistema realice una operación de dispersión y recolección en todos los servidores. De manera similar, las uniones entre fragmentos son costosas desde el punto de vista de procesamiento porque la aplicación debe extraer y combinar datos de varias ubicaciones físicas.
  • Complejidad operativa: Administrar un entorno fragmentado aumenta la dificultad de las tareas rutinarias. Las actualizaciones de esquemas, las copias de seguridad y la recuperación de un momento determinado deben coordinarse en varias instancias independientes.
  • Coherencia transaccional: Muchas arquitecturas fragmentadas tienen dificultades para admitir transacciones ACID en diferentes fragmentos. Esto suele obligar a los desarrolladores a administrar esituaciones complejas de "fallas parciales" o a depender de modelos de coherencia eventual.

Resuelve tus desafíos más difíciles con Google Cloud

Los clientes nuevos obtienen $300 en créditos gratuitos que pueden usar en Google Cloud.

Da el siguiente paso

¿Todo listo para dejar de preocuparte por los límites de la base de datos?

Google Cloud