Soluciona problemas relacionados con errores de plazo excedido en Spanner

En esta página, se proporciona una descripción general de los errores de plazo excedido de Spanner: qué son, por qué se producen y cómo solucionarlos.

Cuando se accede a las APIs de Spanner, las solicitudes pueden fallar debido a errores DEADLINE_EXCEEDED. Este error indica que no se recibió una respuesta dentro del tiempo de espera configurado.

Un error de vencimiento excedido puede ocurrir por muchos motivos diferentes, como instancias de Spanner sobrecargadas, esquemas no optimizados o consultas no optimizadas. En esta página, se describen situaciones comunes en las que ocurre un error durante la fecha límite y se proporciona una guía sobre cómo investigar y resolver estos problemas.

Plazo y filosofía de reintentos de Spanner

La filosofía de plazos y reintentos de Spanner difiere de muchos otros sistemas. En Spanner, debes especificar un plazo de tiempo de espera como la cantidad máxima de tiempo en el que una respuesta es útil. No se recomienda establecer un plazo corto artificial solo para reintentar de inmediato la misma operación nuevamente, ya que esto generará situaciones en las que las operaciones nunca se completan. En este contexto, no se recomiendan las siguientes estrategias y operaciones, ya que son contraproductivas y anulan el comportamiento de reintento interno de Spanner:

  • Establecer un plazo demasiado breve. Esto significa que la operación no es resistente a los aumentos ocasionales de latencia final y no se puede completar antes de que se agote el tiempo de espera. En su lugar, establece un plazo que sea la cantidad máxima de tiempo en el que una respuesta sea útil.

  • Establecer un plazo demasiado largo y cancelar la operación antes de que se supere el plazo. Esto genera reintentos y desperdicio de trabajo en cada intento. En conjunto, esto puede crear una carga adicional significativa en tu instancia.

¿Qué es un error de plazo excedido?

Cuando usas una de las bibliotecas cliente de Spanner, la capa de gRPC subyacente se encarga de la comunicación, el ordenamiento, el desalineamiento y la aplicación de los plazos. Los plazos permiten que tu aplicación especifique cuánto tiempo estará dispuesta a esperar a que se complete una solicitud antes de que se resuelva con el error de vencimiento excedido.

En la guía de configuración de tiempo de espera, se muestra cómo puedes especificar plazos (o tiempos de espera) en cada una de las bibliotecas cliente compatibles de Spanner. Las bibliotecas cliente de Spanner usan la configuración predeterminada de la política de reintento y tiempo de espera, que se define en los siguientes archivos de configuración:

Para obtener más información sobre los plazos de gRPC, consulta gRPC y fechas límite.

Cómo investigar y resolver los errores comunes de fecha límite excedida

Es posible que encuentres DEADLINE_EXCEEDED de errores para los siguientes tipos de problemas:

Problemas con la API de acceso a los datos

Una instancia de Spanner debe estar configurada de forma adecuada para tus cargas de trabajo específicas a fin de evitar problemas de la API de acceso a los datos. En las siguientes secciones, se describe cómo investigar y resolver diferentes problemas de la API de acceso a los datos.

Verifica la carga de CPU de la instancia de Spanner

La latencia de solicitudes puede aumentar significativamente, ya que el uso de CPU supera el umbral de buen estado recomendado. Puedes verificar el uso de CPU de Spanner en la consola de supervisión proporcionada en la consola de Google Cloud. También puedes crear alertas basadas en el uso de CPU de la instancia.

Solución

Si quieres conocer los pasos para reducir el uso de CPU de la instancia, consulta cómo reducir el uso de CPU.

Verifica el desglose de latencia de extremo a extremo de la solicitud

A medida que una solicitud viaja del cliente a los servidores de Spanner y de vuelta, hay varios saltos de red que se deben realizar: desde la biblioteca cliente hasta Google Front End (GFE); desde GFE hasta el frontend de la API de Spanner y, por último, desde el frontend de la API de Spanner hasta la base de datos de Spanner. Si hay problemas de red en cualquiera de estas etapas, es posible que veas errores de plazo excedido.

Es posible capturar la latencia en cada etapa. Para obtener más información, consulta Puntos de latencia en una solicitud de Spanner. Para saber dónde se produce la latencia en Spanner, consulta Identifica dónde se produce la latencia en Spanner.

Solución

Una vez que obtengas el desglose de latencia, podrás usar métricas para diagnosticar la latencia, comprender por qué está sucediendo y encontrar soluciones.

Problemas con la API de datos

Ciertos patrones de uso no óptimos de la API de datos de Spanner pueden causar errores de vencimiento excedido. En esta sección, se proporcionan lineamientos para verificar estos patrones de uso no óptimos.

Verifica si hay consultas costosas

Si intentas ejecutar consultas costosas que no se ejecutan dentro del plazo de tiempo de espera configurado en las bibliotecas cliente, es posible que se produzca un error de plazo excedido. Algunos ejemplos de consultas costosas incluyen, entre otros, análisis completos de una tabla grande, uniones cruzadas en varias tablas grandes o la ejecución de una consulta con un predicado sobre una columna sin clave (también un análisis completo de la tabla).

Puedes inspeccionar consultas costosas con la tabla de estadísticas de consultas y la tabla de estadísticas de transacciones. En estas tablas, se muestra información sobre consultas y transacciones de ejecución lenta, como la cantidad promedio de filas leídas, el promedio de bytes leídos, la cantidad promedio de filas analizadas y mucho más. Además, puedes generar planes de ejecución de consultas para inspeccionar aún más cómo se ejecutan tus consultas.

Solución

Si deseas optimizar las consultas, usa la guía de prácticas recomendadas para las consultas en SQL. También puedes usar los datos obtenidos a través de las tablas de estadísticas mencionadas antes y los planes de ejecución para optimizar tus consultas y realizar cambios de esquema en tus bases de datos. Estas prácticas recomendadas pueden ayudar a reducir el tiempo de ejecución de las declaraciones, lo que podría ayudar a evitar los errores de fecha límite excedida.

Cómo comprobar la contención de bloqueo

Las transacciones de Spanner deben adquirir bloqueos para confirmar. Las aplicaciones que se ejecutan con una capacidad de procesamiento alta pueden hacer que las transacciones compitan por los mismos recursos, lo que aumenta la espera para obtener los bloqueos y afecta el rendimiento general. Esto podría provocar que se excedan los plazos para cualquier solicitud de lectura o escritura.

Puedes encontrar la causa raíz de las transacciones de lectura y escritura de alta latencia con la tabla de estadísticas de bloqueo y consulta la siguiente entrada de blog. En tu tabla de estadísticas de bloqueo, puedes encontrar las claves de fila con los tiempos de espera de bloqueo más altos.

En esta guía para solucionar problemas de conflictos de bloqueo, se explica cómo encontrar las transacciones que acceden a las columnas involucradas en el conflicto. También puedes descubrir qué transacciones están involucradas en un conflicto de bloqueo con la guía para solucionar problemas con etiquetas de transacción.

Solución

Aplica estas prácticas recomendadas para reducir las contenciones de bloqueo. Además, usa transacciones de solo lectura en casos prácticos de lectura sin formato para evitar conflictos de bloqueo con las escrituras. El uso de transacciones de lectura y escritura debe reservarse para operaciones de escritura o flujos de trabajo mixtos de lectura y escritura. Seguir estos pasos debería mejorar la latencia general del tiempo de ejecución de la transacción y reducir los errores de fecha límite excedida.

Verifica si hay esquemas no optimizados

Antes de diseñar un esquema de base de datos óptimo para la base de datos de Spanner, debes considerar los tipos de consultas que se ejecutarán en la base de datos. Los esquemas subóptimos pueden causar problemas de rendimiento cuando se ejecutan algunas consultas. Estos problemas de rendimiento pueden evitar que las solicitudes se completen dentro del plazo configurado.

Solución

El diseño de esquema más óptimo dependerá de las lecturas y escrituras que se realicen en tu base de datos. Se deben seguir las prácticas recomendadas para el diseño de esquemas y las prácticas recomendadas de SQL, independientemente de las características específicas del esquema. Si sigues estas guías, evitas los problemas más comunes de diseño de esquemas. Otras causas raíz del rendimiento deficiente se atribuyen a tu elección de claves primarias, el diseño de la tabla (consulta cómo usar tablas intercaladas para obtener un acceso más rápido), el diseño de esquemas (consulta Optimiza el esquema para el rendimiento) y el rendimiento del nodo configurado dentro de la instancia de Spanner (consulta la Descripción general del rendimiento de Spanner).

Comprueba si hay hotspots

Debido a que Spanner es una base de datos distribuida, el diseño del esquema debe tener en cuenta la prevención de hotspots. Por ejemplo, crear columnas que aumentan de forma monótona limitará la cantidad de divisiones con las que Spanner puede trabajar para distribuir la carga de trabajo de manera uniforme. Estos cuellos de botella pueden generar tiempos de espera. Además, puedes usar Key Visualizer para solucionar problemas de rendimiento causados por hotspots.

Solución

Consulta las resoluciones identificadas en la sección anterior Verifica si hay esquemas no optimizados como primer paso para resolver este problema. Vuelve a diseñar el esquema de la base de datos y usa índices intercalados para evitar los índices que podrían causar la generación de hotspots. Si seguir estos pasos no reduce el problema, consulta la guía para elegir una clave primaria para evitar la generación de hotspots. Por último, evita los patrones de tráfico subóptimos, como las lecturas de gran rango, que podrían impedir la división basada en la carga.

Verifica si hay tiempos de espera mal configurados

Las bibliotecas cliente proporcionan valores predeterminados de tiempo de espera razonable para todas las solicitudes en Spanner. Sin embargo, es posible que debas ajustar estas opciones de configuración predeterminadas para tu carga de trabajo específica. Vale la pena observar el costo de tus consultas y ajustar los plazos para que sean adecuados para tu caso de uso específico.

Solución

La configuración predeterminada de los tiempos de espera es adecuada para la mayoría de los casos de uso. Los usuarios pueden anular esta configuración (consulta la guía de reintento y tiempo de espera personalizado), pero no se recomienda usar tiempos de espera más agresivos que los predeterminados. Si decides cambiar el tiempo de espera, configúralo como la cantidad de tiempo real que la aplicación está dispuesta a esperar el resultado. Puedes experimentar con tiempos de espera configurados más largos, pero nunca establecer un tiempo de espera inferior al tiempo real que la aplicación está dispuesta a esperar, ya que esto haría que la operación se vuelva a intentar con más frecuencia.

Problemas con la API de Admin

Las solicitudes a la API de Admin son operaciones costosas en comparación con las solicitudes a la API de datos. Las solicitudes de administrador como CreateInstance, CreateDatabase o CreateBackups pueden tardar muchos segundos antes de mostrar una respuesta. Las bibliotecas cliente de Spanner establecen plazos de 60 minutos para las solicitudes de administrador de instancias y bases de datos. Esto permite garantizar que el servidor tenga la oportunidad de completar la solicitud antes de que el cliente vuelva a intentarlo o falle.

Solución

Si usas la biblioteca cliente de Spanner de Google para acceder a la API de administrador, asegúrate de que la biblioteca cliente esté actualizada y use la versión más reciente. Si accedes a la API de Spanner directamente a través de una biblioteca cliente que creaste, asegúrate de no tener una configuración de plazos más agresiva que la configuración predeterminada (60 minutos) para las solicitudes de administrador de la instancia y la base de datos.

Problemas con la consola de Google Cloud

Las consultas emitidas desde la página de Spanner Studio de la consola de Google Cloud no pueden superar los cinco minutos. Si creas una consulta costosa que tarda más de cinco minutos en ejecutarse, verás el siguiente mensaje de error:

Captura de pantalla del mensaje de error Se superó el plazo de la consola de Google Cloud

El backend cancelará la consulta con errores y, si es necesario, la transacción puede revertirse.

Solución

Puedes volver a escribir la consulta con la guía de prácticas recomendadas para consultas en SQL.

Problemas con Dataflow

En Apache Beam, la configuración de tiempo de espera predeterminada es de dos horas para las operaciones de lectura y de 15 segundos para las operaciones de confirmación. Estas configuraciones permiten operaciones más largas en comparación con los tiempos de espera de los plazos de la biblioteca cliente independiente. Sin embargo, es posible que recibas un error de tiempo de espera y de vencimiento excedido cuando los elementos de trabajo son demasiado grandes. Si es necesario, puedes personalizar la configuración del tiempo de espera de confirmación de Apache Beam.

Solución

Si se produce un error de fecha límite excedida en los pasos ReadFromSpanner / Execute query / Read from Spanner / Read from Partitions, revisa la tabla de estadísticas de consultas para averiguar qué consulta analizó una gran cantidad de filas. Luego, modifica esas consultas para intentar reducir el tiempo de ejecución.

En el siguiente mensaje de excepción, se muestra otro ejemplo de un error de vencimiento excedido de Dataflow:

exception:
     org.apache.beam.sdk.util.UserCodeException:
     com.google.cloud.spanner.SpannerException: DEADLINE_EXCEEDED:
     io.grpc.StatusRuntimeException: DEADLINE_EXCEEDED: deadline exceeded after
     3599.999905380s.
     [remote_addr=batch-spanner.googleapis.com/172.217.5.234:443] at
 org.apache.beam.runners.dataflow.worker.GroupAlsoByWindowsParDoFn$1.output(GroupAlsoByWindowsParDoFn.java:184)

Se agotó el tiempo de espera porque los elementos de trabajo son demasiado grandes. En el ejemplo anterior, las siguientes dos recomendaciones podrían ser útiles. Primero, puedes intentar habilitar el servicio de Shuffle si aún no está habilitado. En segundo lugar, puedes intentar ajustar las configuraciones en la lectura de la base de datos, como maxPartitions y partitionSizeBytes. Si deseas obtener más información, consulta PartitionOptions para intentar reducir el tamaño del elemento de trabajo. Puedes encontrar un ejemplo de cómo hacerlo en esta plantilla de Dataflow.

La fecha límite adicional superó los recursos de solución de problemas

Si aún ves un error DEADLINE_EXCEEDED después de completar los pasos para solucionar problemas, abre un caso de ayuda si te ocurren las siguientes situaciones:

  • Una latencia alta de Google Front End, pero una latencia de solicitud a la API de Spanner baja
  • Una latencia de solicitud a la API de Spanner alta, pero una latencia de consultas baja

También puedes consultar los siguientes recursos para solucionar problemas: