El problema fundamental que aborda Cache Transcoding es la creciente presión sobre los costos de almacenamiento y ancho de banda en sistemas distribuidos a escala de hyperscaler, particularmente en redes de entrega de contenido (CDN). A medida que los volúmenes de datos y la demanda de contenido aumentan, la eficiencia en el uso de la memoria y la red se vuelve crítica. Este sistema resuelve esto aplicando compresión de datos a nivel de caché, transformando la representación de los activos almacenados para reducir su huella física.
La relevancia actual de esta solución radica en el incremento sostenido de los costos de hardware (RAM y HDD) y la necesidad de optimizar la infraestructura existente para escalar sin incurrir en gastos prohibitivos. Al comprimir los activos una vez al "llenar" la caché y descomprimirlos solo al "servir" al cliente, se logra un balance favorable entre el costo computacional y los ahorros en almacenamiento y transferencia de datos. Este enfoque es una aplicación directa del principio de que la optimización de recursos escasos (en este caso, almacenamiento y ancho de banda) a menudo implica un trade-off con recursos más abundantes o menos costosos (CPU).
Históricamente, la compresión de datos ha sido una técnica fundamental para la optimización de recursos. Desde los primeros algoritmos como Huffman y Lempel-Ziv, hasta los modernos como Brotli y Zstandard, la meta ha sido siempre reducir la redundancia de la información. La novedad aquí no es la compresión en sí, sino su aplicación estratégica dentro de la arquitectura de una CDN, integrándola directamente en el proxy de caché para maximizar los beneficios a través de múltiples capas de la infraestructura (almacenamiento local, transferencia entre tiers de caché).
Arquitectura del Sistema
El sistema Cache Transcoding se integra en Pingora, el proxy de Cloudflare basado en Rust. Cuando una respuesta HTTP elegible (principalmente texto no comprimido como HTML, JSON, CSS, JavaScript) llega al proxy y resulta en un "cache miss", el cuerpo de la respuesta es codificado usando el algoritmo Zstandard (zstd) antes de ser escrito en disco. Los metadatos de la caché registran que el objeto está comprimido y conservan la longitud original del contenido. Esta representación comprimida se mantiene mientras el activo reside en la caché local y se transfiere entre los diferentes tiers de la Tiered Cache de Cloudflare.
En un "cache hit", el objeto zstd almacenado se lee del disco y se decodifica antes de ser servido al cliente. La decodificación ocurre solo en el "hop" final, orientado al cliente. Si el objeto se mueve entre tiers de caché (por ejemplo, de un tier superior a uno inferior), se transfiere en su forma comprimida, minimizando el uso de ancho de banda de la red troncal. La lógica de elegibilidad es crucial: solo se transcodifican respuestas 200 OK con Content-Encoding no establecido, Content-Type de texto compresible y Content-Length conocido de al menos 4 KiB. Esto evita la recompresión de contenido ya comprimido (imágenes, videos) y el procesamiento de objetos muy pequeños donde el overhead de compresión no justifica el ahorro.
La implementación utiliza zstd nivel 3, un balance entre ratio de compresión y velocidad. Un marcador en los metadatos de la caché evita que un objeto sea codificado más de una vez si ya ha sido procesado por otro tier. Esta arquitectura aprovecha la naturaleza asimétrica de la compresión (codificar una vez, decodificar muchas veces) para amortizar el costo de CPU de la codificación a lo largo de múltiples lecturas y transferencias, maximizando los ahorros en almacenamiento y ancho de banda.
Flujo de Cache Transcoding (Cache Miss)
- 1 Cliente Solicita recurso
- 2 Proxy (Pingora) Cache Miss: Recurso no encontrado localmente
- 3 Proxy (Pingora) Fecth de Origen: Obtiene bytes sin comprimir
- 4 Proxy (Pingora) Codifica con Zstandard (zstd level 3)
- 5 Proxy (Pingora) Almacena zstd en disco y transfiere a Tiered Cache (comprimido)
- 6 Proxy (Pingora) Decodifica zstd
- 7 Cliente Recibe recurso original
Flujo de Cache Transcoding (Cache Hit)
- 1 Cliente Solicita recurso
- 2 Proxy (Pingora) Cache Hit: Recurso zstd encontrado localmente
- 3 Proxy (Pingora) Lee zstd del disco
- 4 Proxy (Pingora) Decodifica zstd
- 5 Cliente Recibe recurso original
| Capa | Tecnología | Justificación |
|---|---|---|
| compute | Pingora | Proxy de borde y motor de caché, donde se integra la lógica de compresión/descompresión. |
| storage | Zstandard (zstd) | Algoritmo de compresión sin pérdidas para reducir el tamaño de los activos en disco y en tránsito. vs Brotli, gzip zstd level 3 (balance entre ratio de compresión y velocidad) |
| networking | Tiered Cache | Sistema de caché distribuido que permite la transferencia de activos comprimidos entre data centers, optimizando el uso de ancho de banda de la red troncal. |
Trade-offs
Ganancias
- ▲ Capacidad efectiva de caché
- ▲ Ancho de banda de red entre data centers
- ▲ Densidad de objetos en caché
- ▲ Reducción de evicciones de caché
Costes
- △ Uso de CPU en el proxy
Fundamentos Teóricos
El concepto de compresión de datos se remonta a trabajos fundamentales en teoría de la información, como el teorema de codificación de fuente de Shannon y los algoritmos de Huffman (1952) y Lempel-Ziv (LZ77 y LZ78, 1977-1978). Estos trabajos sentaron las bases para la compresión sin pérdidas, que es el principio subyacente de Zstandard. La idea de intercambiar ciclos de CPU por reducción de almacenamiento y ancho de banda es un trade-off clásico en sistemas distribuidos, a menudo discutido en el contexto de la eficiencia de recursos.
La aplicación de compresión a nivel de caché para optimizar el almacenamiento y el ancho de banda en CDNs se relaciona con principios de diseño de sistemas de almacenamiento jerárquico y gestión de caché, donde la densidad de almacenamiento y la eficiencia de transferencia son métricas clave. Aunque no hay un paper único que "prediga" esta implementación específica, los principios de amortización de costos computacionales (codificar una vez, decodificar muchas) y la optimización de la localidad de los datos son temas recurrentes en la literatura de sistemas distribuidos y bases de datos, donde técnicas como los Write-Ahead Logs (WAL) y las estructuras de datos inmutables (como en LSM-trees) también gestionan trade-offs similares entre escritura, lectura y almacenamiento.