El problema fundamental que K2 aborda es la gestión de flujos de eventos asíncronos a escala global, donde la alineación temporal y de capacidad entre productores y consumidores es inviable. Los sistemas de mensajería tradicionales, como Apache Kafka, están diseñados para entornos de datacenter con redes de baja latencia y máquinas persistentes. Sin embargo, la infraestructura de edge de Cloudflare presenta desafíos únicos: máquinas efímeras, "slices" de recursos pequeños y latencias de red variables sobre la Internet pública.
K2 resuelve esto al introducir un buffer duradero y desacoplado que absorbe escrituras y permite lecturas independientes. La clave de su diseño es la utilización de un sistema de object storage (R2) como primitiva de estado subyacente, lo que permite heredar su durabilidad y consistencia, simplificando la capa de aplicación y habilitando una escalabilidad horizontal masiva en el edge. Este enfoque permite a Cloudflare ofrecer un servicio de streaming de eventos globalmente distribuido sin la complejidad operativa de desplegar y mantener sistemas de logs distribuidos tradicionales en un entorno tan volátil.
Arquitectura del Sistema
La arquitectura de K2 se basa en un log particionado y duradero implementado sobre Cloudflare R2. R2, un object storage con 11 nueves de durabilidad y APIs fuertemente consistentes, actúa como la capa de persistencia fundamental. Esto permite a K2 delegar la replicación y el consenso al almacenamiento, simplificando radicalmente su propia lógica de aplicación.
Dado que los object stores no soportan operaciones de append directamente, K2 acumula escrituras en memoria en un servicio de edge. Una vez que se ha recolectado una cantidad suficiente de datos o ha transcurrido un corto período de tiempo, estos eventos se escriben como "segment files" completos en R2. El ordenamiento y los offsets estrictamente incrementales se logran utilizando las operaciones atómicas de R2, eliminando la necesidad de un servicio de coordinación separado. Los consumidores pueden leer los datos de varias maneras, incluyendo la división de lecturas entre un conjunto de consumidores para paralelismo o el patrón pub/sub donde cada consumidor recibe todos los mensajes. La separación de cómputo y almacenamiento permite escalar cada componente de forma independiente, facilitando la retención de grandes volúmenes de datos históricos a bajo costo.
Flujo de Producción de Eventos K2
- 1 Productor Envía eventos a un servicio K2 en el edge.
- 2 Servicio K2 (Edge) Acumula eventos en memoria.
- 3 Servicio K2 (Edge) Agrupa eventos en un segmento (batch).
- 4 Servicio K2 (Edge) Escribe el segmento completo a R2 usando operaciones atómicas.
- 5 R2 Object Storage Almacena el segmento de forma duradera y consistente.
Flujo de Consumo de Eventos K2
- 1 Consumidor Crea una suscripción a un stream K2.
- 2 Consumidor Solicita un batch de eventos de la suscripción (poll).
- 3 Servicio K2 Asigna un lease al consumidor para un batch de eventos.
- 4 Consumidor Procesa los eventos recibidos.
- 5 Consumidor Envía un ACK/NACK/Extend Lease para el batch.
- 6 Servicio K2 Marca el batch como procesado o lo re-entrega según la respuesta.
| Capa | Tecnología | Justificación |
|---|---|---|
| storage | Cloudflare R2 | Almacenamiento de objetos duradero y consistente que sirve como la capa de persistencia fundamental para los segmentos del log de eventos. Proporciona 11 nueves de durabilidad y APIs fuertemente consistentes, delegando la complejidad de replicación y consenso. vs Amazon S3, Google Cloud Storage, Azure Blob Storage |
| compute | Cloudflare Workers | Plataforma serverless en el edge utilizada para la lógica de aplicación de K2, incluyendo la acumulación de eventos en memoria y la escritura de segmentos a R2. Permite la ejecución de código cerca del usuario. vs AWS Lambda@Edge, Fastly Compute@Edge |
| messaging | Cloudflare K2 | Servicio de streaming de eventos que proporciona un log duradero y particionado. Desacopla productores y consumidores, gestiona la entrega de eventos y la retención a largo plazo. vs Apache Kafka, Amazon Kinesis, Google Cloud Pub/Sub, Azure Event Hubs |
Trade-offs
Ganancias
- ▲▲ Durabilidad del almacenamiento
- ▲▲ Escalabilidad de almacenamiento
- ▲ Simplicidad de la capa de aplicación
- ▲ Costo de almacenamiento a largo plazo
Costes
- ▲ Latencia de producción (produce latency)
- ▲ Granularidad de reintentos (a nivel de batch, no de mensaje)
const result = await env.EVENTS.send([
{
content: new TextEncoder().encode(
JSON.stringify({
event: "page_view",
path: new URL(request.url).pathname,
timestamp: Date.now(),
}),
),
headers: { "content-type": "application/json" },
},
]);
if (!result.success) {
console.error(`Produce failed: ${result.error.message}`);
return new Response("Failed to record event", {
status: result.error.retryable ? 503 : 500,
});
}curl -X POST "https://4d8f5394e3e733debdeca9c65c5b7439.k2.cloudflarestorage.com/subscriptions/ee13f761783d3823a447a47b572ebf76/consume" \
-H "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \
-H "Content-Type: application/json" \
--data '{
"worker_id": "analytics-1",
"max_records": 100
}'Fundamentos Teóricos
El concepto de un log duradero y ordenado es central en la computación distribuida, popularizado por sistemas como el Write-Ahead Log (WAL) en bases de datos y el log de replicación en sistemas de consenso como Paxos o Raft. El diseño de K2, al construir un log sobre un object storage, se alinea con el patrón de "separación de cómputo y almacenamiento" que ha ganado prominencia en la última década, especialmente en bases de datos y sistemas de streaming. Este patrón fue explorado en papers como "The Log-Structured File System" (Rosenblum y Ousterhout, 1992), que enfatizó la eficiencia de las escrituras secuenciales, y más recientemente en arquitecturas de bases de datos en la nube que desacoplan el almacenamiento de la lógica de procesamiento para mejorar la escalabilidad y la resiliencia. La idea de usar un almacenamiento de objetos para durabilidad y consistencia, mientras se gestiona la semántica de log en una capa superior, es una aplicación práctica de estos principios en un entorno de edge.