El problema fundamental que K2 aborda es la necesidad de un sistema de streaming de eventos duradero y escalable en entornos distribuidos masivamente, como la red de edge de Cloudflare, donde las soluciones tradicionales como Apache Kafka son inviables debido a sus supuestos de red y recursos. K2 resuelve esto redefiniendo la capa de durabilidad, empujando la replicación y el consenso al almacenamiento de objetos, desacoplando así el cómputo del almacenamiento.

La relevancia actual de esta solución radica en la creciente demanda de procesamiento de eventos en el edge y la madurez de los servicios de almacenamiento de objetos con garantías de consistencia fuerte. Históricamente, los sistemas de logs distribuidos se construyeron sobre almacenamiento local o SAN, con replicación activa entre nodos. K2 representa un cambio de paradigma al externalizar la durabilidad a una capa de almacenamiento de objetos globalmente distribuida, simplificando la lógica de la aplicación y permitiendo una elasticidad de recursos sin precedentes.

Arquitectura del Sistema

La arquitectura de K2 se basa en un log particionado duradero que reside en el almacenamiento de objetos R2 de Cloudflare. Los writes son gestionados por un servicio de edge que acumula eventos en memoria por un breve período, luego los escribe por lotes como archivos de segmento (segment files) en R2. R2 proporciona operaciones atómicas y garantías de consistencia fuerte (eleven nines), lo que elimina la necesidad de un servicio de coordinación explícito para el ordenamiento y los offsets incrementales.

La latencia de producción (produce latency) de K2 es un trade-off directo de este enfoque de batching, ya que el sistema espera un momento para acumular más eventos antes de realizar un PUT en R2. El consumo de eventos se realiza a través de una API basada en leases, donde los consumidores (típicamente Cloudflare Workers) solicitan un lote de eventos, lo procesan y luego lo confirman (acknowledge) o lo rechazan (negative acknowledge) para reentrega, o extienden el lease. Este diseño permite un alto paralelismo de lectura, adecuado para Workers que son individualmente menos potentes pero escalan horizontalmente de manera eficiente. La capa de almacenamiento de objetos R2 maneja la replicación y la durabilidad, mientras que la capa de aplicación de K2 se enfoca en la gestión del log y la interacción con los clientes.

Flujo de Producción de Eventos K2

  1. 1 Worker/Cliente Envía eventos a K2 a través de una binding o API.
  2. 2 Servicio Edge K2 Recibe eventos y los acumula en memoria.
  3. 3 Servicio Edge K2 Pausa brevemente para batching (introduce latencia).
  4. 4 Servicio Edge K2 Escribe el batch como un segmento de archivo.
  5. 5 R2 Object Storage Almacena el segmento de archivo con operaciones atómicas y consistencia fuerte.
  6. 6 Worker/Cliente Recibe confirmación de éxito o error retryable/no-retryable.

Flujo de Consumo de Eventos K2 (Lease-based)

  1. 1 Consumidor (Worker) Sondea una suscripción para nuevos eventos.
  2. 2 Servicio K2 Entrega un batch de eventos con un lease de 5 minutos.
  3. 3 Consumidor (Worker) Procesa los eventos del batch.
  4. 4 Consumidor (Worker) Envía ACK, NACK o extiende el lease del batch.
CapaTecnologíaJustificación
storage Cloudflare R2 Capa de almacenamiento de objetos duradera y consistente, base del log particionado. Proporciona durabilidad de 'once nueves' y APIs fuertemente consistentes, eliminando la necesidad de lógica de replicación y consenso en la capa de aplicación de K2. vs Amazon S3, Google Cloud Storage
compute Cloudflare Workers Entorno serverless para consumidores de K2. Su naturaleza de paralelización eficiente y bajo costo por invocación se alinea con el modelo de consumo basado en leases de K2, donde Workers individuales pueden ser menos potentes pero escalan horizontalmente. vs AWS Lambda, Google Cloud Functions
messaging Cloudflare K2 (custom) Servicio de streaming de eventos serverless. Implementa la lógica de log particionado, batching de writes, y la API de consumo basada en leases, desacoplando la durabilidad de R2 de la interfaz de streaming. vs Apache Kafka, Amazon Kinesis, Google Pub/Sub

Trade-offs

Ganancias
  • ▲ Costo
  • ▲ Elasticidad
  • ▲ Durabilidad
  • ▲ Operacional (no clusters)
Costes
  • ▲ Latencia de Producción (Produce Latency)
  • ▲ Latencia End-to-End (End-to-End Latency)
  • △ Costo de Consumo (Fan-out)
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,
  });
}
Ejemplo de cómo un Cloudflare Worker envía eventos a K2 utilizando una binding, incluyendo manejo de errores retryable.

Fundamentos Teóricos

El concepto de un log inmutable como abstracción central para sistemas distribuidos tiene sus raíces en trabajos fundamentales como el de Lamport sobre el ordenamiento de eventos en sistemas distribuidos (Lamport, 1978) y la noción de un Write-Ahead Log (WAL) en sistemas de bases de datos. La idea de construir sistemas de datos sobre una capa de almacenamiento de objetos duradera y consistente se alinea con la evolución de los sistemas de archivos distribuidos y las bases de datos que buscan desacoplar el cómputo del almacenamiento para mejorar la escalabilidad y la resiliencia.

Aunque K2 no cita directamente un paper específico, su diseño refleja principios de sistemas de almacenamiento de objetos como Amazon S3, que proporcionan durabilidad y consistencia a gran escala. La estrategia de batching para optimizar las operaciones de escritura en un almacenamiento de objetos que no soporta appends directos es una aplicación práctica de técnicas de buffering y flushing comunes en sistemas de E/S para reducir el número de operaciones de disco y mejorar el throughput, a expensas de la latencia individual de escritura.