🔎 Buscar

🌐 Sistemas distribuidos

Qué es un sistema distribuido, el teorema CAP, fallos y parcial, replicación, particionado, consistencia, consenso (Raft/Paxos), relojes y qué leer a continuación. Con ejemplos y práctica.

Fundamentos CS📖 Contenido

Sistemas distribuidos

Un sistema distribuido es un conjunto de computadoras independientes que colaboran y que al usuario le parecen una sola máquina. Google, tus bases de datos en la nube, un backend con varios nodos, Kafka, Kubernetes: todos son sistemas distribuidos.

Lo que cambia todo es una frase: cualquier cosa puede fallar en cualquier momento. Una máquina se cae, la red se corta, un mensaje llega tarde o se pierde. El ingeniero de distribuidos diseña sistemas que siguen funcionando bien a pesar de los fallos — no asumiendo que no pasarán.

💡 La frase de Leslie Lamport: «Un sistema distribuido es aquel en el que el fallo de una computadora que no sabías que existía puede inutilizar la tuya». Diseñar bien = hacer que eso no pase.

El problema fundamental: los fallos

En una sola máquina, todo es instantáneo y consistente (una variable siempre tiene su valor). Distribuido, aparece lo imposible de saber:

  • ¿El nodo B está caído, o solo lento? (No hay forma de distinguir sin esperar).
  • ¿Mi mensaje llegó? ¿En qué orden? (La red no garantiza entrega ni orden).
  • ¿Qué versión de los datos es la correcta? (Cada nodo ve una parte distinta).
Fallo Descripción Ejemplo
Fallos parciales Parte del sistema funciona, otra no Un nodo de 5 se cae
Partición de red Nodos que no pueden hablar entre sí Dos centros de datos desconectados
Fallos de proceso El programa muere (crash) El worker se muere a mitad
Fallos byzantinos Nodos que se comportan mal (mienten, corrompen) Nodo comprometido (malicioso)
Fallos temporales / tiempo de espera Un nodo “desaparece” y reaparece Timeout mal configurado

⚠️ Fallos byzantinos son los de la seguridad: nodos que mienten. La mayoría de sistemas (Raft, etc.) asumen fallos crash (el nodo se cae pero no miente). Los byzantinos se resuelven con consenso bizantino (blockchain).

El teorema CAP

CAP es la afirmación más famosa de los distribuidos: de las tres propiedades, un sistema distribuido solo puede garantizar dos a la vez:

Letra Propiedad Significado
C Consistencia Todos los nodos ven los mismos datos al mismo tiempo
A Disponibilidad El sistema responde siempre (cada petición tiene respuesta)
P Tolerancia a particiones El sistema sigue funcionando aunque se parta la red

La regla de oro: cuando la red se parte (P ocurre), tienes que elegir entre C y A:

  • CP (consistencia): durante una partición, prefieres negar el servicio (o devolver error) a devolver datos viejos. → Eliges datos correctos. PostgreSQL replicado, ZooKeeper, MongoDB (por defecto).
  • AP (disponibilidad): durante una partición, prefieres seguir respondiendo, aunque cada lado vea datos distintos (que se reconciliarán después). → Eliges que siga funcionando. Cassandra, DynamoDB, sistemas de mensajería.

⚠️ CAP no es «elegir 2 de 3»: en condiciones normales (sin partición) un sistema puede dar C y A. CAP solo importa cuando hay una partición (que tarde o temprano pasa). Por eso todos los sistemas modernos son eventually consistent en algún nivel y usan P fijo: la decisión real es CP vs AP.

Consistencia: de fuerte a eventual

La consistencia describe qué tan actualizados están los datos que lees.

Nivel Qué ve el lector Ejemplo
Fuerte (linearizable) Siempre el último dato escrito Sistema bancario, elecciones de líder
Lecturas consistentes Ve su propia escritura (read-your-writes) Perfil de usuario
Lectura-caída (stale reads) Puede ver datos viejos un tiempo Caché
Eventual Los datos se actualizan… eventualmente DNS, réplicas, feeds
Consistencia fuerte:
  Escribe ▶ [nodo1] ──▶ [nodo2] (espera confirmación antes de responder)
  Lee desde cualquier nodo → siempre lo último

Consistencia eventual:
  Escribe ▶ [nodo1] ──▶ (async) ──▶ [nodo2]
  Leo de nodo2 → puede estar un paso atrás unos milisegundos

💡 El precio de la consistencia fuerte es latencia (esperas a que los demás nodos confirmen) y menos disponibilidad durante particiones. Por eso los sistemas reales mezclan: fuerte para lo crítico, eventual para lo que puede esperar.

Replicación

Replicar es tener copias de los datos en varios nodos. Motivos: disponibilidad (si un nodo muere, otros sirven) y escala de lectura (más nodos = más lecturas por segundo).

Líder-seguidor (primary-replica)

El líder recibe todas las escrituras; los seguidores replican y atienden lecturas.

        Escribe ──▶ [Líder]
                       │  (replica)
          ┌────────────┼────────────┐
          ▼            ▼            ▼
      [Follower]   [Follower]   [Follower]
        Lee          Lee          Lee
  • Escrituras: todas al líder (escalable para lectura, un solo punto para escritura).
  • Síncrono vs asíncrono: con replicación síncrona, el líder espera a que el seguidor confirme (más seguro, más lento). Con asíncrona, el líder responde sin esperar (más rápido, riesgo de perder datos si cae el líder).

⚠️ Failover: si el líder muere, un seguidor debe promoverse a líder. Decidir cuál (sin que haya dos líderes a la vez — split-brain) es un problema de consenso.

Multi-líder y sin líder

  • Multi-líder: varias réplicas aceptan escrituras (útil con múltiples regiones, pero aparecen conflictos de escritura que hay que resolver).
  • Sin líder (peer-to-peer): cualquier nodo acepta escrituras (DynamoDB, Cassandra). Conflictos resueltos con quórum: escribir en N nodos, leer de R nodos; si R + W > N, siempre lees el dato más reciente.

Particionado (sharding)

Cuando los datos ya no caben o no aguantan el tráfico en un solo nodo, se particiona: cada nodo guarda una parte de los datos.

Usuarios por ID:
  [0-1000]   [1001-2000]   [2001-3000]
   nodo A      nodo B        nodo C
  • Por rango: IDs 0-1000 en A, etc. Simple, pero puede sesgar (hot spots) y el rango puede moverse.
  • Por hash: hash(user_id) % N decide el nodo. Distribución uniforme, pero difícil de rebalancear (por eso se usa consistent hashing).
  • Por claves naturales: por región, por tenant (multi-tenancy).

⚠️ El precio del sharding: las consultas que cruzan particiones (JOINs, transacciones multi-nodo) se complican. El diseño del clave de partición es una de las decisiones más importantes (y difíciles de cambiar después) de system design.

Consenso: ponerse de acuerdo

El problema del consenso: varios nodos deben acordar un mismo valor (por ejemplo, quién es el líder) aunque haya fallos y red lenta. Sin consenso, dos nodos podrían creer cada uno que es líder → split-brain (dos líderes, datos que se contradicen).

Raft y Paxos

  • Paxos (Lamport): el algoritmo teórico original, famoso por difícil de entender.
  • Raft: la versión práctica y legible (lo usan etcd, Consul, CockroachDB, MongoDB). Separa el consenso en: elección de líder, replicación de log, seguridad.

Cómo decide Raft quién es líder (resumen):

  1. Cada nodo tiene un término (contador de elecciones) y un timeout de elección aleatorio.
  2. El nodo cuyo timeout expira se candidato y pide votos a los demás.
  3. Gana si consigue mayoría (más de la mitad) de los votos.
  4. El líder replica su log a los seguidores; si la mayoría confirma, el valor está committed.
Candidato ──▶ pide voto a todos
Mayoría de votos ──▶ LÍDER (solo puede haber uno por término)

💡 Por qué «mayoría»: con más de la mitad, no puede haber dos líderes en el mismo término (dos mayorías se solapan en al menos un nodo). Esa propiedad es el corazón del consenso: mayoría = exclusión mutua garantizada.

Uso real: etcd y ZooKeeper guardan la configuración de Kubernetes y otros sistemas; PostgreSQL y MongoDB usan consenso para el failover del líder. Cuando veas «distributed consensus», piensa: elegir un líder / acordar un orden de forma segura.

Relojes y ordenamiento

En distribuidos, no hay un reloj global. Cada máquina tiene su reloj, y se desincronizan. ¿Cómo sabes qué escritura fue «después» de cuál?

  • Relojes físicos (NTP): se sincronizan por red, pero con deriva (ms de error). No sirven para ordenar con exactitud.
  • Relojes lógicos (Lamport): un contador por nodo; cada evento incrementa el reloj. Si e1 < e2 en los relojes, e1 pasó antes que e2. Da un orden parcial.
  • Vector clocks: generalizan a Lamport: cada nodo sabe «qué han visto los demás». Permiten detectar conflictos de escritura concurrentes (los usa Cassandra/DynamoDB).
  • Timestamps híbridos: combinan físico + lógico (los usa CockroachDB, Spanner).

⚠️ Frase para recordar: «el que escribió el timestamp no sabe nada del que lo leyó». En distribuidos, no ordenas por hora de reloj: ordenas por orden causal (Lamport, vector clocks) o por consenso (orden total del log).

Cheatsheet de conceptos

Término En una frase
Sistema distribuido Varias máquinas que parecen una sola
Nodo Una máquina del sistema
Partición Corte de red entre nodos
Replicación Copias de los datos en varios nodos
Particionado (sharding) Cada nodo guarda una parte de los datos
Líder / seguidor Quién acepta escrituras / quién replica
Failover Cambio automático al nuevo líder
Split-brain Dos líderes a la vez (muy malo)
Quórum Mayoría necesaria para decidir
Consenso Nodos acordando un valor (Raft, Paxos)
Consistencia fuerte Todos ven lo último inmediatamente
Consistencia eventual Los datos convergen… eventualmente
CAP Consistencia / Disponibilidad / Particiones
CP vs AP Elegir entre correcto o disponible durante partición
Reloj lógico Ordenar eventos sin reloj global
Timeout / retry Esperar y reintentar ante fallos

Práctica propuesta

  1. Levanta 3 instancias de Redis (o PostgreSQL) con replicación. Escribe en el líder y lee de un seguidor. Observa la eventual consistency.
  2. Simula una partición de red (bloquea un puerto con firewall o desconecta un contenedor) y observa qué pasa con las peticiones: ¿CP o AP es tu sistema?
  3. Ejecuta un clúster de etcd (o un Raft simple con Go) y mata el líder. Observa cómo los seguidores eligen otro (consenso).
  4. Lee el paper de Raft (raft.github.io) con la animación interactiva. Explica el split-brain en una frase.
  5. Diseña (en papel) un sistema de likes que deba funcionar ante una partición: ¿CP o AP? ¿Cómo lo reconcilias después?

Para profundizar

Estudio · Recursos de todo el mundo (inglés, chino, japonés, español, francés, ruso…) curados y traducidos al español.