Estaba revisando el documento que entendí que podemos lograr exactamente una sola transacción con la habilitación idempotence=true
idempotencia: el productor idempotente habilita exactamente una vez para un productor contra un solo tema. Básicamente, cada mensaje enviado tiene garantías más fuertes y no se duplicará en caso de que haya un error
Entonces, si ya tenemos idempotencia, ¿por qué necesitamos otra propiedad exactamente, una vez en Kafka Stream? Qué es exactamente diferente entre la idempotencia frente a exactamente una vez
¿Por qué la propiedad de una sola vez no está disponible en Kafka Producer normal?
apache-kafka
apache-kafka-streams
Sandeep
fuente
fuente
Respuestas:
En un entorno distribuido, la falla es un escenario muy común que puede ocurrir en cualquier momento. En el entorno de Kafka, el agente puede fallar, fallas en la red, fallas en el procesamiento, fallas al publicar mensajes o fallas en el consumo de mensajes, etc. Este escenario diferente introdujo diferentes tipos de pérdida y duplicación de datos.
Escenarios de falla
A (Ack Failed): el mensaje publicado por el productor se realizó correctamente con el reintento> 1 pero no se pudo recibir el acuse de recibo debido a un error. En ese caso, el Productor volverá a intentar que el mismo mensaje podría introducir duplicados.
B (El proceso del productor falló en los mensajes por lotes): el productor que envió el lote de mensajes falló con pocos resultados publicados. En ese caso, y una vez que el productor se reinicie, volverá a publicar todos los mensajes del lote que introducirá duplicados en Kafka.
C (Fire & Forget Failed) Mensaje publicado por el productor con reintento = 0 (disparar y olvidar). En caso de falla publicada, no se dará cuenta y enviará el siguiente mensaje, esto causará la pérdida del mensaje.
D (Error del consumidor en el mensaje por lotes) Un consumidor recibe un lote de mensajes de Kafka y confirma manualmente su desplazamiento (enable.auto.commit = false). Si el consumidor falló antes de comprometerse con Kafka, la próxima vez el Consumidor volverá a consumir los mismos registros que reproducen duplicados en el lado del consumidor.
Semántica exactamente una vez
Para lograr la semántica Exactamente una vez en Kafka, utiliza debajo de 3 propiedades
Habilitar idempotente (enable.idempotence = true)
"Tenga en cuenta que habilitar la idempotencia requiere que MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION sea menor o igual a 5, RETRIES_CONFIG sea mayor que 0 y ACKS_CONFIG sea 'todos'. Si el usuario no establece estos valores explícitamente, se elegirán valores adecuados. establecido, se lanzará una ConfigException "
Para lograr la idempotencia, Kafka usa una identificación única que se llama identificación del producto o PID y número de secuencia mientras produce mensajes. El productor sigue incrementando el número de secuencia en cada mensaje publicado que se asigna con un PID único. El intermediario siempre compara el número de secuencia actual con el anterior y rechaza si el nuevo no es +1 mayor que el anterior, lo que evita la duplicación y al mismo tiempo si se muestra una pérdida mayor en los mensajes
En caso de falla, el agente comparará el número de secuencia con el anterior y si la secuencia no aumenta +1 rechazará el mensaje.
Transacción (nivel de aislamiento)
Las transacciones nos dan la capacidad de actualizar atómicamente los datos en múltiples particiones de temas. Todos los registros incluidos en una transacción se guardarán con éxito, o ninguno de ellos lo será. Le permite confirmar las compensaciones de sus consumidores en la misma transacción junto con los datos que ha procesado, lo que permite una semántica de extremo a extremo exactamente una vez .
El productor no espera para escribir un mensaje en kafka donde el productor usa beginTransaction, commitTransaction y abortTransaction (en caso de falla) El consumidor usa aislamiento.nivel read_committed o read_uncommitted
Si un consumidor con aislamiento.level = read_committed llega a un mensaje de control para una transacción que no se ha completado, no entregará más mensajes desde esta partición hasta que el productor confirme o cancele la transacción o se produzca un tiempo de espera de transacción. El productor determina el tiempo de espera de la transacción utilizando la configuración transaction.timeout.ms (valor predeterminado de 1 minuto).
Exactamente una vez en productor y consumidor
En condiciones normales donde tenemos productores y consumidores separados. El productor tiene que administrar las transacciones de forma idempotente y al mismo tiempo para que el consumidor pueda usar el aislamiento. Esto garantiza que el productor siempre se sincronizará con el sistema fuente. Incluso el bloqueo del productor o la transacción cancelada, siempre será coherente y publicará el mensaje o lote de mensaje como unidad una vez.
El mismo consumidor recibirá un mensaje o lote de mensaje como unidad una vez.
Exactamente una vez en Kafka Stream
Kafka Stream consume mensajes del tema A, procesa y publica mensajes en el Tema B y, una vez publicado, usa commit (el commit se ejecuta principalmente bajo cubierta) para vaciar todos los datos del almacén de estado en el disco.
Exactamente una vez en Kafka Stream hay un patrón de lectura-proceso-escritura que garantiza que estas operaciones se tratarán como operaciones atómicas. Dado que Kafka Stream atiende al productor, al consumidor y a la transacción, Kafka Stream viene con un procesamiento especial de parámetros. Garantía que podría exactamente una vez o al menos una vez, lo que hace que la vida sea fácil de manejar todos los parámetros por separado.
Processing.guarantee: exactamente_una vez que proporciona automáticamente los siguientes parámetros que no necesita establecer explícitamente
fuente
Kafka stream ofrece la semántica exactamente una vez desde el punto de vista de extremo a extremo (consume de un tema, procesa ese mensaje y luego produce otro tema). Sin embargo, mencionó solo el atributo idempotente del productor . Esa es solo una pequeña parte de la imagen completa.
Deja que exprese esa pregunta de otra manera:
Respuesta: Dado que la semántica de entrega de una sola vez no es solo en el paso de producción sino también el flujo completo de procesamiento. Para lograr la entrega semántica exactamente una vez, hay algunas condiciones que deben cumplirse con la producción y el consumo.
Este es el escenario genérico: el proceso A produce mensajes sobre el tema T. Al mismo tiempo, el proceso B intenta consumir mensajes del tema T. Queremos asegurarnos de que el proceso B nunca procese un mensaje dos veces.
Parte del productor: debemos asegurarnos de que los productores nunca produzcan un mensaje dos veces. Podemos usar Kafka Idempotent Producer
Parte del consumidor: aquí está el flujo de trabajo básico para el consumidor:
Los pasos anteriores son solo un camino feliz. Hay muchos problemas que surgen en la realidad.
Debido a que pueden ocurrir muchos problemas, la ejecución del trabajo y la compensación de compromiso deben ser atómicas para garantizar exactamente una vez la entrega semántica en el lado del consumidor. No significa que no podamos, pero se necesita mucho esfuerzo para garantizar la entrega semántica de una vez. Kafka Stream defiende el trabajo para los ingenieros.
Señaló que: Kafka Stream ofrece "procesamiento de flujo exactamente una vez". Se refiere a consumir de un tema, materializar el estado intermedio en un tema de Kafka y producir uno. Si nuestra aplicación depende de algunos otros servicios externos (base de datos, servicios ...), debemos asegurarnos de que nuestras dependencias externas puedan garantizar exactamente una vez en esos casos.
TL, DR: exactamente una vez para el flujo completo necesita la cooperación entre productores y consumidores.
Referencias
fuente