Solución de problemas de los consumidores de secuencias de datos de Kinesis - Amazon Kinesis Data Streams

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Solución de problemas de los consumidores de secuencias de datos de Kinesis

Algunos registros de Kinesis Data Streams se omiten al usar Kinesis Client Library

La causa más frecuente de la omisión de registros es que haya una excepción de processRecords no administrada. Kinesis Client Library (KCL) depende del código processRecords para administrar cualquier excepción que surja del procesamiento de los registros de datos. Cualquier excepción que se origine en processRecords se absorbe en KCL. Para evitar los reintentos infinitos sobre un error recurrente, KCL no reenvía el lote de registros procesados en el momento de la excepción. A continuación, KCL llama a processRecords para solicitar el siguiente lote de registros de datos sin reiniciar el procesador de registros. Esto da como resultado que en las aplicaciones consumidoras se observen registros omitidos. Para evitar que se omitan registros, administre todas las excepciones de processRecords convenientemente.

Registros que pertenecen al mismo fragmento se procesan en distintos procesadores de registros a la vez

Para cualquier aplicación de Kinesis Client Library (KCL) en ejecución, una partición solo tiene un propietario. Sin embargo, varios procesadores de registros podrían procesar el mismo fragmento temporalmente. En el caso de una instancia de un proceso de trabajo que pierda la conectividad de red, KCL asume que el proceso de trabajo inaccesible ya no está procesando registros, después de que pase el tiempo de conmutación por error, y da instrucciones a otras instancias de procesos de trabajo para sustituirla. Durante un breve periodo, los nuevos procesadores de registros y los procesadores de registros del proceso de trabajo inaccesible pueden procesar datos procedentes del mismo fragmento.

Debe definir un tiempo de conmutación por error que sea adecuado para su aplicación. En el caso de las aplicaciones de baja latencia, el valor predeterminado de 10 segundos puede representar el tiempo máximo que desee esperar. Sin embargo, en aquellos casos en los que prevea que se producirán problemas de conectividad, como al hacer llamadas en zonas geográficas en las que la conectividad se podría perder con más frecuencia, puede que este número sea demasiado bajo.

Su aplicación debe anticiparse a esta situación y administrarla, especialmente debido a que la conectividad de red normalmente se restaura al proceso de trabajo previamente inaccesible. Si los fragmentos de un procesador de registros son ocupados por otro procesador de registros, debe afrontar los dos casos siguientes para cerrarse sin ocasionar problemas:

  1. Después de que se complete la llamada actual a processRecords, KCL invoca el método de cierre en el procesador de registros con el motivo "ZOMBIE". Cabe esperar que sus procesadores de registros eliminen los recursos según corresponda y, a continuación, se cierren.

  2. Si intenta crear un punto de comprobación en un proceso de trabajo "zombie", KCL producirá una ShutdownException. Tras recibir esta excepción, lo normal es que el código salga del método actual sin ocasionar problemas.

Para obtener más información, consulte Administración de registros duplicados.

La aplicación consumidora lee a una velocidad menor que lo esperado

Los motivos más comunes para que el rendimiento de lectura sea menor que lo esperado son los siguientes:

  1. Varias aplicaciones consumidoras tienen lecturas totales que superan los límites por fragmento. Para obtener más información, consulte Cuotas y límites. En este caso, puede aumentar el número de particiones en el flujo de datos de Kinesis.

  2. El límite que especifica el número máximo de comandos GetRecords por llamada puede haberse configurado con un valor bajo. Si utiliza KCL, es posible que haya configurado el proceso de trabajo con un valor bajo para la propiedad maxRecords. En general, recomendamos que utilice los valores predeterminados del sistema para esta propiedad.

  3. La lógica de la llamada processRecords puede tardar más de lo previsto por una serie de posibles razones; la lógica puede requerir un uso intensivo de la CPU, bloquear la E/S o provocar un efecto embudo en la sincronización. Para probar si alguno de estos supuestos es cierto, realice ejecuciones de prueba de procesadores de registros vacíos y compare el rendimiento de lectura. Para obtener información sobre cómo mantener la entrada de datos, consulte Cambio en los fragmentos, escalado y procesamiento paralelo.

Si tiene una única aplicación consumidora, siempre puede leer al menos dos veces más rápido que la velocidad de inclusión. Esto se debe a que puede escribir hasta 1000 registros por segundo para escrituras, hasta un máximo de escritura de datos de 1 MB por segundo (incluidas las claves de partición). Cada partición abierta admite hasta 5 transacciones por segundo en el caso de las lecturas, con una velocidad máxima total de lectura de datos de 2 MB por segundo. Tenga en cuenta que con cada lectura (llamada a GetRecords) se obtiene un lote de registros. El tamaño de los datos devueltos por GetRecords varía en función del uso del fragmento. El volumen máximo de datos que GetRecords puede devolver es de 10 MB. Si una llamada devuelve ese límite, las llamadas posteriores realizadas en los siguientes 5 segundos provocan una ProvisionedThroughputExceededException.

GetRecords Devuelve una matriz de registros vacía incluso cuando hay datos en la transmisión

El consumo o la obtención de registros se basa en un modelo de extracción. Se espera que los desarrolladores GetRecordsrealicen llamadas en un bucle continuo sin interrupciones. Cada llamada a GetRecords devuelve también un valor ShardIterator que debe utilizarse en la siguiente iteración del bucle.

La operación GetRecords no se bloquea. En su lugar, se devuelve de inmediato, con registros de datos relevantes o con un elemento Records vacío. Un elemento Records vacío se devuelve con dos condiciones:

  1. No hay más datos actualmente en el fragmento.

  2. No hay datos cerca de la parte del fragmento a la que apunta el ShardIterator.

La última condición es sutil, pero supone un equilibrio de diseño necesario para evitar el tiempo de búsqueda ilimitado (latencia) al recuperar registros. Por lo tanto, la aplicación que consume la secuencia debe proceder en bucle y llamar a GetRecords, ocupándose también de los registros vacíos.

En un escenario de producción, la única vez que se debería salir del bucle continuo es cuando el valor NextShardIterator es NULL. Cuando NextShardIterator es NULL, significa que el fragmento actual se ha cerrado y el valor ShardIterator, de lo contrario, apuntaría más allá del último registro. Si la aplicación consumidora nunca llama a SplitShard o a MergeShards, el fragmento permanece abierto y las llamadas a GetRecords nunca devuelven para NextShardIterator el valor NULL.

Si utiliza Kinesis Client Library (KCL), el patrón de consumo anterior se abstrae automáticamente. Esto incluye la administración automática de un conjunto de fragmentos que cambian de forma dinámica. Con KCL, el desarrollador solo suministra la lógica para procesar registros de entrada. Esto es posible porque la biblioteca realiza automáticamente llamadas continuas a GetRecords.

El iterador de fragmentos caduca de forma inesperada

Con cada nueva solicitud GetRecords se devuelve un nuevo iterador de fragmentos (como NextShardIterator) que debe usar entonces en la siguiente solicitud GetRecords (como ShardIterator). Normalmente, este iterador de fragmentos no caduca antes de utilizarlo. Sin embargo, los iteradores de fragmentos pueden caducar por no haber llamado a GetRecords durante más de 5 minutos, o porque haber reiniciado la aplicación consumidora.

Si el iterador de particiones caduca inmediatamente, antes de poder utilizarlo, esto podría indicar que la tabla de DynamoDB que utiliza Kinesis no tiene capacidad suficiente para almacenar los datos arrendados. Es más probable que se dé esta situación si tiene un gran número de fragmentos. Para solucionar este problema, aumente la capacidad de escritura asignada a la tabla de fragmentos. Para obtener más información, consulte Uso de una tabla de arrendamiento para realizar el seguimiento de las particiones procesadas por la aplicación de consumo de KCL.

El procesamiento de registros del consumidor se queda atrás

En la mayoría de casos de uso, las aplicaciones consumidoras leen los datos más recientes de la secuencia. En determinadas circunstancias, puede que las lecturas del consumidor se queden atrás, lo que no es deseable. Tras identificar el retraso con el que están realizando las lecturas sus consumidores, consulte los motivos más comunes por los que estos se retrasan.

Comience por la métrica GetRecords.IteratorAgeMilliseconds, que controla la posición de lectura de todos los fragmentos y los consumidores de la secuencia. Tenga en cuenta que si la antigüedad de un iterador supera el 50 % del periodo de retención (con un valor predeterminado de 24 horas pero configurable hasta 365 días), existe el riesgo de pérdida de datos debido a la caducidad del registro. Una parche rápido es aumentar el periodo de retención. Así se detiene la pérdida de datos importantes mientras se realizan los pasos para solucionar el problema. Para obtener más información, consulte Supervisión del servicio Amazon Kinesis Data Streams con Amazon CloudWatch. A continuación, identifique el retraso con el que su aplicación de consumo lee cada fragmento mediante una CloudWatch métrica personalizada emitida por la Biblioteca de clientes de Kinesis (KCL). MillisBehindLatest Para obtener más información, consulte Supervisión de la biblioteca de clientes de Kinesis con Amazon CloudWatch.

Estos son los motivos más comunes por los que los consumidores se pueden retrasar:

  • Los grandes aumentos repentinos de GetRecords.IteratorAgeMilliseconds o MillisBehindLatest suelen indicar un problema transitorio, como que la operación de la API provoca un error en una aplicación descendente. Debe investigar estos aumentos repentinos si alguna de las métricas muestra constantemente este comportamiento.

  • Un incremento gradual de estas métricas indica que un consumidor no mantiene el ritmo de la secuencia porque no procesa los registros lo suficientemente rápido. Las causas más comunes para este comportamiento son la insuficiencia de recursos físicos o una lógica de procesamiento de registros que no está ajustada a un aumento en el rendimiento de la secuencia. Para comprobar este comportamiento, consulte las demás CloudWatch métricas personalizadas que la KCL emite asociadas a la processTask operación, incluidas, y. RecordProcessor.processRecords.Time Success RecordsProcessed

    • Si percibe un aumento en la métrica processRecords.Time que se correlaciona con una mejora en el rendimiento, debe analizar su lógica de procesamiento de registros para identificar por qué no se ajusta al aumento de rendimiento.

    • Si percibe un incremento de los valores processRecords.Time que no está correlacionado con el aumento de rendimiento, compruebe si está realizando llamadas de bloqueo en la ruta crítica, ya que suelen ser la causa de la reducción de velocidad en el procesamiento de registros. Otro enfoque consiste en aumentar el paralelismo incrementando el número de fragmentos. Por último, confirme que tiene una cantidad suficiente de recursos físicos (memoria, uso de CPU, etc.) en los nodos de procesamiento subyacentes durante los picos de demanda.

Error de permisos no autorizados para la clave maestra de KMS

Este error se produce cuando una aplicación consumidora lee desde una secuencia cifrada sin permisos para la clave maestra de KMS. Para asignar permisos a una aplicación de modo que pueda obtener acceso a una clave de KMS, consulte Uso de políticas de claves en AWS KMS y Uso de políticas de IAM con AWS KMS.

Problemas, preguntas e ideas de solución de problemas comunes para los consumidores