La proliferación de redes sociales descentralizadas basadas en protocolos como AT Protocol presenta un desafío fundamental de la computación distribuida: cómo indexar y servir eficientemente un volumen masivo y en constante crecimiento de datos distribuidos en múltiples nodos (PDSes) para proporcionar una experiencia de usuario centralizada y de alto rendimiento. Este problema se agrava por la necesidad de backfill de datos históricos y la resiliencia frente a fallos de red y datos inconsistentes.

La solución de Blacksky, al reemplazar el indexador TypeScript original con 'rsky-wintermute' basado en Rust, aborda directamente las limitaciones de rendimiento y escalabilidad inherentes a las arquitecturas de indexación secuencial. La tesis es que un indexador concurrente, con colas de procesamiento separadas para eventos en vivo y backfill, junto con optimizaciones de base de datos y un robusto conjunto de herramientas operativas, es esencial para operar un AppView a la escala de un 'hyperscaler' en el contexto de una red social descentralizada.

Arquitectura del Sistema

La arquitectura del AppView de Blacksky se basa en un conjunto de servicios interconectados. El corazón del sistema es 'rsky-wintermute', un indexador monolítico en Rust que consume el 'firehose' de eventos del AT Protocol (vía WebSocket desde bsky.network). Wintermute utiliza 'Fjall' (una base de datos clave-valor embebida) para gestionar colas de eventos ('firehose_live', 'firehose_backfill', 'repo_backfill', 'labels') y escribe los datos indexados en una base de datos PostgreSQL 17. La persistencia de eventos en Fjall y el uso de 'ON CONFLICT DO NOTHING' en PostgreSQL garantizan la idempotencia y la resiliencia ante reintentos.

El 'bsky-dataplane' (gRPC) y el 'bsky-appview' (HTTP) son los componentes principales que sirven las APIs al cliente, leyendo directamente de PostgreSQL. Se ha implementado una capa de caché Redis (actualmente deshabilitada por un bug de serialización de timestamps) para reducir la carga de la base de datos. Las consultas críticas como 'getTimeline' y 'getListFeed' han sido reescritas utilizando 'LATERAL JOIN' en PostgreSQL para forzar el uso de índices por usuario, evitando escaneos completos de tablas. Para la búsqueda de texto completo, se integra 'Palomar' (Go) que indexa perfiles y posts en OpenSearch, con 'palomar-sync' (Rust) sincronizando métricas como conteos de seguidores y PageRank.

La arquitectura también incluye servicios especializados como 'rsky-relay' para etiquetas de moderación y 'rsky-video' para la gestión de subidas de video, que interactúa con PDSes de usuario y CDNs como Bunny Stream. Las decisiones de diseño enfatizan la separación de preocupaciones (indexación vs. servicio), la concurrencia para el rendimiento y la robustez operativa para manejar la complejidad de un sistema distribuido a gran escala.

Flujo de Indexación de Eventos (rsky-wintermute)

  1. 1 bsky.network Firehose Envía eventos AT Protocol vía WebSocket
  2. 2 rsky-wintermute Ingester Conecta al firehose, escribe eventos a colas Fjall (KV store)
  3. 3 rsky-wintermute Indexer Lee de colas Fjall, parsea registros, escribe a PostgreSQL con ON CONFLICT
  4. 4 PostgreSQL 17 Base de datos principal para datos indexados

Flujo de Consulta de Feeds (AppView)

  1. 1 Cliente App Solicita feeds (e.g., getTimeline, getListFeed)
  2. 2 bsky-appview (HTTP) Servidor API, recibe solicitudes
  3. 3 bsky-dataplane (gRPC) Capa de datos, ejecuta consultas optimizadas con LATERAL JOIN
  4. 4 PostgreSQL 17 Base de datos, responde a consultas
  5. 5 Redis (opcional) Capa de caché para perfiles, registros, etc. (actualmente deshabilitado)
CapaTecnologíaJustificación
data-processing rsky-wintermute (Rust) Indexador de eventos de alto rendimiento para el AT Protocol, maneja ingesta en vivo y backfill. vs TypeScript consumer (original) Colas de procesamiento paralelas (live, backfill, labels), uso de Fjall (KV embebido) para colas.
storage PostgreSQL 17 Base de datos relacional principal para almacenar todos los datos indexados del AT Protocol. Uso de LATERAL JOIN para optimización de consultas, schema 'bsky', ON CONFLICT DO NOTHING para idempotencia.
cache Redis Capa de caché para reducir la carga de la base de datos en perfiles de actor, registros y conteos de interacción. Actualmente deshabilitado debido a un bug de serialización de timestamps en Protobuf.
compute bsky-dataplane (Node.js/TypeScript) Capa de datos gRPC que interactúa con PostgreSQL y Redis, sirviendo datos al AppView. Puerto gRPC 2585, utiliza DB_PRIMARY_URL y DB_REPLICA_URL.
compute bsky-appview (Node.js/TypeScript) Servidor HTTP API que expone los endpoints XRPC de app.bsky.* a los clientes. Puerto HTTP 2584, requiere BSKY_DATAPLANE_URLS y BSKY_DID.
data-processing Palomar (Go) Servicio de búsqueda de texto completo que indexa perfiles y posts en OpenSearch. Integración con OpenSearch, boosting por conteo de seguidores.
storage OpenSearch Motor de búsqueda para Palomar, utilizado para búsquedas de texto completo. vs Elasticsearch

Trade-offs

Ganancias
  • ▲▲ Rendimiento de indexación
  • Resiliencia operativa
  • Eficiencia de consultas
Costes
  • Complejidad de la arquitectura
  • Coste de infraestructura

Fundamentos Teóricos

El desafío de indexar y consultar datos distribuidos a gran escala se relaciona directamente con los principios de las bases de datos distribuidas y los sistemas de procesamiento de eventos. El uso de un 'firehose' de eventos y un indexador que consume estos eventos para construir una vista materializada es un patrón común en la arquitectura de sistemas de datos, a menudo asociado con el patrón 'Change Data Capture' (CDC) y los 'event streams' popularizados por sistemas como Apache Kafka. La necesidad de backfill y la gestión de la consistencia entre el estado en vivo y el estado histórico se alinea con los conceptos de 'eventual consistency' y los desafíos de la 'reconciliación de estados' en sistemas distribuidos.

La optimización de consultas con 'LATERAL JOIN' en PostgreSQL refleja principios de optimización de bases de datos relacionales, donde la comprensión profunda del planificador de consultas y la estructura de los datos es crucial para el rendimiento a escala. Los problemas de consistencia de caché y serialización de datos (como el bug de los timestamps en Redis) son desafíos clásicos en la computación distribuida, donde la serialización/deserialización y la invalidación de caché son fuentes comunes de errores, como se discute en trabajos sobre 'consistency models' y 'cache coherence' en sistemas distribuidos.