El problema fundamental que RAP aborda es la latencia inherente a las consultas puntuales (point queries) en grandes volúmenes de datos almacenados en data lakes de objetos (ej. GCS, S3). Los motores SQL distribuidos, optimizados para throughput analítico, introducen segundos de overhead para una sola fila, haciendo inviable el acceso interactivo para servicios online o agentes de IA. La raíz del problema reside en la cadena de lecturas dependientes necesarias para localizar datos dentro de archivos Parquet, donde cada paso implica una latencia de red significativa en almacenamiento de objetos.
RAP resuelve esto desacoplando la localización de datos del proceso de lectura. Al precomputar un índice externo que mapea claves a ubicaciones físicas (archivo, fila, offset), elimina la necesidad de escanear metadatos o datos dentro del archivo para cada consulta. Esto transforma múltiples round-trips secuenciales en una única búsqueda O(1) en el índice, seguida de lecturas de rango precisas y paralelizables, reduciendo drásticamente la latencia y el consumo de ancho de banda. La relevancia actual se amplifica con la demanda de agentes de IA que requieren acceso rápido a vastos contextos históricos de usuario.
Arquitectura del Sistema
La arquitectura de RAP se centra en un índice externo que opera sobre archivos Parquet existentes. Este índice es una estructura de datos de tipo multimap que asocia una clave de búsqueda (ej. user ID) con una lista de tuplas (file_ordinal, row_numbers, value_count). El file_ordinal es una referencia a un archivo Parquet específico, y row_numbers especifica las filas dentro de ese archivo. El índice se construye leyendo los footers de los archivos Parquet, escaneando las columnas clave y mapeando las ubicaciones de las páginas y filas. Es un índice append-only, lo que facilita su actualización incremental.
Cuando una consulta llega, el lector de RAP primero consulta el índice externo para obtener las ubicaciones exactas de los datos. Luego, utiliza metadatos de archivo cacheados para resolver los row_numbers a ubicaciones de página precisas. Finalmente, emite lecturas de rango (ranged reads) directamente al almacenamiento de objetos para recuperar solo las páginas necesarias. Estas lecturas de rango pueden ejecutarse en paralelo, eliminando la latencia de las dependencias. Las optimizaciones incluyen ordenar los datos por clave, co-agrupar campos relacionados, usar una página por clave, restablecer frames ZSTD en límites de clave, almacenar datos como blobs/variants, entrelazar columnas y usar índices cubrientes (covering indexes) para evitar lecturas de almacenamiento por completo. Estas técnicas manipulan la estructura interna de los archivos Parquet para minimizar bytes leídos y operaciones de E/S, manteniendo la compatibilidad con el formato Parquet estándar.
Flujo de Consulta Puntual con RAP
- 1 Cliente Solicita datos para una clave específica (ej. User ID)
- 2 Servicio RAP Recibe la consulta y consulta el índice externo
- 3 Índice Externo Devuelve (file_ordinal, row_numbers) para la clave
- 4 Servicio RAP Resuelve row_numbers a offsets de página usando metadatos cacheados
- 5 Almacenamiento de Objetos Emite lecturas de rango paralelas para las páginas exactas
- 6 Servicio RAP Ensambla los datos y los devuelve al cliente
Flujo de Construcción/Actualización del Índice RAP
- 1 Pipeline de Datos Genera nuevos archivos Parquet
- 2 Constructor de Índice Lee footers y metadatos de los nuevos archivos Parquet
- 3 Constructor de Índice Escanea columnas clave para mapear clave a (file, row)
- 4 Constructor de Índice Escribe nuevos fragmentos de índice
- 5 Índice Externo Añade nuevos fragmentos, manteniendo la estructura append-only
| Capa | Tecnología | Justificación |
|---|---|---|
| storage | Google Cloud Storage (GCS) | Almacenamiento de objetos de bajo costo y alta durabilidad para el data lake. RAP optimiza el acceso a este almacenamiento. vs Amazon S3, Azure Blob Storage |
| data-processing | Apache Parquet | Formato de archivo columnar para el almacenamiento de datos en el data lake. RAP se construye sobre y optimiza el acceso a estos archivos. vs ORC, Avro Optimizado con técnicas como 'one page per key', ZSTD frame resets, interleaving columns. |
| data-processing | Trino (PrestoSQL) | Motor SQL distribuido para consultas analíticas. RAP complementa su funcionalidad al ofrecer acceso de baja latencia para consultas puntuales. vs Apache Spark SQL, Google BigQuery |
| cache | Metadatos cacheados | Almacena metadatos de archivos Parquet (ej. mapeo de row_numbers a page_locations) para reducir la latencia de resolución. |
Trade-offs
Ganancias
- ▲▲ Latencia de consulta puntual
- ▲ Costo de almacenamiento
- ▲ Flexibilidad de acceso a datos históricos
Costes
- △ Granularidad de partition pruning para batch queries (con coarser partitioning)
- △ Overhead de PageIndex (con 'one page per key')
- △ Ratio de compresión (con ZSTD frame resets)
- ▲ Pruning por campo y predicate pushdown (con Blobs/Variants)
- ▲ I/O para single-column scans (con interleaving columns)
- ▲ Tamaño del índice (con covering index)
Fundamentos Teóricos
El problema de la recuperación eficiente de datos en grandes colecciones ha sido un pilar de la investigación en bases de datos y sistemas de archivos distribuidos. La idea de un índice externo para acelerar el acceso aleatorio a datos secuenciales se remonta a los sistemas de gestión de archivos de los años 70 y 80, donde los índices B-tree eran fundamentales para mapear claves lógicas a bloques físicos en disco. En el contexto de los sistemas de almacenamiento de objetos inmutables, la estrategia de RAP se alinea con los principios de los Log-Structured Merge-trees (LSM-trees), popularizados por papers como 'The Log-Structured File System' de Rosenblum y Ousterhout (1992), donde las escrituras son secuenciales y las lecturas se optimizan mediante índices y compactación.
La optimización de lecturas de rango y la reducción de round-trips son conceptos centrales en la optimización de E/S, especialmente relevantes en entornos de red de alta latencia. La noción de 'covering index', donde los valores se almacenan directamente en el índice para evitar lecturas de la tabla principal, es un concepto bien establecido en la teoría de bases de datos relacionales, mejorando el rendimiento de consultas específicas. La aplicación de estas técnicas a formatos de columna como Parquet, que ya utiliza estructuras como PageIndex y Bloom Filters para optimizar escaneos, representa una evolución en la forma de abordar el acceso aleatorio en sistemas OLAP (Online Analytical Processing) que ahora deben soportar cargas OLTP (Online Transaction Processing) o híbridas.