Ya sea que usemos Kafka como cola, bus de mensajes o plataforma de almacenamiento de datos, siempre un productor escribe datos en Kafka, un consumidor lee datos de Kafka o una aplicación cumple ambos roles.
Por ejemplo, en un sistema de procesamiento de transacciones de tarjetas de crédito, habrá una aplicación de cliente, tal vez una tienda en línea, responsable de enviar cada transacción a Kafka inmediatamente cuando se realiza un pago. Otra aplicación es responsable de verificar inmediatamente esta transacción con un motor de reglas y determinar si la transacción se aprueba o se niega. La respuesta de aprobación / denegación se puede volver a escribir a Kafka y la respuesta se puede propagar a la tienda en línea donde se inició la transacción. Una tercera aplicación puede leer tanto las transacciones como el estado de aprobación de Kafka y almacenarlos en una base de datos donde los analistas pueden luego revisar las decisiones y quizás mejorar el motor de reglas.
Apache Kafka se envía con API de cliente integradas que los desarrolladores pueden usar cuando desarrollan aplicaciones que interactúan con Kafka.
Hay muchas razones por las que una aplicación puede necesitar escribir mensajes en Kafka: registrar las actividades del usuario para auditoría o análisis, registrar métricas, almacenar mensajes de registro, registrar información de dispositivos inteligentes, comunicarse de forma asíncrona con otras aplicaciones, almacenar información en búfer antes de escribir en una base de datos y mucho más.
Esos diversos casos de uso también implican diversos requisitos: ¿cada mensaje es crítico o podemos tolerar la pérdida de mensajes? ¿Estamos de acuerdo con la duplicación accidental de mensajes? ¿Existe algún requisito estricto de latencia o rendimiento que debamos cumplir?
En el ejemplo de procesamiento de transacciones con tarjeta de crédito que presentamos anteriormente, podemos ver que es fundamental no perder un solo mensaje ni duplicar ningún mensaje. La latencia debe ser baja, pero se pueden tolerar latencias de hasta 500 ms y el rendimiento debe ser muy alto: esperamos procesar hasta un millón de mensajes por segundo.
Un caso de uso diferente podría ser almacenar información de clics de un sitio web. En ese caso, se puede tolerar la pérdida de algunos mensajes o algunos duplicados; La latencia puede ser alta siempre que no afecte a la experiencia del usuario. En otras palabras, no nos importa si el mensaje tarda unos segundos en llegar a Kafka, siempre que la página siguiente se cargue inmediatamente después de que el usuario haga clic en un enlace. El rendimiento dependerá del nivel de actividad que preveamos en nuestro sitio web.
Los diferentes requisitos influirán en la forma en que utilice la API del productor para escribir mensajes en Kafka y la configuración que utilice.
Si bien las API del productor son muy simples, hay un poco más que sucede bajo el capó del productor cuando enviamos datos.
Comenzamos a producir mensajes a Kafka creando un ProducerRecord, que debe incluir el tema al que queremos enviar el registro y un valor. Opcionalmente, también podemos especificar una clave y / o una partición. Una vez que enviamos el ProducerRecord, lo primero que hará el productor es serializar la clave y los objetos de valor en ByteArrays para que puedan enviarse a través de la red.
A continuación, los datos se envían a un particionador. Si especificamos una partición en ProducerRecord, el particionador no hace nada y simplemente devuelve la partición que especificamos. Si no lo hicimos, el particionador elegirá una partición por nosotros, generalmente basada en la clave ProducerRecord. Una vez que se selecciona una partición, el productor sabe a qué tema y partición irá el registro. Luego agrega el registro a un lote de registros que también se enviarán al mismo tema y partición. Un hilo independiente es responsable de enviar esos lotes de registros a los brokers de Kafka correspondientes.
Cuando el broker recibe los mensajes, envía una respuesta. Si los mensajes se escribieron correctamente en Kafka, devolverá un objeto RecordMetadata con el tema, la partición y el desplazamiento del registro dentro de la partición. Si el corredor no pudo escribir los mensajes, devolverá un error. Cuando el productor recibe un error, puede volver a intentar enviar el mensaje unas cuantas veces más antes de darse por vencido y devolver un error.