Escalar rápido el almacenamiento online para más de mil millones de usuarios de ChatGPT (parte II)
Cómo optimizamos Azure Cosmos DB en Habitat, nuestra plataforma de almacenamiento para aplicaciones, para gestionar un crecimiento sin precedentes.
Todos los productos de OpenAI necesitan un acceso rápido y fiable a los datos, que proporciona nuestra plataforma de almacenamiento, Habitat. Debe responder en milisegundos a más de mil millones de usuarios de 40 regiones geográficas. Nuestra infraestructura se enfrentaba a un reto extraordinario: dar soporte a un crecimiento explosivo y a nuevos casos de uso sin dejar de mejorar la fiabilidad, el rendimiento y la rapidez con la que trabajan los desarrolladores de producto. Resolver ese reto exigió replantear el diseño y el funcionamiento de nuestra plataforma de almacenamiento online. Evaluábamos constantemente las ventajas y las contrapartidas, siguiendo este orden: primero, alcanzar la fiabilidad necesaria para el tráfico crítico de los productos; después, la velocidad que necesitaban los usuarios de todo el mundo; y, por último, operar con agilidad a una escala masiva.
Esta serie de dos partes explica cómo transformamos Habitat de una simple biblioteca cliente y una base de datos en una plataforma de almacenamiento distribuida globalmente que sirve más de 500 petabytes de datos. La parte I se centró en la evolución de Habitat de un cliente Python a un servicio. También abordó las técnicas que nos permitieron llevar un servicio basado en Python mucho más allá de lo que muchos considerarían viable.
En esta entrada, la parte II, explicamos cómo escalamos el componente de almacenamiento subyacente: Azure Cosmos DB. Gracias a una estrecha colaboración con el equipo de Azure, llegamos a un enfoque multiinquilino viable basado en contenedores gestionados conjuntamente, con un excelente rendimiento de lectura a escala masiva y global.
Figura 01 · ¿Qué es Habitat?
Plataforma de almacenamiento en línea
Habitat es la plataforma de almacenamiento en línea que creamos para que los productos de OpenAI accedan a la información necesaria con rapidez y fiabilidad.
- Solicitud
- Respuesta
- Cambios (CDC)
A medida que las empresas crecen, los equipos de infraestructura suelen pasar de operar sistemas de inquilino único a sistemas multiinquilino. En los sistemas de inquilino único, cada equipo responsable de un área de producto mantiene su propio sistema. Esto reduce el alcance de los incidentes y facilita la delimitación de responsabilidades y el aislamiento de las cargas de trabajo. A medida que crecen los equipos y las áreas de producto, este enfoque resulta costoso de mantener. El enfoque de inquilino único hace que cada equipo de producto sea responsable de planificar la capacidad, lo que a menudo conduce a un exceso considerable de aprovisionamiento.
En cambio, el enfoque multiinquilino asigna el control a un equipo centralizado de bases de datos, con más conocimientos y experiencia para aprovisionar recursos. Pero los sistemas multiinquilino generan sus propios problemas, como el de los vecinos ruidosos: un inquilino consume una proporción inusualmente alta de recursos en detrimento de los demás.
En Habitat, tuvimos que sopesar todas estas ventajas y contrapartidas para diseñar un sistema de almacenamiento fiable y eficiente a gran escala. Hoy, Habitat es una capa de base de datos multiinquilino para muchos productos de OpenAI, pero hemos recorrido un camino circular: pasamos de usar un solo contenedor multiinquilino de Azure Cosmos DB a aprovisionar contenedores subyacentes de inquilino único y, finalmente, volvimos a un contenedor multiinquilino como opción predeterminada. Aún estamos al principio de nuestra trayectoria con el enfoque multiinquilino en Habitat. Admitimos un amplio conjunto de casos de uso, pero hemos podido posponer la inversión en este ámbito aprovechando las primitivas integradas de Azure Cosmos DB siempre que ha sido posible.
Antes de repasar nuestra trayectoria con Azure Cosmos DB, conviene conocer algunos conceptos básicos:
Una cuenta de Azure Cosmos DB define un conjunto de contenedores y una política de replicación
Cada contenedor se aprovisiona con un rendimiento determinado, medido en unidades de solicitud por segundo (RU/s)
Los datos de cada contenedor se almacenan mediante la fragmentación habitual por una clave de partición lógica especificada, con límites documentados de almacenamiento y rendimiento por clave
Azure Cosmos DB distribuye las claves de partición lógica entre un número menor de particiones físicas subyacentes. Estas se dividen en varias particiones físicas cuando el almacenamiento supera un umbral o cuando el contenedor necesita más particiones físicas para sostener el rendimiento aprovisionado
Al principio aceptábamos toda la carga de los clientes, confiando en que el límite declarado de 10 000 RU/s por clave de partición lógica proporcionaría contrapresión. Además, cuando empezamos, solo usábamos un contenedor predeterminado de Azure Cosmos DB en cada cuenta. Esto funcionaba razonablemente bien, pero resultó problemático por varios motivos:
Debido a decisiones iniciales sobre la API, permitimos que los clientes seleccionaran directamente las claves de partición lógica. Como resultado, se producen colisiones frecuentes entre distintos casos de uso de producto en claves de partición habituales, como user_id o workspace_id. Como estos casos de uso compartían los límites de Azure Cosmos DB para las mismas claves de partición lógica, el diseño restringía el rendimiento total disponible para cada usuario.
Antes de migrar a Habitat y Azure Cosmos DB, un problema habitual al escalar Postgres era que un gran número de solicitudes de una organización o clave con muchísima actividad —un inquilino que generaba una carga desproporcionada— podía dejar fuera de servicio toda la base de datos. Dedicamos un gran esfuerzo colectivo a almacenar esas claves en caché e incorporar mecanismos de concesión temporal ante los fallos de caché, para que la carga resultante no saturase la base de datos subyacente.
Figure 02a · Logical partition key limits
Different clients, the same partition key
Aunque los límites documentados de tamaño de datos y rendimiento se refieren a las claves de partición lógica, en realidad se aplican en la partición física. En la práctica, esto significa que las particiones lógicas no pueden alcanzar las 10 000 RU/s. En cambio, comparten los límites de la partición física con todas las demás claves de partición lógica alojadas en ella.
Esto permitía que los vecinos ruidosos afectaran a muchas claves de partición lógica sin relación entre sí: las cargas que operaban sobre datos de funciones especializadas del producto alteraban los flujos esenciales de inicio de sesión y registro.
Figure 02b · Noisy neighbors
Different users, the same physical partition
El límite de rendimiento de una partición física también es variable y depende del rendimiento total asignado al contenedor de Azure Cosmos DB. El rendimiento aprovisionado del contenedor se reparte de forma aproximadamente uniforme entre sus particiones físicas.
A medida que crece el volumen de datos, las particiones físicas se dividen y aumenta el número total de particiones, mientras el rendimiento total aprovisionado permanece igual. Como resultado, el límite efectivo de rendimiento por partición disminuye a medida que crece el tamaño de los datos.
En los casos de uso que más almacenamiento consumen, similares al almacenamiento de blobs, esto genera un tipo de fallo en el que el crecimiento del almacenamiento por sí solo reduce la capacidad de rendimiento de las cargas activas, aunque las tasas de solicitudes y el uso se mantengan estables.
Figure 02C · Weak partitions
The limit falls below demand
A partition splits when it reaches its storage limit. Each child receives half the throughput capacity.
Los contenedores separados ayudan a resolver parcialmente estos límites de las claves de partición y los problemas de vecinos ruidosos. Al usar contenedores separados, cada uno puede tener sus propias particiones físicas independientes. Así, solo las distintas cargas de ese mismo contenedor pueden actuar como vecinos ruidosos o coincidir en el espacio de claves de partición. La contrapartida es que aprovisionar nuevos contenedores conlleva trabajo adicional: cada uno requiere una planificación individual de capacidad. Por eso, queremos crearlos solo cuando tenga sentido delimitar un servicio o caso de uso.
Empezamos a usar contenedores separados de Azure Cosmos DB para los nuevos casos de uso más críticos que requerían un aislamiento sólido. Combinamos este enfoque con un script que gestionaba las particiones débiles ajustando el rendimiento total aprovisionado de cada contenedor a su número de particiones físicas, y así evitamos en gran medida todos los problemas que teníamos.
Sin embargo, como habíamos empezado con un contenedor predeterminado, muchos casos de uso críticos heredados quedaron atrapados en él, a falta de una migración de datos. Para proteger los servicios críticos que aún dependían de los datos del contenedor compartido predeterminado, solíamos recomendar a los equipos que crearan contenedores separados para los nuevos servicios o las funciones de producto importantes. A medida que crecíamos, aumentaban tanto la presión sobre el contenedor predeterminado como los incidentes en producción. Empezamos a aprovisionar contenedores para cualquier servicio nuevo o función de producto de gran tamaño, simplemente para evitar que el contenedor predeterminado recibiera más carga.
Esto nos evitó muchas caídas de todo el sitio, al limitar el alcance de los incidentes a la degradación de funciones o servicios concretos. Sin embargo, el trabajo adicional de aprovisionar nuevos contenedores acabó pasándonos factura:
En el antiguo contenedor compartido predeterminado, era poco probable que un caso de uso nuevo que pasara de 0 a 1 millón de QPS alterara de forma significativa el uso agregado total. En un contenedor aislado, en cambio, pasar de 0 a 1 millón de QPS podía multiplicar por 1000 la carga de referencia, que hasta entonces procedía únicamente de pruebas de uso internas.
Con los contenedores dedicados, los equipos debían acordarse de aprovisionar de antemano el rendimiento previsto para sus lanzamientos. A menudo, los equipos de producto ponían sus funciones en producción y olvidaban ampliar la capacidad de antemano. El día del lanzamiento acabábamos reunidos para gestionar incidentes graves e intentando ampliar los contenedores en el último momento.
Mezclar cargas de trabajo es una ventaja fundamental de los sistemas multiinquilino, a la que renunciamos con esta estrategia de contenedores a cambio de un mejor aislamiento.
Figure 03 · Lack of stable aggregate growth
The same workload, different headroom
1K RU/s during load testing → 1M RU/s at launch
Con el tiempo, supervisar el uso de los contenedores dedicados también exigía un conocimiento profundo del producto para saber cuándo cambiaría o aumentaría el tráfico.
Podemos proporcionar un script básico del plano de control para aumentar el rendimiento aprovisionado de cada contenedor según las tendencias de crecimiento. Pero, sin un crecimiento agregado estable, ajustar correctamente la capacidad implicaba involucrar en su planificación a prácticamente todos los equipos de producto de OpenAI.
Este enfoque no escaló a nivel organizativo: el grado de atención que cada equipo responsable de un servicio prestaba al aprovisionamiento de Azure Cosmos DB variaba enormemente.
A medida que la organización crecía, resultaba cada vez más difícil gestionar esos problemas operativos. La falta de un único equipo central de planificación hizo que muchos equipos planificaran mal. Por ello, acabamos volviendo a una solución multiinquilino y colaboramos estrechamente con el equipo de Azure para corregir los problemas originales de este enfoque mediante un diseño multiinquilino de recursos compartidos:
Limitar primero las solicitudes de las claves con más actividad impide que los vecinos ruidosos consuman todo el rendimiento disponible de una partición física. Esto reduce el efecto del vecino ruidoso, por el que una sola clave muy activa puede afectar a todo el sitio.
Del mismo modo, la QoS basada en niveles de solicitudes impide que las cargas de trabajo no interactivas, como las inserciones masivas o las extracciones de datos, utilicen todo el rendimiento de una partición física. Al asignar una prioridad menor a las solicitudes de estas cargas, se limitan primero, lo que evita limitar las solicitudes interactivas de mayor prioridad que atienden a los usuarios finales.
Azure Cosmos DB ya contaba con un modo sin servidor que habría resuelto nuestro problema de particiones débiles en el modo aprovisionado. Sin embargo, tenía una gran desventaja: solo escalaba según el uso del almacenamiento y limitaba el consumo de RU a 5000 RU/s por partición física. Esto resolvería el problema de las particiones débiles, pero nos impediría ampliar la capacidad de los casos de uso con un consumo intensivo de RU.
El equipo de Azure Cosmos DB desarrolló para nosotros un nuevo modo sin servidor mejorado. Permitía que cada partición física alcanzara las 10 000 RU/s e incorporaba divisiones basadas en el consumo de RU, además de las basadas en el uso del almacenamiento. Gracias a ello, dejamos de supervisar y ampliar los contenedores manualmente.
Con estos cambios, hemos podido volver a usar un único contenedor compartido. Esto ha simplificado considerablemente la planificación de capacidad, tanto inicial como continua, para los equipos de producto, sin perder el aislamiento entre cargas de trabajo. En los meses transcurridos desde entonces, no hemos tenido incidentes de aprovisionamiento ni de vecinos ruidosos, pese a la aceleración del desarrollo de productos.
Cuando las empresas alcanzan la escala de OpenAI, los servicios gestionados dejan de estar tan «gestionados». Muchas cargas de trabajo se convierten en casos atípicos dentro de la infraestructura del proveedor de nube. Cuando OpenAI se convirtió en uno de los mayores usuarios de Azure Cosmos DB, operarlo con éxito exigió un enfoque distinto: pruebas y paneles compartidos, canales directos entre equipos de ingeniería y responsabilidad conjunta sobre los tipos de fallo que solo aparecen a nuestra escala. Hoy, nuestra mayor cuenta de Azure Cosmos DB almacena decenas de petabytes de datos y atiende más de 20 millones de QPS. Hasta donde sabemos, somos la única empresa que ha desplegado Azure Cosmos DB a esta escala.
A finales de 2024, una caída regional dejó claro por qué era necesaria esta colaboración. Un corte eléctrico afectó a la región principal de Azure de una de nuestras mayores cuentas de Azure Cosmos DB. Durante la conmutación por error que siguió, descubrimos que nuestras cuentas más grandes tardarían varias horas en pasar a una región secundaria, algo que ni nuestro equipo ni el de Azure Cosmos DB habían probado a nuestra escala.
Alrededor de un mes después, al devolver esas cuentas a la región original, provocamos otra caída grave. Una avalancha de conexiones a la región original saturó su puerta de enlace de Azure Cosmos DB. Una peculiaridad de cómo el cliente de Azure Cosmos DB en modo de puerta de enlace gestionaba las conmutaciones por error hizo que todos los clientes establecieran conexiones y enviaran solicitudes de inmediato a la región original, aunque solo una parte de las particiones físicas había vuelto a ella.
En cada caída, tanto OpenAI como Azure siguieron sus procesos de gestión de incidentes, identificaron varias causas raíz e implementaron correcciones. Pero estas caídas eran síntomas de un problema sistémico más amplio en la forma en que nuestro equipo y el de Azure Cosmos DB operaban y realizaban pruebas. Al principio, recurrir a servicios gestionados nos permitió avanzar rápido y centrarnos en los objetivos del negocio. A gran escala, los servicios gestionados dejan de estar tan gestionados y exigen una integración profunda con el proveedor en todos los niveles, desde el diseño hasta las operaciones.
Hoy, los equipos de ingeniería de Habitat y Azure supervisan conjuntamente todas las capas de Habitat, desde nuestras capas de servicio hasta las de almacenamiento físico de Azure Cosmos DB. Operamos y probamos los cambios en una cuenta de Azure Cosmos DB del tamaño de la de producción, pero fuera del entorno de producción. Probamos y mejoramos los SDK conjuntamente y definimos las prácticas recomendadas para escalar y dimensionar nuestras cuentas de Azure Cosmos DB. Los equipos de ingeniería tenemos contacto directo a través de Teams e incluso hemos habilitado formas de enviarnos avisos de guardia directamente, sin pasar por los distintos niveles de soporte.
Durante el último año hemos realizado un importante trabajo conjunto para mejorar la escalabilidad del plano de control y de la puerta de enlace de Azure Cosmos DB. Hemos añadido protección frente a la carga y almacenamiento en caché de diversos metadatos de Azure Cosmos DB en su puerta de enlace para proteger la partición de metadatos; reducido la presión de nuestra flota de procesos habitat-service en Python mediante la agrupación y una mayor reutilización de conexiones; ubicado las cargas de trabajo en el mismo lugar cuando ha sido posible; y aislado las cargas críticas de las cargas de trabajo no interactivas mediante distintas VPC.
Este nivel de colaboración en ingeniería ha sido fundamental para la estabilidad de nuestro sistema Azure Cosmos DB durante el último año. Todo sistema lo bastante grande o crítico exige este tipo de trabajo en equipo: derribar las barreras entre responsables y trabajar más allá de los límites organizativos.
Como mencionamos en la parte I, nuestra filosofía básica es: haz que funcione, haz que sea rápido y haz que sea barato. Primero la fiabilidad, después el rendimiento y, por último, la eficiencia. Habitat se había convertido en una infraestructura crítica para OpenAI, por lo que la primera prioridad era garantizar su fiabilidad. A medida que el sistema se estabilizaba en 2025 y OpenAI se expandía por el mundo, la latencia se convirtió en el siguiente obstáculo para los usuarios y los equipos de producto.
Los recursos de cómputo y almacenamiento solían estar en regiones distintas, lo que hacía inevitables las solicitudes entre regiones.
Figure 04 · Improving performance at a global scale
Global traffic
Compute and storage capacity were often located in different regions, making cross-region requests unavoidable.
Las ubicaciones geográficas de los recursos de cómputo y almacenamiento se muestran solo a título ilustrativo.
La latencia variaba mucho según dónde se almacenaban los datos y desde dónde se atendía la solicitud. Para que las solicitudes a Habitat rindieran bien, los desarrolladores de producto recurrían a cachés adicionales en el cliente, agrupaban solicitudes, minimizaban las lecturas y escrituras en la base de datos y sacaban tareas de la ruta crítica siempre que era posible. Aunque esto dio lugar a algunos diseños de producto interesantes y más resistentes a los problemas de la base de datos, también aumentó la complejidad de los productos y ralentizó su evolución. No estábamos cumpliendo el objetivo de Habitat: facilitar un desarrollo rápido de productos sin necesidad de conocer la base de datos.
Esta ha sido una de nuestras principales prioridades en 2026, y hemos desarrollado una estrategia por capas para optimizar el rendimiento de las lecturas, que representan más del 90 % de las solicitudes a Habitat:
Tenemos varias cuentas de Azure Cosmos DB en distintas regiones de Azure de todo el mundo para usuarios con requisitos de residencia de datos. Incluso para los usuarios sin requisitos estrictos de residencia de datos, almacenar los datos cerca de ellos también mejora su experiencia al reducir la latencia.
En la práctica, no podemos aplicar este enfoque de forma generalizada fuera de los casos de uso de residencia de datos, porque la ubicación está limitada por la capacidad física de la nube. Dado el tamaño de nuestros conjuntos de datos, muchas regiones no pueden alojar el enorme volumen de almacenamiento que exige su parte proporcional del tráfico de usuarios.
En regiones con limitaciones de capacidad en los centros de datos, suministro eléctrico o refrigeración, a veces debemos elegir: reservar capacidad para almacenar los datos junto a los recursos de cómputo y reducir la latencia de Habitat, o destinarla a más cómputo para atender solicitudes y dirigir las de almacenamiento a lugares más lejanos.
Por ello, las decisiones de ubicación suelen exigir un equilibrio entre dos prioridades de producto: a) optimizar la latencia para distintos productos y grupos de usuarios, y b) disponer de capacidad bruta de almacenamiento y cómputo.
Para las cargas de trabajo donde la latencia es más crítica, como los metadatos de autenticación necesarios en cada solicitud, reducimos el tiempo de ida y vuelta (RTT) entre los recursos de cómputo y Habitat mediante cuentas de Azure Cosmos DB con un alto grado de replicación en numerosas regiones secundarias. Algunas cuentas se replican en las 40 regiones de Azure desde las que atendemos el tráfico; otras, en al menos una región por continente.
Hemos tenido que incorporar a Habitat una capa transparente de traslado de datos y enrutamiento antes de lo previsto para poder mover conjuntos de datos entre cuentas con distintas topologías de replicación.
Sin embargo, este enfoque también está limitado, en última instancia, por la capacidad, por lo que solo lo aplicamos a unos pocos conjuntos de datos seleccionados expresamente.
En las cargas de trabajo de Habitat predominan ampliamente las lecturas: las aplicaciones consultan constantemente ajustes, estados y otras propiedades. Una proporción desmesurada del tráfico corresponde a un conjunto de trabajo relativamente pequeño de tipos de datos de acceso frecuente. Esto hace que el sistema sea especialmente adecuado para el almacenamiento en caché distribuido. Aunque la caché mejora el rendimiento en infraestructuras de una sola región, sus ventajas se multiplican al trabajar entre regiones, donde permite «ocultar» la latencia interregional.
Hemos integrado en Habitat una capa de caché distribuida de tipo lookaside. Almacena una copia de los objetos y las aristas consultados recientemente en servidores Valkey ubicados en nuestra infraestructura, cerca de donde se procesan las solicitudes de los usuarios. Normalmente, estas cachés usan un tiempo de vida (TTL) que busca un equilibrio entre la tasa de aciertos y la obsolescencia de los datos. Los TTL cortos reducen la obsolescencia, pero atenúan las ventajas de la caché, porque los elementos caducan pronto y deben recuperarse con más frecuencia. Los TTL más largos mejoran las tasas de aciertos, pero sirven datos obsoletos durante periodos prolongados, lo que perjudica la experiencia del usuario y vuelve impredecible el comportamiento del producto.
Otra opción es ejecutar operaciones explícitas de invalidación cuando la aplicación escribe en los mismos datos subyacentes. Esto mejora mucho la actualidad de los datos en caché, pero puede ser difícil de implementar correctamente. Además, sigue siendo vulnerable a ciertos casos extremos, como los fallos parciales, que dejan la caché desactualizada. Los despliegues multirregión agravan estos problemas: las redes entre regiones son menos fiables y se producen condiciones de carrera entre la caché y la replicación del almacenamiento subyacente. Complementar este enfoque con TTL limita el tiempo máximo de obsolescencia, pero mantiene el mismo compromiso inherente a los TTL que hemos descrito.
Hemos adoptado un enfoque de invalidación más avanzado, siguiendo los pasos de sistemas como TAO de Meta. La caché integrada de Habitat utiliza la captura de cambios de datos (CDC) a través de la fuente de cambios de Azure Cosmos DB para propagar invalidaciones globalmente en segundos. Así logra altas tasas de aciertos con un bajo nivel de obsolescencia. Un servicio de nuestra infraestructura consume esta fuente de cambios y ejecuta invalidaciones en las cachés locales cuando se actualizan los datos subyacentes. Esto provoca un fallo de caché en la siguiente lectura, y la caché se rellena con la versión más reciente de los datos.
También hemos reducido notablemente la latencia al eliminar sobrecarga del propio servicio Habitat mediante la reescritura del código en Rust, que ofrece un mayor rendimiento que el código original en Python.
En conjunto, estos cambios han reducido el p50 general de latencia de lectura a nivel mundial de unos 120 ms a unos 10 ms: una mejora de 12 veces desde que empezamos a centrarnos en el rendimiento a principios de este año.
Figure 05 · Improving performance at a global scale
p50 latency for reads
Three major design changes improved read latency
Aunque la caché ha reducido drásticamente la mediana de latencia, las solicitudes más lentas aún deben recuperar datos no almacenados en caché desde el almacenamiento subyacente, a menudo en regiones lejanas. A medida que dispongamos de más capacidad y mejoremos la eficiencia del almacenamiento, prevemos abordar un reto más fundamental: ubicar los datos desde el principio cerca de donde se consultarán.
Una CDC fiable y escalable —que propague los cambios de la base de datos a los sistemas posteriores— es esencial no solo para la estrategia de caché de Habitat. Cada segundo, millones de cambios capturados en miles de contenedores y millones de particiones pasan por más de cien temas de Kafka. También alimentan índices secundarios con consistencia eventual, flujos de traslado de datos, análisis sin conexión y otras funciones de producto en tiempo real. A medida que nuestra infraestructura subyacente se ha expandido por el mundo, escuchar los cambios en las filas se ha vuelto cada vez más complejo. Si un cliente quiere registrar una función de devolución de llamada que se ejecute cuando cambien filas de su tipo, primero debe averiguar, entre otras cosas, qué cuentas y contenedores de Cosmos contienen sus datos y qué despliegue del servicio CDC escucha esos contenedores en cada región. También debe dimensionar correctamente la flota de procesos de trabajo del servicio CDC, Kafka y su consumidor. Nuestra plataforma CDC busca ocultar toda esta complejidad a los desarrolladores de producto y ofrecer una interfaz sencilla: los clientes registran una función para ejecutarla sobre las filas modificadas, y nosotros nos encargamos de toda la infraestructura y el escalado.
Un plano de control interno comprueba continuamente que se capturen los cambios de todos los contenedores necesarios, selecciona de qué regiones de Cosmos leer y distribuye el trabajo de forma eficiente entre miles de procesos de trabajo de varias regiones geográficas. El uso de regiones de réplica y de lecturas de la fuente de cambios con menor prioridad protege el tráfico de Habitat sensible a la latencia frente a las cargas de captura en segundo plano. En una flota tan grande se producen continuamente caídas de procesos de trabajo, problemas en contenedores, errores en el almacén de concesiones, configuraciones no válidas y fallos de destino. Reforzamos la gestión del ciclo de vida de los procesos de trabajo CDC y de las concesiones, aislamos los fallos entre flujos e incorporamos medidas de protección para los cambios de configuración y los despliegues. Usamos colas de mensajes fallidos para evitar que los fallos permanentes de entrega bloqueen la cabecera de la cola. Toleramos las caídas regionales redirigiendo los lectores a otras regiones de Cosmos. A nuestra escala, incluso hemos tenido que modificar el SDK de CDC de Azure para hacer más eficiente la implementación de los puntos de control, agrupándolos en memoria y volcándolos solo periódicamente.
Aunque el uso interno de Azure Cosmos DB en Habitat es complejo, su propuesta de valor siempre ha sido ocultar los detalles de infraestructura a los desarrolladores de producto para acelerar el desarrollo. Nuestra plataforma CDC sigue el mismo principio.
Un equipo pequeño pudo sostener una plataforma de almacenamiento en rápido crecimiento manteniendo deliberadamente limitada la API de almacenamiento, ampliando la capacidad del servicio Python y priorizando los retos de ingeniería más urgentes. Nos centramos primero en la fiabilidad para el tráfico crítico de los productos, después en el rendimiento de lectura para usuarios de todo el mundo y, por último, en la eficiencia operativa a gran escala. Este enfoque permitió un crecimiento rápido y nuevos casos de uso, al tiempo que mejoraba la fiabilidad, el rendimiento y la velocidad de desarrollo de productos.
Para escalar Habitat y el almacenamiento de conversaciones de cara a los próximos mil millones de usuarios, debemos resolver la dificultad de replicar nuestros datos en toda la infraestructura a una escala aún mayor. Para anticiparnos a ello, estamos desarrollando internamente un sistema propio de almacenamiento online a escala de exabytes, optimizado para los tipos de datos voluminosos de Habitat. Este sistema en desarrollo combina el núcleo de RocksDB Cloud de Rockset con replicación basada en Raft. Implementa el mismo modelo de documentos que Azure Cosmos DB, pero usa almacenamiento desagregado y replicación física para reducir la capacidad flash necesaria, a cambio de un menor pico de QPS.
Si te interesa trabajar en proyectos de infraestructura de datos de este tipo a una escala de vanguardia, consulta nuestras vacantes.


