El sharding divide una base de datos en varias, cada una con una parte de los datos. Es la respuesta cuando una sola máquina ya no puede con las escrituras o no puede guardar los datos, y también una de las decisiones más caras en la vida de un sistema: las consultas, las transacciones, los cambios de esquema y la operación se vuelven más difíciles.
Este artículo cubre cuándo compensa el sharding, cómo elegir una clave de shard, los esquemas principales, cómo encuentran las consultas el shard correcto y cómo hacer resharding sin caídas. El diagrama muestra una base de datos de pedidos con sharding por hash y shards lógicos.
Prueba todo lo demás primero
Antes del sharding, revisa las opciones más baratas, más o menos en este orden:
- Arregla consultas e índices. La mayoría de los problemas de «la base de datos va lenta» son un índice que falta o una consulta que lee demasiado.
- Escala verticalmente. Una máquina más grande, con más memoria y discos más rápidos, da años de margen a muchos sistemas.
- Añade réplicas de lectura para cargas dominadas por lecturas; el artículo sobre replicación de bases de datos trata el retraso que traen consigo.
- Cachea las lecturas frecuentes, como en el artículo sobre estrategias de caché.
- Divide por función: lleva las tablas de analítica, búsqueda o auditoría a sus propias bases de datos.
Haz sharding cuando las escrituras o el tamaño de los datos superen lo que puede manejar un primario, incluso después de esos pasos, y la tendencia indique que irá a peor.
Elegir la clave de shard
La clave de shard decide en qué shard vive una fila. Una buena clave tiene tres propiedades:
- Todas las consultas frecuentes la incluyen. Si la consulta de la lista de pedidos filtra por cliente,
customer_idpermite al router enviarla a un solo shard. Una consulta sin la clave tiene que preguntar a todos los shards. - Reparte la carga de forma uniforme. Muchos valores distintos, sin que ningún valor concentre una gran parte del tráfico.
- Mantiene juntos los datos relacionados. Todos los pedidos, líneas y pagos de un cliente en un mismo shard hacen que las transacciones y los joins sean locales.
En un SaaS multiinquilino, la clave suele ser el ID del inquilino. En una app de consumo, el ID del usuario o del cliente. Cuidado con las claves que parecen buenas pero concentran la carga, como una marca de tiempo (todas las escrituras nuevas van a un shard) o un código de país (un país domina).
Rango, hash o directorio
| Esquema | Cómo se colocan las filas | Ventaja | Inconveniente |
|---|---|---|---|
| Rango | Por rangos de clave, como A-F, G-M | Los recorridos por rango se quedan en un shard | Los rangos nuevos o populares se convierten en puntos calientes |
| Hash | Por el hash de la clave | Reparto uniforme | Las consultas por rango tocan todos los shards |
| Directorio | Una tabla de búsqueda asigna cada clave o grupo a un shard | Control total, movimientos fáciles | El directorio es crítico y tiene que ser rápido |
Un híbrido habitual: calcula el hash de la clave hacia un número fijo de shards lógicos (por ejemplo, 1024) y mantén un pequeño directorio que asigne los shards lógicos a hosts físicos. Las claves nunca cambian de shard lógico; solo se mueven shards lógicos enteros entre hosts. El equipo de ingeniería de Instagram describió este enfoque en 2012, con miles de shards lógicos sobre muchos menos servidores de bases de datos.
Enrutar las consultas
Algo tiene que saber dónde vive cada clave:
- En la aplicación, mediante una biblioteca que calcula el hash de la clave y busca el host. Es sencillo, pero cada servicio y cada lenguaje necesitan la misma lógica.
- En un proxy entre la aplicación y las bases de datos. Vitess lo hace para MySQL con su proxy VTGate, y Citus lo hace para Postgres mediante un nodo coordinador.
En ambos casos, cachea el mapa de shards y recárgalo cuando cambie. Un mapa desactualizado durante un movimiento es el bug clásico del resharding: un router escribe en el host antiguo después del cambio y la fila desaparece sin ruido del nuevo. Versiona el mapa y rechaza las escrituras que lleven una versión antigua. Las consultas sin clave de shard se reparten a todos los shards y se combinan los resultados, lo que sirve para tareas administrativas poco frecuentes y falla como vía de acceso normal.
Resharding sin caídas
Con shards lógicos, añadir capacidad significa mover algunos shards lógicos a un host nuevo:
- Copia los datos de los shards lógicos al host nuevo mientras el antiguo sigue sirviendo.
- Transmite los cambios en curso, con la replicación de la base de datos o con change data capture, hasta que la copia se ponga al día.
- Bloquea brevemente las escrituras de esos shards lógicos, deja que lleguen los últimos cambios, actualiza el mapa de shards y reanuda.
- Verifica y después borra los datos movidos del host antiguo.
Vitess y Citus automatizan variantes de este flujo. Ensáyalo antes de necesitarlo; hacer resharding bajo carga por primera vez es un mal día.
IDs que funcionan entre shards
Una secuencia por base de datos reparte los mismos IDs en cada shard. Usa IDs únicos sin coordinación: UUID (la versión 7 los mantiene más o menos ordenados en el tiempo, lo que favorece a los índices) o IDs de 64 bits al estilo Snowflake que combinan una marca de tiempo, un número de shard o de máquina y un contador. Incluir el número de shard lógico en el ID tiene una ventaja extra: con solo un ID de pedido, el router sabe dónde buscar sin preguntar a nadie.
El diagrama de arquitectura
Contenido del diagrama
- Order service
- Shard router
- Shard map
- Host 1: shards 0-255
- Host 2: shards 256-511
- Host 3: shards 512-767
- Host 4: shards 768-1023
- Host 5: shards 896-1023
- Analytics warehouse
- query + key
- cached lookup
- move shards 896-1023
- CDC from all hosts
Cómo leerlo:
- Izquierda: el servicio de pedidos envía cada consulta con un ID de cliente al router de shards.
- Centro: el router calcula el hash del ID de cliente hacia uno de 1024 shards lógicos y encuentra el host en el mapa de shards en caché (discontinuo).
- Derecha: cuatro hosts Postgres tienen 256 shards lógicos cada uno. El host 4 está moviendo su mitad superior a un nuevo host 5: el paso de resharding en curso.
- Arriba a la derecha: los informes que abarcan varios clientes leen un almacén analítico alimentado por change data capture, así que nunca se reparten entre shards.
- El bloque Markdown enumera las reglas que debe seguir quien escriba consultas.
Los costes que aceptas
El diagrama de arquitectura SaaS multiinquilino muestra la variante de este diseño con un shard por inquilino, en la que los compromisos de abajo se aplican por inquilino.
- Las transacciones entre shards se convierten en transacciones distribuidas o sagas. Diseña para que sean poco frecuentes.
- Las restricciones de unicidad entre shards necesitan un esquema de IDs global en lugar de una secuencia por base de datos.
- Los cambios de esquema se ejecutan en cada shard, así que las migraciones necesitan herramientas y deben tolerar que queden a medias.
- La operación se multiplica: copias de seguridad, actualizaciones y monitorización para cada shard.
Qué poner en un diagrama de sharding
- La clave de shard y el esquema (hash, rango, directorio).
- Los shards lógicos y físicos, si los separas.
- Dónde se hace el enrutamiento: biblioteca, proxy o coordinador.
- El camino de las consultas sin clave, como un almacén de datos o un índice de búsqueda.
- El estado del resharding, cuando hay un movimiento en curso.
Constrúyelo en Archboard
- Inicia sesión con Google o GitHub y crea un diagrama.
- Añade nodos Contenedor del pack Modelo C4 para el servicio y el router de shards, y una Base de datos para el mapa de shards.
- Añade nodos Postgres del pack Datos para los hosts, etiquetados con sus rangos de shards lógicos, y uno más para el host nuevo.
- Añade un Almacén de datos del pack Datos para los informes, alimentado por una arista CDC punteada.
- Dibuja el movimiento de resharding como una arista discontinua y añade un bloque Markdown del pack Básico con las reglas de sharding.
El ejemplo usa 10 nodos de diagrama, dentro del plan Free.
Preguntas frecuentes
¿Qué diferencia hay entre sharding y particionado? El particionado suele consistir en dividir una tabla dentro de un único servidor de base de datos. El sharding reparte los datos entre varios servidores, de modo que cada uno guarda solo una parte.
¿Cómo elijo una clave de shard? Elige el atributo por el que filtran todas las consultas frecuentes y que mantiene juntos los datos relacionados, con muchos valores distintos y carga uniforme, como un ID de inquilino o de cliente.
¿Qué son los shards lógicos? Un número fijo y grande de cubetas de hash que se asignan a menos servidores físicos. Mover shards lógicos enteros entre servidores evita recalcular el hash de cada clave al añadir capacidad.
¿Cómo ejecuto consultas en todos los shards? Evítalas en las rutas críticas. Para los informes, replica los datos en un almacén; para tareas administrativas poco frecuentes, una consulta repartida a través del router es aceptable.
¿Cuándo debo hacer sharding? Cuando el volumen de escritura o el tamaño de los datos superen lo que puede manejar un único primario bien ajustado y la tendencia continúe, después de indexar, escalar verticalmente, añadir réplicas, cachear y dividir por función.