Borg, Spanner y el stack que hace posible la escala de Google


En la Parte 1 describimos el flujo de software del login de Gmail: las 8 capas que un request atraviesa desde el navegador hasta el token de sesión. Pero ese flujo de software corre sobre una infraestructura que es igual de impresionante y menos documentada en español.

Esta parte cubre los tres pilares de infraestructura que hacen posible que el sistema de autenticación de Gmail funcione a escala global sin coordinación centralizada: Borg (el scheduler que inspiró Kubernetes), Spanner (la base de datos distribuida globalmente con consistencia fuerte) y TrueTime (el mecanismo de reloj que hace posible el orden global de transacciones).

👉🏼 Fuentes: Borg paper - Google Research (2015) · Google SRE Book · Spanner paper


Borg: el scheduler que corre el mundo de Google

Antes de que existiera Kubernetes, antes de que Docker fuera popular, Google resolvía el problema de cómo correr cientos de miles de jobs en decenas de miles de máquinas con un sistema interno llamado Borg.

El paper de Borg lo define con precisión: es un cluster manager que corre cientos de miles de jobs, de miles de aplicaciones diferentes, a través de múltiples clusters cada uno con hasta decenas de miles de máquinas. Los servicios de Gmail incluyendo el Auth Service, el Risk Engine y el Token Service de la Parte 1 son jobs de Borg.

Lo que Borg resuelve

El problema que Borg resuelve es la brecha entre "tengo N máquinas disponibles" y "quiero correr M servicios con diferentes requerimientos de CPU, memoria, prioridad y disponibilidad". Sin un scheduler, alguien tendría que decidir manualmente qué corre en qué máquina. A escala de Google, eso es imposible.

Borg hace cuatro cosas simultáneamente para el sistema de autenticación de Gmail:

1. Admission control: decide si hay recursos disponibles para iniciar un nuevo job antes de intentarlo. Si el Auth Service necesita 500 instancias adicionales porque hay un pico de logins en Asia, Borg verifica que hay máquinas disponibles en esa región antes de schedulear.

2. Efficient task packing: empaqueta múltiples servicios en la misma máquina física para maximizar utilización. El Auth Service, el Token Service y el Risk Engine pueden correr en la misma máquina física Borg gestiona el aislamiento con process-level performance isolation para que un servicio no afecte a los otros.

3. Over-commitment: Borg permite que los servicios declaren más recursos de los que realmente usan en promedio, porque la probabilidad de que todos los servicios en una máquina lleguen a su pico simultáneamente es baja. Esto aumenta la utilización global del cluster significativamente.

4. Fault recovery: cuando una máquina falla (y en datacenters a escala de Google, las máquinas fallan constantemente la resiliencia se construye sobre la asunción de que el hardware falla), Borg detecta el fallo y reschedula los jobs afectados en otras máquinas, minimizando el tiempo de recovery.

Borg y Kubernetes: la relación directa

Kubernetes fue creado por ex-ingenieros de Google que trabajaron en Borg. Las abstracciones que conocemos hoy Pods, Services, Deployments, el concepto de declarar el estado deseado y dejar que el sistema converja a él son directamente derivadas de las ideas del paper de Borg de 2015.

La diferencia más relevante para arquitectos de sistemas: Borg opera sobre máquinas físicas bare-metal de Google, con acceso total al hardware. Kubernetes opera sobre VMs o máquinas en cloud providers. Borg tiene décadas de optimizaciones específicas para el hardware de Google que Kubernetes no puede replicar en ambientes genéricos.



Spanner: la base de datos que resolvió lo "imposible"

En teoría de bases de datos distribuidas, el teorema CAP afirma que un sistema no puede garantizar simultáneamente Consistencia, Disponibilidad y tolerancia a Particiones de red. Spanner es lo más cercano que existe a violar ese teorema en condiciones reales.

Spanner es la base de datos globalmente distribuida de Google. Está diseñado para escalar hasta millones de máquinas en cientos de datacenters y billones de filas. Para el sistema de identidad de Gmail, Spanner es la fuente de verdad para cada cuenta de usuario en el mundo.

El problema que Spanner resuelve

Antes de Spanner, Google usaba MySQL con sharding manual para algunos servicios. El paper de Spanner documenta el caso de F1, el backend de publicidad de Google: el equipo tenía que limitar el crecimiento en MySQL almacenando algunos datos en tablas externas, lo que comprometía el comportamiento transaccional y la capacidad de hacer queries cross-table. Reparticionar MySQL requería mover datos entre servidores un proceso complejo y de alto riesgo que no podían hacer regularmente.

Spanner resuelve eso con replicación automática multi-región, transacciones distribuidas globalmente consistentes, y failover automático que es prácticamente invisible para las aplicaciones.

Cómo Spanner garantiza consistencia global

El mecanismo central es Paxos sobre múltiples réplicas. Cada fragmento de datos (shard) de Spanner tiene múltiples réplicas en diferentes datacenters. Para que una escritura sea confirmada, debe ser aceptada por un quórum de réplicas usando el protocolo de consenso Paxos.

Una réplica es elegida como líder de Paxos y es responsable de coordinar las escrituras. Las réplicas siguidoras manejan las lecturas. Si el datacenter del líder falla, Paxos elige un nuevo líder automáticamente entre los followers sin intervención humana.

Para el login de Gmail esto significa: si el servidor que maneja el update de "último login exitoso" del usuario falla a mitad de la operación, Spanner garantiza que la transacción o se completó en todas las réplicas o no se completó en ninguna. No hay estados inconsistentes.

Two-Phase Commit para transacciones distribuidas

Cuando una transacción toca datos en múltiples shards (por ejemplo, actualizar el estado de la cuenta Y agregar una entrada al log de auditoría en una tabla diferente), Spanner usa Two-Phase Commit (2PC):

  1. Prepare phase: el coordinador contacta a todos los shards involucrados. Cada shard confirma que puede commitear (tiene los locks necesarios, no hay conflictos).
  2. Commit phase: si todos los shards dijeron sí, el coordinador envía la señal de commit. Si cualquier shard dijo no, toda la transacción se aborta.

La atomicidad garantiza que si el proceso de login actualiza el contador de intentos fallidos Y resetea el timestamp de "último login", ambas operaciones ocurren juntas o ninguna ocurre.


TrueTime: el reloj que hace posible el orden global

El problema más difícil en sistemas distribuidos no es la consistencia es el tiempo. Los relojes de las máquinas derivan. En un sistema distribuido global donde una transacción puede tocar servidores en São Paulo, Dublín y Tokio simultáneamente, ¿cómo sabes el orden en que ocurrieron dos eventos?

La solución de Google es TrueTime: una API que expone el tiempo actual con un intervalo de incertidumbre explícito. En lugar de decir "son las 14:32:45.123", TrueTime dice "el tiempo actual está entre 14:32:45.118 y 14:32:45.128" un intervalo de 10 milisegundos de incertidumbre.

La implementación de TrueTime

TrueTime usa dos fuentes de tiempo combinadas en cada datacenter de Google:

  • Relojes atómicos GPS: antenas GPS que reciben señal de los satélites con precisión de nanosegundos
  • Relojes atómicos Cesio: relojes de Cesio locales que no dependen de señal externa

Los dos tipos se combinan con un algoritmo que detecta cuando uno de los dos diverge. La incertidumbre típica de TrueTime es de 1 a 7 milisegundos. En condiciones de red congestionada puede subir a 14 milisegundos y el sistema lo sabe, porque la incertidumbre es explícita.

Cómo Spanner usa TrueTime para consistencia causal

Cuando Spanner commitea una transacción, asigna un timestamp usando TrueTime. El protocolo garantiza que si la transacción T1 commitea antes que T2, el timestamp de T1 es menor que el de T2. Para garantizar esto, Spanner espera hasta que el límite superior del intervalo de incertidumbre de TrueTime ha pasado antes de confirmar el commit lo que se llama commit wait.

En la práctica: Spanner espera entre 1 y 14 milisegundos adicionales después de cada commit para garantizar el orden global. Ese es el precio de la consistencia externa real. Para un login de Gmail, ese delay es invisible para el usuario pero garantiza que si dos instancias del Auth Service en diferentes continentes procesan el mismo usuario simultáneamente, el estado final de Spanner es coherente.


La interacción de los tres sistemas en un login

En el flujo de autenticación de la Parte 1, los tres sistemas interactúan así:

Borg decidió cuántas instancias del Auth Service, Risk Engine y Token Service están corriendo en este momento, en qué máquinas, con qué garantías de recursos. Cuando hay un pico de logins, Borg puede escalar horizontalmente en segundos sin intervención humana.

Spanner guarda el registro de identidad del usuario que el Auth Service consulta, el estado de su cuenta que el Risk Engine evalúa, y el refresh token que el Token Service persiste. Cada una de esas operaciones es una transacción globalmente consistente.

TrueTime garantiza que el timestamp del login que se registra en el log de auditoría del usuario en Spanner tiene un orden causal correcto respecto a todos los otros eventos del sistema incluso si el log se escribe desde un servidor en Brasil y los datos de sesión se actualizan desde un servidor en Irlanda.


Las lecciones para arquitectos de sistemas

Tres principios de esta infraestructura que aplican directamente a sistemas de menor escala:

1. El tiempo es un problema de primera clase. En cualquier sistema distribuido, asumir que los relojes están sincronizados es un error. NTP tiene una precisión de decenas de milisegundos en condiciones normales. Para sistemas que necesitan ordering causal real, es necesario mecanismos explícitos TrueTime en Google, Hybrid Logical Clocks en otros sistemas, o simplemente diseñar para tolerancia a eventos desordenados.

2. El scheduler es parte de la arquitectura. No es un detalle operacional es una decisión arquitectónica. La capacidad de Borg de reschedulear jobs automáticamente es lo que permite que el Auth Service de Gmail no tenga un SPOF. En el contexto de LATAM con Ab4cus, Kubernetes sobre DigitalOcean cumple un rol equivalente más limitado pero con el mismo principio.

3. La base de datos define los límites del sistema. Spanner permite que el sistema de identidad de Gmail escale horizontalmente sin sharding manual porque el sharding es automático. En sistemas que no tienen ese lujo, las decisiones de schema y particionamiento de PostgreSQL toman el lugar de esa abstracción.


Lo que sigue en la Parte 3

La tercera parte cierra la serie con los dos sistemas más sofisticados del stack: Dapper el sistema de distributed tracing que permite observar qué pasa en cada milisegundo de un login y el Risk Engine en detalle cómo Google distingue a un usuario real de un bot o un atacante con credenciales robadas.

💥 Evaluar la arquitectura de tu sistema con Ab4cus

Publicar un comentario

0 Comentarios