Ruta de crecimiento del arquitecto: interpretación en profundidad del manejo de errores del conector Kafka y la cola de mensajes no entregados

El conector Kafka es parte de Kafka y es un marco poderoso para construir canalizaciones de transmisión entre Kafka y otras tecnologías. Se puede utilizar para transmitir datos desde varios lugares (incluidas bases de datos, colas de mensajes y archivos de texto) a Kafka, y transmitir datos desde Kafka al final de destino (como almacenamiento de documentos, NoSQL, base de datos, almacenamiento de objetos, etc.) .

El mundo real no es perfecto y los errores son inevitables, por lo que es mejor que la canalización de Kafka pueda manejarlo de la manera más elegante posible cuando se producen errores. Un escenario común es recibir mensajes de temas que no coinciden con un formato de serialización específico (por ejemplo, cuando se espera que sea Avro, en realidad es JSON y viceversa). Desde el lanzamiento de Kafka 2.0, el conector Kafka ha incluido una opción de manejo de errores , es decir, la función de enrutar mensajes a una cola de mensajes no entregados , que es una técnica común para construir canalizaciones de datos.

En este artículo, presentaremos varios modos comunes de manejar problemas y explicaremos cómo implementarlos.

Deténgase inmediatamente después de la falla

A veces, es posible que desee detener el procesamiento inmediatamente cuando se produce un error. Puede encontrar que la mala calidad de los datos se debe a motivos ascendentes y debe resolverlos el ascendente. No tiene sentido seguir tratando de procesar otros mensajes.

Ruta de crecimiento del arquitecto: interpretación en profundidad del manejo de errores del conector Kafka y la cola de mensajes no entregados

 

Este es el comportamiento predeterminado del conector Kafka y también se puede especificar explícitamente mediante los siguientes elementos de configuración:

errors.tolerance = none

En este ejemplo, el conector está configurado para leer datos en formato JSON del tema y luego escribirlos en un archivo de texto sin formato. Tenga en cuenta que el conector FileStreamSinkConnector se utiliza con fines de demostración. No se recomienda utilizarlo en producción.

curl -X POST http: // localhost: 8083 / Connectors -H "Content-Type: application / json" -d '{ 
 "name": "file_sink_01", "config": {"connector.class": "org. apache.kafka.connect.file.FileStreamSinkConnector "," temas ":" test_topic_json "," value.converter ":" org.apache.kafka.connect.json.JsonConverter "," value.converter.schemas.enable ": falso , "key.converter": "org.apache.kafka.connect.json.JsonConverter", "key.converter.schemas.enable": false, "file": "/ data / file_sink_01.txt"}} '

Algunos mensajes de formato JSON en el asunto no son válidos, el conector terminará inmediatamente y entrará en el siguiente estado FALLIDO:

$ curl -s "http: // localhost: 8083 / conectores / file_sink_01 / status" | \ 
 jq -c -M '[.name, .tasks []. state]' ["file_sink_01", "FAILED"]

Verifique el registro del nodo trabajador del conector Kafka, puede ver que el error se ha registrado y la tarea ha finalizado:

org.apache.kafka.connect.errors.ConnectException: Tolerancia excedida en el controlador de errores 
 en org.apache.kafka.connect.runtime.errors.RetryWithToleranceOperator.execAndHandleError (RetryWithToleranceOperator.java:178)… Causado por: org.apache. connect.errors.DataException: Error al convertir el byte [] a los datos de Kafka Connect debido a un error de serialización: en org.apache.kafka.connect.json.JsonConverter.toConnectData (JsonConverter.java:334)… Causado por: org.apache.kafka .common.errors.SerializationException: com.fasterxml.jackson.core.JsonParseException: Carácter inesperado ('b' (código 98)): esperaba que el nombre del campo comenzara con comillas dobles en [Fuente: (byte []) "{brokenjson -: "barra 1"} "; línea: 1, columna: 3]

Para arreglar la canalización, debe resolver el problema del mensaje en el tema de origen. A menos que se especifique de antemano, el conector Kafka no simplemente "omitirá" los mensajes no válidos. Si se trata de un error de configuración (por ejemplo, se especifica un convertidor de serialización incorrecto), entonces es mejor Reiniciar el conector después de la corrección. Sin embargo, si de hecho es un mensaje inválido para el asunto, entonces es necesario encontrar una forma, es decir, no evitar el procesamiento de todos los demás mensajes válidos.

Ignore silenciosamente los mensajes no válidos

Si solo desea que continúe el procesamiento:

errores.tolerancia = todos

Ruta de crecimiento del arquitecto: interpretación en profundidad del manejo de errores del conector Kafka y la cola de mensajes no entregados

 

En la práctica, es aproximadamente como sigue:

curl -X POST http: // localhost: 8083 / Connectors -H "Content-Type: application / json" -d '{ 
 "name": "file_sink_05", "config": {"connector.class": "org. apache.kafka.connect.file.FileStreamSinkConnector "," temas ":" test_topic_json "," value.converter ":" org.apache.kafka.connect.json.JsonConverter "," value.converter.schemas.enable ": falso , "key.converter": "org.apache.kafka.connect.json.JsonConverter", "key.converter.schemas.enable": false, "file": "/ data / file_sink_05.txt", "errors.tolerance ": "todas" } }'

Después de iniciar el conector (sigue siendo el tema fuente original, que contiene mensajes válidos y no válidos), puede continuar ejecutando:

$ curl -s "http: // localhost: 8083 / conectores / file_sink_05 / status" | \ 
 jq -c -M '[.name, .tasks []. state]' ["file_sink_05", "RUNNING"]

En este momento, incluso si hay mensajes no válidos en el tema de origen leído por el conector, no habrá errores escritos en la salida del nodo trabajador del conector de Kafka, y los mensajes válidos se escribirán en el archivo de salida como se esperaba:

$ head data / file_sink_05.txt 
{foo = bar 1} {foo = bar 2} {foo = bar 3}…

¿Es posible sentir la pérdida de datos?

Después de configurar errors.tolerance = all, el conector Kafka ignorará los mensajes no válidos y no registrará los mensajes descartados de forma predeterminada. Si confirma la configuración de errors.tolerance = all, entonces debe considerar cuidadosamente si conocer la pérdida real del mensaje y cómo. En la práctica, esto significa monitoreo / alarma basado en indicadores disponibles y / o registro de mensajes de falla.

La forma más sencilla de determinar si se descarta algún mensaje es comparar la cantidad de mensajes en el tema de origen con el número escrito en el destino:

$ kafkacat -b localhost: 9092 -t test_topic_json -o comienzo -C -e -q -X enable.partition.eof = true | wc -l 
 150 $ wc -l datos / file_sink_05.txt 100 datos / file_sink_05.txt

Aunque este enfoque no es muy elegante, se puede ver que el mensaje se pierde, y debido a que no hay ningún registro en el registro, el usuario aún no sabe nada al respecto.

Un método más confiable es usar indicadores JMX para monitorear activamente y alertar la tasa de mensajes de error:

Ruta de crecimiento del arquitecto: interpretación en profundidad del manejo de errores del conector Kafka y la cola de mensajes no entregados

 

En este momento, puede ver que ha ocurrido un error, pero no sabe que el mensaje tiene un error, pero esto es lo que quiere el usuario. De hecho, incluso si estos mensajes descartados se escriben en / dev / null, en realidad puede ser conocido.Este es exactamente el punto donde aparece el concepto de cola de mensajes no entregados.

Enrutar mensajes a la cola de mensajes no entregados

El conector Kafka se puede configurar para enviar mensajes no procesables (como el error de deserialización mencionado anteriormente) a un tema de Kafka separado, la cola de mensajes no procesados. Los mensajes válidos se procesarán normalmente y la canalización seguirá ejecutándose. A continuación, puede comprobar si hay mensajes no válidos de la cola de mensajes no entregados e ignorarlos o corregirlos y volver a procesarlos según sea necesario.

Ruta de crecimiento del arquitecto: interpretación en profundidad del manejo de errores del conector Kafka y la cola de mensajes no entregados

 

La cola de mensajes no entregados se puede habilitar mediante la siguiente configuración:

errors.tolerance = todos los 
errores.deadletterqueue.topic.name =

Si está ejecutando en un clúster Kafka de un solo nodo, también debe configurar errors.deadletterqueue.topic.replication.factor = 1, y su valor predeterminado es 3.

Un ejemplo de una configuración de conector con esta configuración es aproximadamente el siguiente:

curl -X POST http: // localhost: 8083 / Connectors -H "Content-Type: application / json" -d '{ 
 "name": "file_sink_02", "config": {"connector.class": "org. apache.kafka.connect.file.FileStreamSinkConnector "," temas ":" test_topic_json "," value.converter ":" org.apache.kafka.connect.json.JsonConverter "," value.converter.schemas.enable ": false , "key.converter": "org.apache.kafka.connect.json.JsonConverter", "key.converter.schemas.enable": false, "file": "/data/file_sink_02.txt", "errors.tolerance ":" all "," errors.deadletterqueue.topic.name ":" dlq_file_sink_02 "," errors.deadletterqueue.topic.replication.factor ": 1}} '

Use el mismo tema fuente que antes y luego procese los datos JSON válidos y no válidos mezclados, verá que el nuevo conector puede ejecutarse de manera estable:

$ curl -s "http: // localhost: 8083 / conectores / file_sink_02 / status" | \ 
 jq -c -M '[.name, .tasks []. state]' ["file_sink_02", "RUNNING"]

Los registros válidos en el asunto de origen se escribirán en el archivo de destino:

$ head data / file_sink_02.txt 
{foo = bar 1} {foo = bar 2} {foo = bar 3} […]

De esta forma, la canalización puede continuar ejecutándose normalmente y todavía hay datos en el tema de la cola de mensajes no entregados, que se pueden ver en los datos del indicador:

Ruta de crecimiento del arquitecto: interpretación en profundidad del manejo de errores del conector Kafka y la cola de mensajes no entregados

 

Examinando el tema en sí también se puede ver:

ksql> LISTA DE TEMAS; 
 Tema de Kafka | Registrado | Particiones | Réplicas de partición | Consumidores | Grupos de consumidores------------------------------------------------- -------------------------------------------------- dlq_file_sink_02 | falso | 1 | 1 | 0 | 0 test_topic_json | falso | 1 | 1 | 1 | 1 ------------------------------------------------- -------------------------------------------------- ksql> PRINT 'dlq_file_sink_02' FROM BEGINNING; Formato: STRING1 / 24/19 5:16:03 PM UTC, NULL, {foo: "bar 1"} 1/24/19 5:16:03 PM UTC, NULL, { foo: "bar 2"} 24/1/19 5:16:03 p.m. UTC, NULL, {foo: "bar 3"}…

Se puede ver en la salida que la marca de tiempo del mensaje es (24/01/19 5:16:03 PM UTC), la clave es (NULL) y luego el valor. En este momento, puede ver que el valor es un formato JSON no válido {foo: "bar 1"} (foo también debe estar entre comillas), por lo que JsonConverter lanzará una excepción al procesarlo, por lo que eventualmente se enviará al tema de letra muerta.

Pero solo al ver el mensaje puede saber que es JSON no válido. Aun así, solo puede asumir el motivo por el que se rechazó el mensaje. Para determinar el motivo real por el que el conector de Kafka trata el mensaje como no válido, existen dos métodos:

  • El encabezado del mensaje de la cola de mensajes no entregados;
  • El registro del nodo trabajador del conector Kafka.

Se presentarán por separado a continuación.

Razón por la que no se registró el mensaje: encabezado del mensaje

El encabezado del mensaje son metadatos adicionales almacenados con la clave, el valor y la marca de tiempo del mensaje de Kafka, que se introdujo en la versión 0.11 de Kafka. El conector Kafka puede escribir información sobre el motivo del rechazo del mensaje en el encabezado del mensaje en sí. Este enfoque es mejor que escribir en un archivo de registro porque vincula directamente la causa al mensaje.

Configure los siguientes parámetros para incluir el motivo del rechazo en el encabezado del mensaje de la cola de mensajes no entregados:

errors.deadletterqueue.context.headers.enable = true

El ejemplo de configuración es aproximadamente el siguiente:

curl -X POST http: // localhost: 8083 / Connectors -H "Content-Type: application / json" -d '{ 
 "name": "file_sink_03", "config": {"connector.class": "org. apache.kafka.connect.file.FileStreamSinkConnector "," temas ":" test_topic_json "," value.converter ":" org.apache.kafka.connect.json.JsonConverter "," value.converter.schemas.enable ": falso , "key.converter": "org.apache.kafka.connect.json.JsonConverter", "key.converter.schemas.enable": false, "file": "/data/file_sink_03.txt", "errors.tolerance ":" all "," errors.deadletterqueue.topic.name ":" dlq_file_sink_03 "," errors.deadletterqueue.topic.replication.factor ": 1," errores.deadletterqueue.context.headers.enable ": true}} '

Como antes, el conector puede operar normalmente (porque errors.tolerance = todo está configurado).

$ curl -s "http: // localhost: 8083 / conectores / file_sink_03 / status" | \ 
 jq -c -M '[.name, .tasks []. state]' ["file_sink_03", "RUNNING"]

Los mensajes válidos en el asunto de origen se escribirán en el archivo de destino normalmente:

$ head data / file_sink_03.txt 
{foo = bar 1} {foo = bar 2} {foo = bar 3} […]

Puede usar cualquier herramienta de consumo para verificar los mensajes en la cola de mensajes no entregados (antes se usaba KSQL), pero aquí se usará kafkacat, y la razón se verá de inmediato. La operación más simple es aproximadamente la siguiente:

kafkacat -b localhost: 9092 -t dlq_file_sink_03 
% Selección automática del modo de consumidor (use -P o -C para anular) {foo: "bar 1"} {foo: "bar 2"}…

Pero kafkacat tiene funciones más poderosas, puede ver más información que el mensaje en sí:

kafkacat -b localhost: 9092 -t dlq_file_sink_03 -C -o-1 -c1 \ 
 -f '\ nClave (% K bytes):% k Valor (% S bytes):% s Marca de tiempo:% T Partición:% p Desplazamiento: % o Encabezados:% h \ n '

Este comando obtendrá el último mensaje (-o-1, use el último mensaje para el desplazamiento), leerá solo un mensaje (-c1) y lo formateará con el parámetro -f para que sea más fácil de entender:

Clave (-1 bytes): 
 Valor (13 bytes): {foo: "bar 5"} Marca de tiempo: 1548350164096 Partición: 0 Desplazamiento: 34 Encabezados: __connect.errors.topic = test_topic_json, __ connect.errors.partition = 0, __ connect. errors.offset = 94, __ connect.errors.connector.name = file_sink_03, __ connect.errors.task.id = 0, __ connect.errors.stage = VALUE_CONVERTER, __ connect.errors.class.name = org.apache.kafka.connect. json.JsonConverter, __ connect.errors.exception.class.name = org.apache.kafka.connect.errors.DataException, __ connect.errors.exception.message = Error al convertir el byte [] a los datos de Kafka Connect debido a un error de serialización:, __ connect .errors.exception.stacktrace = org.apache.kafka.connect.errors.DataException: Error al convertir el byte [] a los datos de Kafka Connect debido a un error de serialización: […]

También es posible mostrar solo el encabezado del mensaje y usar algunas técnicas simples para dividirlo de modo que pueda ver más información sobre el problema con mayor claridad:

$ kafkacat -b localhost: 9092 -t dlq_file_sink_03 -C -o-1 -c1 -f '% h' | tr ',' '\ n' 
__connect.errors.topic = test_topic_json__connect.errors.partition = 0__connect.errors.offset = 94__connect.errors.connector.name = file_sink_03__connect.errors.task.id = 0__connect.errors.stage = VALUE_CONVERTER__connect.errors.class.name = org.apache.kafka.connect.json.JsonConverter__connect.errors.exception.class.name = org.apache.kafka.connect.errors.DataException__connect.errors.exception.message = Error al convertir el byte [] a los datos de Kafka Connect debido a un error de serialización:

Cada mensaje procesado por el conector Kafka proviene del tema de origen y de un punto específico (desplazamiento) en el tema, y ​​el encabezado del mensaje lo indica con precisión. Por lo tanto, puede usarlo para volver al tema original y verificar el mensaje original cuando sea necesario. Dado que la cola de mensajes no entregados ya tiene una copia del mensaje, esta verificación es más como una práctica de seguros.

Según la información detallada obtenida del encabezado del mensaje anterior, puede verificar el mensaje de origen nuevamente:

__connect.errors.topic = test_topic_json 
__connect.errors.offset = 94

Inserte estos valores en los parámetros -t y -o que representan el tema y el desplazamiento de kafkacat respectivamente, y obtendrá:

$ kafkacat -b localhost: 9092 -C \ 
 -t test_topic_json -o94 \ -f '\ nClave (% K bytes):% k Valor (% S bytes):% s Marca de tiempo:% T Partición:% p Desplazamiento:% o Tema:% t \ n'Key (-1 bytes): Valor (13 bytes): {foo: "bar 5"} Marca de tiempo: 1548350164096 Partición: 0 Desplazamiento: 94 Tema: test_topic_json

En comparación con los mensajes anteriores en la cola de mensajes no entregados, puede ver que son exactamente iguales, incluso incluyendo la marca de tiempo. La única diferencia es el asunto, el desplazamiento y el encabezado del mensaje.

Motivo del error en el mensaje de registro: registro

La segunda opción para registrar el motivo del rechazo de un mensaje es escribirlo en el registro. Dependiendo del método de instalación, el conector Kafka lo escribirá en archivos de registro o de salida estándar. De cualquier manera, se genera un montón de resultados detallados para cada mensaje fallido. Realice la siguiente configuración para habilitar esta función:

errors.log.enable = true

Al configurar errors.log.include.messages = true, también puede incluir metadatos sobre el mensaje en sí en la salida. Estos metadatos incluyen algunos de los mismos elementos que el encabezado del mensaje mencionado anteriormente, incluido el asunto y el desplazamiento del mensaje de origen. Tenga en cuenta que no incluye la clave del mensaje ni el valor en sí.

La configuración del conector en este momento es la siguiente:

curl -X POST http: // localhost: 8083 / Connectors -H "Content-Type: application / json" -d '{ 
 "name": "file_sink_04", "config": {"connector.class": "org. apache.kafka.connect.file.FileStreamSinkConnector "," temas ":" test_topic_json "," value.converter ":" org.apache.kafka.connect.json.JsonConverter "," value.converter.schemas.enable ": falso , "key.converter": "org.apache.kafka.connect.json.JsonConverter", "key.converter.schemas.enable": false, "file": "/data/file_sink_04.txt", "errors.tolerance ":" todos "," errors.log.enable ": verdadero," errors.log.include.messages ": true}} '

El conector puede funcionar correctamente:

$ curl -s "http: // localhost: 8083 / conectores / file_sink_04 / status" | \ 
 jq -c -M '[.name, .tasks []. state]' ["file_sink_04", "RUNNING"] Los registros válidos del tema de origen se escriben en el archivo de destino: $ head data / file_sink_04.txt {foo = barra 1} {foo = barra 2} {foo = barra 3} […]

En este momento, mire el registro del nodo trabajador del conector Kafka y verá que cada mensaje fallido tiene un registro de error:

ERROR Error encontrado en la tarea file_sink_04-0. Ejecutando la etapa 'VALUE_CONVERTER' con la clase 'org.apache.kafka.connect.json.JsonConverter', donde el registro consumido es {topic = 'test_topic_json', partition = 0, offset = 94, timestamp = 1548350164096, timestampType = CreateTime}. (org.apache.kafka.connect.runtime.errors.LogReporter) 
org.apache.kafka.connect.errors.DataException: Error al convertir el byte [] a datos de Kafka Connect debido a un error de serialización: en org.apache.kafka.connect. json.JsonConverter.toConnectData (JsonConverter.java:334) […] Causado por: org.apache.kafka.common.errors.SerializationException: com.fasterxml.jackson.core.JsonParseException: Carácter inesperado ('f' (código 102) ): esperaba que las comillas dobles comenzaran el nombre del campo en [Fuente: (byte []) "{foo:" barra 5 "}"; línea: 1, columna: 3]

Puede ver el error en sí y la información relacionada con el error:

{topic = 'test_topic_json', partition = 0, offset = 94, timestamp = 1548350164096, timestampType = CreateTime}

Como se muestra arriba, el tema y el desplazamiento se pueden usar en herramientas como kafkacat para verificar el mensaje sobre el tema fuente. Dependiendo de la excepción lanzada, también puede ver el mensaje fuente grabado:

Causado por: org.apache.kafka.common.errors.SerializationException: 
… en [Fuente: (byte []) "{foo:" bar 5 "}"; línea: 1, columna: 3]

Procesamiento de mensajes en cola de mensajes no entregados

Aunque se configura una cola de mensajes no entregados, ¿cómo lidiar con esos "mensajes no entregados"? Debido a que es solo un tema de Kafka, puede usar herramientas estándar de Kafka como cualquier otro tema. Como hemos visto anteriormente, por ejemplo, puede usar kafkacat para verificar el encabezado del mensaje, y kafkacat también puede hacer verificaciones generales sobre el contenido del mensaje y sus metadatos. Por supuesto, dependiendo del motivo del rechazo, también puede optar por reproducir el mensaje.

Un escenario es que el conector está usando el convertidor Avro, pero el asunto es un mensaje en formato JSON (y por lo tanto se escribe en la cola de mensajes no entregados). Probablemente debido a razones heredadas, los productores de formato JSON y Avro están escribiendo el tema de origen. Este problema debe resolverse, pero actualmente solo los datos en el flujo de canalización deben escribirse en el receptor.

Primero, comience con el receptor inicial leyendo el tema de origen, use Avro para deserializar y enrutar a la cola de mensajes no entregados:

curl -X POST http: // localhost: 8083 / Connectors -H "Content-Type: application / json" -d '{ 
 "name": "file_sink_06__01-avro", "config": {"connector.class": " org.apache.kafka.connect.file.FileStreamSinkConnector "," temas ":" test_topic_avro "," archivo ":" / data / file_sink_06.txt "," key.converter ":" io.confluent.connect.avro.AvroConverter "," key.converter.schema.registry.url ":" http: // esquema-registro: 8081 "," value.converter ":" io.confluent.connect.avro.AvroConverter "," value.converter.schema .registry.url ":" http: // registro-esquema: 8081 "," errors.tolerance ":" all "," errors.deadletterqueue.topic.name ":" dlq_file_sink_06__01 ","errors.deadletterqueue.topic.replication.factor": 1, "errors.deadletterqueue.context.headers.enable": true, "errors.retry.delay.max.ms": 60000, "errors.retry.timeout": 300000}} '

Además, cree un segundo receptor, use la cola de mensajes no entregados del primer receptor como tema de origen e intente deserializar el registro en JSON. Aquí, debe cambiar value.converter, key.converter, nombre del tema de origen y Nombre de la cola de mensajes no entregados (si este conector necesita enrutar mensajes a la cola de mensajes no entregados, evite la recursividad).

Ruta de crecimiento del arquitecto: interpretación en profundidad del manejo de errores del conector Kafka y la cola de mensajes no entregados

 

curl -X POST http: // localhost: 8083 / conectores -H "Content-Type: application / json" -d '{ 
 "name": "file_sink_06__02-json", "config": {"connector.class": " org.apache.kafka.connect.file.FileStreamSinkConnector "," temas ":" dlq_file_sink_06__01 "," archivo ":" / data / file_sink_06.txt "," value.converter ":" org.apache.kafka.connect.json .JsonConverter "," value.converter.schemas.enable ": false," key.converter ":" org.apache.kafka.connect.json.JsonConverter "," key.converter.schemas.enable ": false," errores .tolerance ":" all "," errors.deadletterqueue.topic.name ":" dlq_file_sink_06__02 "," errors.deadletterqueue.topic.replication.factor ": 1,"errors.deadletterqueue.context.headers.enable": true, "errors.retry.delay.max.ms": 60000, "errors.retry.timeout": 300000}} '

Ahora puedes verificarlo.

Primero, el tema de origen recibe 20 mensajes Avro, y luego puede ver que el receptor Avro original lee y recibe 20 mensajes:

Ruta de crecimiento del arquitecto: interpretación en profundidad del manejo de errores del conector Kafka y la cola de mensajes no entregados

 

Luego envíe 8 mensajes JSON. En este momento, 8 mensajes se envían a la cola de mensajes no entregados y luego los recibe el receptor JSON:

Ruta de crecimiento del arquitecto: interpretación en profundidad del manejo de errores del conector Kafka y la cola de mensajes no entregados

 

Ahora envíe 5 mensajes JSON más formateados incorrectamente, y luego podrá ver que ambos tienen mensajes fallidos. Hay 2 puntos para confirmar:

  1. Existe una diferencia entre la cantidad de mensajes enviados desde el receptor Avro a la cola de mensajes no entregados y la cantidad de mensajes JSON enviados correctamente;
  2. El mensaje se envía a la cola de mensajes no entregados del receptor JSON.

Ruta de crecimiento del arquitecto: interpretación en profundidad del manejo de errores del conector Kafka y la cola de mensajes no entregados

 

Supervisión de la cola de mensajes no entregados a través de KSQL

Además de usar JMX para monitorear la cola de mensajes no entregados, también puede usar las capacidades de agregación de KSQL para escribir una aplicación de transmisión simple para monitorear la velocidad a la que se escriben los mensajes en la cola:

- Registre el flujo para cada tema de la cola de mensajes no entregados.
CREATE STREAM dlq_file_sink_06__01 (MSG VARCHAR) WITH (KAFKA_TOPIC = 'dlq_file_sink_06__01', VALUE_FORMAT = 'DELIMITED'); CREATE STREAM dlq_file_sink_06__02 (DELIMITED 'VARCHEL desde el principio de' VALUE_TOPICDAR '); Consumer data SET'auto.offset.reset '=' earliest '; - Utilice otras columnas para crear un flujo de monitoreo, que se puede usar para consultas de agregación posteriores CREATE STREAM DLQ_MONITOR WITH (VALUE_FORMAT =' AVRO ') AS \ SELECT'dlq_file_sink_06__01' AS SINK_NAME, \ 'Registros:' AS GROUP_COL, \ MSG \ FROM dlq_file_sink_06__01; - Use el mensaje de la segunda cola de mensajes no entregados para inyectar el mismo flujo de monitoreo INSERT INTO DLQ_MONITOR \ SELECT'dlq_file_sink_06__02 'AS SINK_NAME, \' Registros: 'AS GROUP_COL, \ MSG \ FROM dlq_file_sink_06__02; - Crear una vista agregada de mensajes dentro de la ventana de tiempo de cada cola de mensajes no entregados cada minuto CREAR TABLA DLQ_MESSAGE_COUNT_PER_MIN AS \ SELECT TIMESTAMPTOSTRING (WINDOWSTART (), 'aaaa-MM-dd HH: mm: ss') COMO START_TS, \ SINK_NAME, \ GROUP_COL, \ COUNT (*) AS DLQ_MESSAGE_COUNT \ FROM DLQ_MONITOR \ WINDOW TUMBLING (TAMAÑO 1 MINUTE) \ GROUP BY SINK_NAME, \ GROUP_COL;

Esta tabla agregada se puede consultar de forma interactiva. A continuación, se muestra la cantidad de mensajes en cada cola de mensajes no entregados en un minuto:

ksql> SELECT START_TS, SINK_NAME, DLQ_MESSAGE_COUNT FROM DLQ_MESSAGE_COUNT_PER_MIN; 
2019-02-01 02:56:00 | dlq_file_sink_06__01 | 92019-02-01 03:10:00 | dlq_file_sink_06__01 | 82019-02-01 03:12:00 | dlq_file_sink_06__01 | 52019-02-01 02:56:00 | dlq_file_sink_06__02 | 52019-02-01 03:12:00 | dlq_file_sink_06__02 | 5

Debido a que el tema de Kafka se encuentra debajo de esta tabla, se puede enrutar a cualquier panel de monitoreo deseado y también se puede usar para generar alarmas. Suponiendo que algunos mensajes de error son aceptables, pero más de 5 mensajes en un minuto es un gran problema que necesita atención:

CREAR TABLA DLQ_BREACH AS \ 
 SELECT START_TS, SINK_NAME, DLQ_MESSAGE_COUNT \ FROM DLQ_MESSAGE_COUNT_PER_MIN \ WHERE DLQ_MESSAGE_COUNT> 5;

Ahora hay un tema DLQ_BREACH al que el servicio de alarma puede suscribirse y, cuando se recibe cualquier mensaje, se pueden activar las acciones adecuadas (como una notificación).

ksql> SELECT START_TS, SINK_NAME, DLQ_MESSAGE_COUNT FROM DLQ_BREACH; 
2019-02-01 02:56:00 | dlq_file_sink_06__01 | 92019-02-01 03:10:00 | dlq_file_sink_06__01 | 8

¿Dónde proporciona el conector Kafka el manejo de errores?

El método de manejo de errores del conector Kafka se muestra en la siguiente tabla:

¿La descripción de la etapa del ciclo de vida del conector maneja errores? Cuando el conector se inicia por primera vez, realizará la inicialización necesaria, como conectarse al almacén de datos, sin extracción (para el conector de origen), leer mensajes del almacén de datos de origen, conversión sin formato, leer y escribir datos de temas de Kafka y formato JSON / Avro Para la serialización / deserialización, hay una aplicación de conversión de mensaje único, cualquier conversión de mensaje único configurada, hay una recepción (para el conector receptor), el mensaje se escribe en el almacén de datos de destino ninguno

Tenga en cuenta que el conector de origen no tiene una cola de mensajes no entregados.

Proceso de configuración de manejo de errores

Con respecto a la configuración del manejo de errores del conector, puede seguir los pasos a continuación:

Ruta de crecimiento del arquitecto: interpretación en profundidad del manejo de errores del conector Kafka y la cola de mensajes no entregados

 

para resumir

El manejo de errores es una parte importante de cualquier canalización de datos estable y confiable. Dependiendo de cómo se usen los datos, hay dos opciones. Si algún mensaje de error de la canalización es inaceptable, lo que indica que hay un problema grave en sentido ascendente, el procesamiento debe detenerse inmediatamente (este es el comportamiento predeterminado del conector Kafka).

Por otro lado, si solo desea transmitir datos al almacenamiento para su análisis o procesamiento no crítico, es más importante mantener la canalización funcionando de manera estable siempre que no se propaguen los errores. En este momento, puede definir el método de manejo de errores. La forma recomendada es usar una cola de mensajes no entregados y monitorear de cerca las métricas JMX disponibles desde el conector Kafka.

Al final

Los lectores que vean esto pueden reenviar y seguir, ¡y se actualizarán más artículos destacados en el futuro!

Supongo que te gusta

Origin blog.csdn.net/python8989/article/details/108524399
Recomendado
Clasificación