El problema fundamental que resuelve esta arquitectura es la escalabilidad vertical de un sistema de control de versiones distribuido (Git) para soportar cargas de trabajo intensivas de escritura en un único repositorio, un desafío exacerbado por el auge del desarrollo impulsado por agentes (AI agents). Tradicionalmente, Git, aunque distribuido, tiene un modelo de objetos y referencias que implica una fuerte coordinación para las actualizaciones de referencias, lo que limita el rendimiento de escritura en un solo repositorio.
La tesis central es que la mayoría de las operaciones de escritura en Git (almacenamiento de objetos) son inherentemente inmutables y pueden ser concurrentes sin coordinación, mientras que solo una pequeña porción (actualizaciones de referencias) requiere consenso y ordenación. Al desacoplar estos dos aspectos y optimizar cada uno para sus patrones de acceso, GitHub puede escalar las escrituras y lecturas de manera significativa, manteniendo la semántica de Git para los usuarios.
Este enfoque contrasta con arquitecturas monolíticas o fuertemente acopladas donde la lógica de almacenamiento de objetos y la gestión de referencias residen en el mismo componente, creando cuellos de botella de coordinación y computación. La necesidad de esta evolución surge de la proyección de que los repositorios individuales se volverán exponencialmente más activos con la adopción masiva de agentes de desarrollo.
Arquitectura del Sistema
La nueva arquitectura, denominada "Project Rubicon", se basa en dos principios: minimizar la coordinación y desacoplar el almacenamiento de la computación. Los componentes clave son Spokes, Virtual Replicas, Azure Blob Storage y Ref-CAS.
Spokes actúa como un balanceador de carga y enrutador, dirigiendo las solicitudes de Git a un grupo de Virtual Replicas asignadas a un repositorio. Las Virtual Replicas son un pool de computación desechable que sirve lecturas y escrituras. Su disco local funciona como una caché que puede reconstruirse en cualquier momento, lo que permite su escalado elástico y mejora la tolerancia a fallos. La corrección del sistema no depende de que una solicitud llegue a una réplica específica.
El estado duradero se divide: los objetos Git (packs y datos auxiliares de aceleración de lectura) residen en Azure Blob Storage, aprovechando su durabilidad, replicación y alto throughput para escrituras distribuidas. Las referencias (ramas, tags) y el manifiesto de packs (lista de packs que componen el repositorio) se almacenan en Ref-CAS, un servicio de log replicado dedicado. Ref-CAS implementa un consenso de tipo compare-and-swap (CAS) para cada actualización de referencia, garantizando la atomicidad y el orden. Cada commit en Ref-CAS recibe un Log Sequence Number (LSN), que sirve como versión del repositorio para las lecturas. La compactación de packs se realiza en nodos de compactación separados, que operan directamente sobre Blob Storage y utilizan Ref-CAS para notificar a las Virtual Replicas sobre el estado evolutivo del repositorio, desacoplando así la computación intensiva de la compactación del servicio de solicitudes en las Virtual Replicas.
Un flujo de escritura implica que una Virtual Replica indexa el pack entrante, lo sube a Blob Storage, y luego realiza una transacción en Ref-CAS para listar el pack en el manifiesto y actualizar las referencias. Un flujo de lectura implica que una Virtual Replica verifica su versión de referencia con Ref-CAS, descarga los packs necesarios de Blob Storage a su caché y sirve la lectura. Ref-CAS solo almacena punteros a los objetos, no los objetos en sí, asegurando que los objetos ya sean durables en Blob Storage antes de que una referencia apunte a ellos.
Flujo de Escritura (Push)
- 1 Cliente Git Envía un push con nuevos objetos y referencias.
- 2 Spokes Enruta la solicitud a una Virtual Replica.
- 3 Virtual Replica Indexa el pack entrante.
- 4 Virtual Replica Sube el pack a Azure Blob Storage.
- 5 Virtual Replica Comite una transacción CAS en Ref-CAS (actualiza referencias y manifiesto).
- 6 Ref-CAS Aplica la transacción con consenso de quórum, asigna LSN.
- 7 Compaction Node (async) Fusiona packs en segundo plano para optimizar lecturas.
Flujo de Lectura (Fetch)
- 1 Cliente Git Envía una solicitud de fetch.
- 2 Spokes Enruta la solicitud a una Virtual Replica.
- 3 Virtual Replica Verifica la versión de referencia actual con Ref-CAS (LSN).
- 4 Ref-CAS Responde con la versión actual y referencias si la réplica está desactualizada.
- 5 Virtual Replica Descarga packs necesarios de Azure Blob Storage a su caché local.
- 6 Virtual Replica Sirve la lectura desde la caché.
| Capa | Tecnología | Justificación |
|---|---|---|
| storage | Azure Blob Storage | Almacenamiento duradero y replicado para objetos Git (packs, índices, aceleradores de lectura). Elegido por su alta disponibilidad, durabilidad, bajo costo por byte y alto throughput agregado para escrituras distribuidas. |
| storage | Ref-CAS (Reference Compare-and-Swap) | Servicio de log replicado dedicado a la gestión de referencias Git y manifiestos de packs. Proporciona consistencia fuerte y ordenación para las actualizaciones de referencias mediante un consenso de quórum y operaciones compare-and-swap. vs Write-ahead log para todas las referencias en un solo blob (limitado a cientos de escrituras/segundo), Dividir referencias en múltiples blobs (trade-off de latencia de lectura por escritura) |
| compute | Virtual Replicas | Flota de computación desechable que sirve solicitudes de lectura y escritura. Su disco local es una caché reconstruible, permitiendo escalado elástico y tolerancia a fallos. Desacopladas de la compactación. |
| compute | Compaction Nodes | Nodos dedicados que realizan la compactación de packs en segundo plano, operando directamente sobre Azure Blob Storage y Ref-CAS. Desacoplan la computación intensiva de la compactación de los nodos de servicio de tráfico. |
| networking | Spokes | Servicio de enrutamiento y balanceo de carga para solicitudes de clientes Git, API y UI web. También gestiona la partición, aislamiento y equidad del tráfico entre tenants. |
Trade-offs
Ganancias
- ▲▲ Vertical scalability for writes on a single repository
- ▲ Read throughput and latency (especially for unchanged repositories)
- ▲ Fault tolerance and recovery time
- ▲ Independent scaling of components (read/write compute, storage, compaction)
Costes
- △ Increased architectural complexity (introducing Ref-CAS)
Fundamentos Teóricos
El problema de la coordinación en sistemas distribuidos y la gestión de estado concurrente es un tema central en la informática distribuida, con raíces en trabajos fundamentales como el algoritmo Paxos de Leslie Lamport (1990) o Raft. La decisión de GitHub de minimizar la coordinación y desacoplar el almacenamiento de objetos inmutables de las referencias mutables refleja principios de diseño de sistemas distribuidos que buscan evitar cuellos de botella de consenso global. La inmutabilidad de los objetos Git se alinea con el concepto de Content-Addressable Storage (CAS), donde los datos son identificados por un hash de su contenido, permitiendo escrituras concurrentes sin colisiones. La gestión de referencias como un log replicado con compare-and-swap es una aplicación directa de los principios de un Write-Ahead Log (WAL) y un sistema de consenso distribuido, donde solo las operaciones que modifican el estado compartido (las referencias) requieren un acuerdo de quórum, similar a cómo las bases de datos distribuidas gestionan sus metadatos o logs de transacciones. La separación de la computación de la compactación de los nodos de servicio es un patrón común en sistemas de almacenamiento a gran escala, como los que utilizan LSM-trees, donde la compactación (merging de SSTables) es una tarea de fondo intensiva en I/O y CPU que se desacopla de las operaciones de lectura/escritura en primer plano.