Un pedido, cuatro sistemas
Un cliente paga su pedido. El almacén tiene que prepararlo, facturación tiene que anotarlo y el servicio de correo tiene que dar las gracias.
Si la web llama a cada uno, un sistema lento frena todos los pedidos. Es mejor escribir un evento en un registro y dejar que cada sistema lo lea cuando esté listo.
Al final de esta lección
Nota
Puedo explicar un registro de eventos y cómo lo leen los consumidores.
Palabras clave
| Palabra | Qué significa | Ejemplo |
|---|---|---|
| Evento | la señal de que algo ha ocurrido | pedido pagado |
| Topic | un registro de eventos que tiene nombre | |
| Partición | un trozo ordenado de un topic | |
| Desplazamiento | el número de un evento dentro de su partición, desde cero (offset en inglés) | |
| Productor | un programa que añade eventos a un topic | |
| Consumidor | un programa que lee los eventos de un topic |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Un topic es un registro donde se añade
Kafka guarda los eventos en un topic. Piensa en el libro de caja de una tienda: las líneas nuevas van al final y las antiguas no cambian.
Un productor añade eventos. Cada uno recibe un desplazamiento, su número de sitio, desde 0. Los eventos se quedan un tiempo fijado, siete días por ejemplo, los haya leído alguien o no.
Ejemplo: un registro y sus desplazamientos
| Desplazamiento | Evento | Escrito por |
|---|---|---|
| 0 | pedido 2001 pagado | web |
| 1 | pedido 2002 pagado | web |
| 2 | pedido 2001 preparado | almacén |
| 3 | pedido 2003 pagado | web |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Crear un topic de dos particiones
curl -s -X POST -H "Content-Type: application/json" -d '{"name":"caja","partitions":2,"replicationFactor":1,"configs":{}}' http://kafka-ui:8080/api/clusters/lab/topics -o /dev/null -w "%{http_code}\n"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Ver los desplazamientos del topic vacío
curl -s http://kafka-ui:8080/api/clusters/lab/topics/caja | grep -o '"partition":[0-9]*\|"offsetMax":[0-9]*'Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Las particiones reparten el trabajo
Un solo registro en una sola máquina no aguantaría los eventos de una gran cadena. Por eso un topic se parte en particiones. Cada una es un registro aparte, con sus propios desplazamientos.
Los eventos mantienen su orden dentro de una misma partición. Entre dos particiones no se promete ningún orden.
Añadir un evento a la partición 0
curl -s -X POST -H "Content-Type: application/json" -d '{"partition":0,"key":"caja1","value":"pan","headers":{},"keySerde":"String","valueSerde":"String"}' http://kafka-ui:8080/api/clusters/lab/topics/caja/messages -w "%{http_code}\n"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Añadir un segundo evento a la partición 0
curl -s -X POST -H "Content-Type: application/json" -d '{"partition":0,"key":"caja1","value":"leche","headers":{},"keySerde":"String","valueSerde":"String"}' http://kafka-ui:8080/api/clusters/lab/topics/caja/messages -w "%{http_code}\n"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Añadir un evento a la partición 1
curl -s -X POST -H "Content-Type: application/json" -d '{"partition":1,"key":"web","value":"arroz","headers":{},"keySerde":"String","valueSerde":"String"}' http://kafka-ui:8080/api/clusters/lab/topics/caja/messages -w "%{http_code}\n"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Volver a mirar los desplazamientos
curl -s http://kafka-ui:8080/api/clusters/lab/topics/caja | grep -o '"partition":[0-9]*\|"offsetMax":[0-9]*'Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Un consumidor recuerda su desplazamiento
Un consumidor lee los eventos de una partición, en orden, y recuerda el desplazamiento del siguiente que necesita. Si se para y arranca de nuevo, sigue donde lo dejó.
Dos servicios pueden leer un mismo topic. Cada uno guarda su desplazamiento: uno lento nunca frena a uno rápido. La distancia entre el final del registro y el desplazamiento de un consumidor es su retraso.
Un consumidor lee y avanza
# Una partición de un topic, como lista. Un consumidor recuerda un solo número.
partition = ["pan", "leche", "café", "arroz"]
offset = 2
print("Leído:", partition[offset], "en el desplazamiento", offset)
offset = offset + 1
print("Siguiente desplazamiento:", offset)
print("Por leer:", len(partition) - offset)
# Cambia el primer desplazamiento por 0 para leer desde el principio.
Dos consumidores, dos desplazamientos
# Dos servicios leen el mismo registro. Cada uno tiene su propio desplazamiento.
log = ["pan", "leche", "café"]
offsets = {"facturacion": 3, "correos": 1}
for name in offsets:
left = len(log) - offsets[name]
print(name, "tiene", left, "mensajes por leer")
# Pon el desplazamiento de correos en 3 y vuelve a ejecutar.
Releer la partición 0 desde el principio
curl -s -N "http://kafka-ui:8080/api/clusters/lab/topics/caja/messages/v2?seekType=BEGINNING&partitions=0&limit=10" | grep -o '"partition":[0-9]*,"offset":[0-9]*\|"value":"[a-z]*"'Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Un error muy común
Advertencia
Mucha gente cree que leer retira el evento, como una carta que sacas de un buzón. En un registro no es así. Leer solo hace avanzar el desplazamiento del consumidor. El evento se queda: otro servicio también puede leerlo.
Para ir más lejos: predecir los desplazamientos
En el terminal, pulsa la flecha hacia arriba hasta recuperar el envío a la partición 1. Cambia arroz por huevos y envíalo dos veces.
Antes de mirar, apunta el offsetMax que esperas en cada partición. Después pulsa el comando que muestra los desplazamientos y compara.