Spanner proporciona un conjunto de tablas de estadísticas integradas para ayudarte a obtener información valiosa sobre tus consultas, lecturas y transacciones. Para correlacionar estadísticas con el código de tu aplicación y mejorar la solución de problemas, puedes añadir una etiqueta (una cadena de formato libre) a las operaciones de lectura, consulta y transacción de Spanner en el código de tu aplicación. Estas etiquetas se rellenan en las tablas de estadísticas para ayudarte a correlacionar y buscar información en función de las etiquetas.
Spanner admite dos tipos de etiquetas: etiquetas de solicitud y etiquetas de transacción. Como indican sus nombres, puedes añadir etiquetas de transacción a las transacciones y etiquetas de solicitud a las APIs de lectura y consulta individuales. Puede definir una etiqueta de transacción en el ámbito de la transacción y definir etiquetas de solicitud individuales para cada solicitud de API aplicable dentro de la transacción. Las etiquetas de solicitud y de transacción que se definen en el código de la aplicación se rellenan en las columnas de las siguientes tablas de estadísticas.
Tabla de estadísticas | Tipo de etiquetas rellenadas en la tabla de estadísticas |
---|---|
Estadísticas de las consultas TopN | Solicitar etiquetas |
Estadísticas de lectura de TopN | Solicitar etiquetas |
Estadísticas de transacciones TopN | Etiquetas de transacción |
Estadísticas de las N cerraduras principales | Etiquetas de transacción |
Solicitar etiquetas
Puedes añadir una etiqueta de solicitud opcional a una consulta o a una solicitud de lectura. Spanner agrupa las estadísticas por etiqueta de solicitud, que se puede ver en el campo REQUEST_TAG
de las tablas de estadísticas de consultas y estadísticas de lecturas.
Cuándo usar etiquetas de solicitud
A continuación se indican algunos de los casos en los que es útil usar etiquetas de solicitud.
- Buscar la fuente de una consulta o lectura problemática: Spanner recoge estadísticas de lecturas y consultas en tablas de estadísticas integradas. Cuando encuentres las consultas lentas o las lecturas que consumen mucha CPU en la tabla de estadísticas, si ya les has asignado etiquetas, podrás identificar la fuente (aplicación o microservicio) que llama a estas operaciones en función de la información de la etiqueta.
- Identificar lecturas o consultas en las tablas de estadísticas: asignar etiquetas de solicitud ayuda a filtrar las filas de la tabla de estadísticas en función de las etiquetas que te interesen.
- Determinar si las consultas de una aplicación o un microservicio concretos son lentas: las etiquetas de solicitud pueden ayudar a identificar si las consultas de una aplicación o un microservicio concretos tienen latencias más altas.
- Agrupar estadísticas de un conjunto de lecturas o consultas: puedes usar etiquetas de solicitud para monitorizar, comparar y generar informes sobre el rendimiento de un conjunto de lecturas o consultas similares. Por ejemplo, si varias consultas acceden a una tabla o a un conjunto de tablas con el mismo patrón de acceso, puede añadir la misma etiqueta a todas esas consultas para hacer un seguimiento conjunto.
Cómo asignar etiquetas de solicitud
En el siguiente ejemplo se muestra cómo definir etiquetas de solicitud mediante las bibliotecas de cliente de Spanner.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Cómo ver las etiquetas de solicitud en la tabla de estadísticas
La siguiente consulta devuelve las estadísticas de consultas en intervalos de 10 minutos.
SELECT t.text,
t.request_tag,
t.execution_count,
t.avg_latency_seconds,
t.avg_rows,
t.avg_bytes
FROM SPANNER_SYS.QUERY_STATS_TOP_10MINUTE AS t
LIMIT 3;
Tomemos los siguientes datos como ejemplo de los resultados que obtenemos de nuestra consulta.
texto | request_tag | execution_count | avg_latency_seconds | avg_rows | avg_bytes |
---|---|---|---|---|---|
SELECT SingerId, AlbumId, AlbumTitle FROM Albums | app=concert,env=dev,action=select | 212 | 0,025 | 21 | 2365 |
select * from orders; | app=catalogsearch,env=dev,action=list | 55 | 0,02 | 16 | 33.35 |
SELECT SingerId, FirstName, LastName FROM Singers; | [empty string] | 154 | 0,048 | 42 | 486,33 |
En esta tabla de resultados, podemos ver que, si has asignado un REQUEST_TAG
a una consulta, se rellena en la tabla de estadísticas. Si no se ha asignado ninguna etiqueta de solicitud, se muestra como una cadena vacía.
En el caso de las consultas etiquetadas, las estadísticas se agregan por etiqueta (por ejemplo, la etiqueta de solicitud app=concert,env=dev,action=select
tiene una latencia media de 0,025 segundos). Si no se ha asignado ninguna etiqueta, las estadísticas se agregan por consulta (por ejemplo, la consulta de la tercera fila tiene una latencia media de 0,048 segundos).
Etiquetas de transacción
Se puede añadir una etiqueta de transacción opcional a las transacciones individuales.
Spanner agrupa las estadísticas por etiqueta de transacción, que se puede ver en el campo TRANSACTION_TAG
de las tablas de estadísticas de transacciones.
Cuándo usar etiquetas de transacción
A continuación, se indican algunos de los casos en los que es útil usar etiquetas de transacción.
- Buscar la fuente de una transacción problemática: Spanner recoge estadísticas de las transacciones de lectura y escritura en la tabla de estadísticas de transacciones. Cuando encuentres transacciones lentas en la tabla de estadísticas de transacciones, si ya les has asignado etiquetas, podrás identificar la fuente (aplicación o microservicio) que llama a estas transacciones en función de la información de la etiqueta.
- Identificar transacciones en tablas de estadísticas: asignar etiquetas a las transacciones ayuda a filtrar las filas de la tabla de estadísticas de transacciones en función de las etiquetas que te interesen. Sin etiquetas de transacción, descubrir qué operaciones representa una estadística puede ser un proceso engorroso. Por ejemplo, para obtener estadísticas de transacciones, tendrías que examinar las tablas y las columnas implicadas para identificar la transacción sin etiquetar.
- Determinar si las transacciones de una aplicación o un microservicio concretos son lentas: las etiquetas de transacción pueden ayudar a identificar si las transacciones de una aplicación o un microservicio concretos tienen latencias más altas.
- Agrupar estadísticas de un conjunto de transacciones: puede usar etiquetas de transacción para monitorizar, comparar y generar informes sobre el rendimiento de un conjunto de transacciones similares.
- Identificar qué transacciones acceden a las columnas implicadas en el conflicto de bloqueo: las etiquetas de transacción pueden ayudar a identificar las transacciones concretas que provocan conflictos de bloqueo en las tablas de Estadísticas de bloqueos.
- Enviar datos de cambios de usuarios desde Spanner mediante flujos de cambios: Los registros de datos de los flujos de cambios contienen etiquetas de transacción de las transacciones que han modificado los datos de los usuarios. De esta forma, el lector de un flujo de cambios puede asociar los cambios con el tipo de transacción en función de las etiquetas.
Cómo asignar etiquetas de transacción
En el siguiente ejemplo se muestra cómo definir etiquetas de transacción con las bibliotecas de cliente de Spanner. Cuando usas una biblioteca de cliente, puedes definir una etiqueta de transacción al principio de la llamada de transacción, que se aplica a todas las operaciones individuales de esa transacción.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Cómo ver las etiquetas de transacción en la tabla Estadísticas de transacciones
La siguiente consulta devuelve las estadísticas de transacciones en intervalos de 10 minutos.
SELECT t.fprint,
t.transaction_tag,
t.read_columns,
t.commit_attempt_count,
t.avg_total_latency_seconds
FROM SPANNER_SYS.TXN_STATS_TOP_10MINUTE AS t
LIMIT 3;
Tomemos los siguientes datos como ejemplo de los resultados que obtenemos de nuestra consulta.
fprint | transaction_tag | read_columns | commit_attempt_count | avg_total_latency_seconds |
---|---|---|---|---|
40015598317 | app=concert,env=dev | [Venues._exists, Venues.VenueId, Venues.VenueName, Venues.Capacity] |
278802 | 0,3508 |
20524969030 | app=product,service=payment | [Singers.SingerInfo] | 129012 | 0,0142 |
77848338483 | [empty string] | [Singers.FirstName, Singers.LastName, Singers._exists] | 5357 | 0,048 |
En esta tabla de resultados, podemos ver que, si has asignado un
TRANSACTION_TAG
a una transacción, se rellena en la tabla de estadísticas de transacciones. Si no se ha asignado ninguna etiqueta de transacción, se muestra como una cadena vacía.
En el caso de las transacciones etiquetadas, las estadísticas se agregan por etiqueta de transacción (por ejemplo, la etiqueta de transacción app=concert,env=dev
a tiene una latencia media de 0,3508 segundos). Si no se ha asignado ninguna etiqueta, las estadísticas se agregan por FPRINT
(por ejemplo, 77848338483 en la tercera fila tiene una latencia media de 0,048 segundos).
Cómo ver las etiquetas de transacción en la tabla Estadísticas de bloqueo
La siguiente consulta devuelve las estadísticas de los bloqueos en intervalos de 10 minutos.
La función CAST()
convierte el campo row_range_start_key
BYTES en una cadena.
SELECT
CAST(s.row_range_start_key AS STRING) AS row_range_start_key,
s.lock_wait_seconds,
s.sample_lock_requests
FROM SPANNER_SYS.LOCK_STATS_TOP_10MINUTE s
LIMIT 2;
Tomemos los siguientes datos como ejemplo de los resultados que obtenemos de nuestra consulta.
row_range_start_key | lock_wait_seconds | sample_lock_requests |
---|---|---|
Canciones(2,1,1) | 0,61 | LOCK_MODE: ReaderShared COLUMN: Singers.SingerInfo TRANSACTION_TAG: app=product,service=shipping LOCK_MODE: WriterShared COLUMN: Singers.SingerInfo TRANSACTION_TAG: app=product,service=payment |
albums(2,1+) | 0,48 | LOCK_MODE: ReaderShared COLUMN: users._exists1 TRANSACTION_TAG: [empty string] LOCK_MODE: WriterShared COLUMN: users._exists TRANSACTION_TAG: [empty string] |
En esta tabla de resultados, podemos ver que, si has asignado un
TRANSACTION_TAG
a una transacción, se rellena en la tabla de estadísticas de bloqueo. Si no se ha asignado ninguna etiqueta de transacción, se muestra como una cadena vacía.
Asignación entre métodos de API y etiquetas de solicitud o transacción
Las etiquetas de solicitud y las etiquetas de transacción se aplican a métodos de API específicos en función de si el modo de transacción es de solo lectura o de lectura y escritura. Por lo general, las etiquetas de transacción se aplican a las transacciones de lectura y escritura, mientras que las etiquetas de solicitud se aplican a las transacciones de solo lectura. En la siguiente tabla se muestra la asignación de métodos de API a los tipos de etiquetas aplicables.
Métodos de la API | Modos de transacción | Etiqueta de solicitud | Etiqueta de transacción |
---|---|---|---|
Leer, StreamingRead |
Transacción de solo lectura | Sí | No |
Transacción de lectura y escritura | Sí | Sí | |
ExecuteSql, ExecuteStreamingSql1 |
Transacción de solo lectura1 | Sí1 | No |
Transacción de lectura y escritura | Sí | Sí | |
ExecuteBatchDml | Transacción de lectura y escritura | Sí | Sí |
BeginTransaction | Transacción de lectura y escritura | No | Sí |
Confirmación | Transacción de lectura y escritura | No | Sí |
1 En las consultas de flujo de cambios ejecutadas mediante el conector Apache Beam SpannerIO Dataflow, el REQUEST_TAG
contiene un nombre de tarea de Dataflow.
Limitaciones
Cuando añadas etiquetas a tus lecturas, consultas y transacciones, ten en cuenta las siguientes limitaciones:
- La longitud de una cadena de etiquetas está limitada a 50 caracteres. Las cadenas que superen este límite se truncarán.
- Solo se permiten caracteres ASCII (32-126) en una etiqueta. Los caracteres Unicode arbitrarios se sustituyen por guiones bajos.
- Se quitan los caracteres de guion bajo (_) iniciales de la cadena.
- Las etiquetas distinguen entre mayúsculas y minúsculas. Por ejemplo, si añade la etiqueta de solicitud
APP=cart,ENV=dev
a un conjunto de consultas y añadeapp=cart,env=dev
a otro conjunto de consultas, Spanner agrega estadísticas por separado para cada etiqueta. Puede que falten etiquetas en las tablas de estadísticas en las siguientes circunstancias:
- Si Spanner no puede almacenar estadísticas de todas las operaciones etiquetadas que se ejecutan durante el intervalo en las tablas, el sistema prioriza las operaciones que consumen más recursos durante el intervalo especificado.
Nombres de etiquetas
Al asignar etiquetas a las operaciones de tu base de datos, es importante que tengas en cuenta qué información quieres transmitir en cada cadena de etiquetas. La convención o el patrón que elijas hará que tus etiquetas sean más eficaces. Por ejemplo, si las etiquetas tienen nombres adecuados, será más fácil correlacionar las estadísticas con el código de la aplicación.
Puedes elegir la etiqueta que quieras dentro de las limitaciones indicadas. Sin embargo, le recomendamos que cree una cadena de etiquetas como un conjunto de pares clave-valor separados por comas.
Por ejemplo, supongamos que usas una base de datos de Spanner para un caso práctico de comercio electrónico. Puede incluir información sobre la aplicación, el entorno de desarrollo y la acción que realiza la consulta en la etiqueta de solicitud que va a asignar a una consulta concreta. Puedes asignar la cadena de la etiqueta en el formato clave-valor como app=cart,env=dev,action=update
.Esto significa que la consulta se llama desde la aplicación del carrito en el entorno de desarrollo y se usa para actualizar el carrito.
Supongamos que tienes otra consulta de una aplicación de búsqueda de catálogo y le asignas la cadena de etiqueta app=catalogsearch,env=dev,action=list
. Ahora, si alguna de estas consultas aparece en la tabla de estadísticas de consultas como una consulta de alta latencia, puede identificar fácilmente la fuente mediante la etiqueta.
A continuación, se muestran algunos ejemplos de cómo se puede usar un patrón de etiquetado para organizar las estadísticas de operaciones. Estos ejemplos no son exhaustivos. También puedes combinarlos en tu cadena de etiquetas usando un delimitador, como una coma.
Etiquetas | Ejemplos de pares etiqueta-valor | Descripción |
---|---|---|
Aplicación | app=cart app=frontend app=catalogsearch |
Ayuda a identificar la aplicación que llama a la operación. |
Entorno | env=prod env=dev env=test env=staging |
Ayuda a identificar el entorno asociado a la operación. |
Framework | framework=spring framework=django framework=jetty |
Ayuda a identificar el framework asociado a la operación. |
Acción | action=list action=retrieve action=update |
Ayuda a identificar la acción realizada por la operación. |
Servicio | service=payment service=shipping |
Ayuda a identificar el microservicio que llama a la operación. |
Importante
- Cuando asignas una
REQUEST_TAG
, las estadísticas de varias consultas que tienen la misma cadena de etiqueta se agrupan en una sola fila de la tabla estadísticas de consultas. Solo se muestra el texto de una de esas consultas en el campoTEXT
. - Cuando asignas un
REQUEST_TAG
, las estadísticas de varias lecturas que tienen la misma cadena de etiqueta se agrupan en una sola fila de la tabla Estadísticas de lectura. El conjunto de todas las columnas que se leen se añade al campoREAD_COLUMNS
. - Cuando asigna un
TRANSACTION_TAG
, las estadísticas de las transacciones que tienen la misma cadena de etiqueta se agrupan en una sola fila de la tabla Estadísticas de transacciones. El conjunto de todas las columnas que escriben las transacciones se añade al campoWRITE_CONSTRUCTIVE_COLUMNS
y el conjunto de todas las columnas que se leen se añade al campoREAD_COLUMNS
.
Situaciones de solución de problemas con etiquetas
Buscar la fuente de una transacción problemática
La siguiente consulta devuelve los datos sin procesar de las transacciones principales del periodo seleccionado.
SELECT
fprint,
transaction_tag,
ROUND(avg_total_latency_seconds,4) as avg_total_latency_sec,
ROUND(avg_commit_latency_seconds,4) as avg_commit_latency_sec,
commit_attempt_count,
commit_abort_count
FROM SPANNER_SYS.TXN_STATS_TOP_10MINUTE
WHERE interval_end = "2020-05-17T18:40:00"
ORDER BY avg_total_latency_seconds DESC;
En la siguiente tabla se muestran datos de ejemplo devueltos por nuestra consulta, en la que tenemos tres aplicaciones (carrito, producto y frontend) que son propietarias de la misma base de datos o la consultan.
Una vez que haya identificado las transacciones que experimentan una latencia alta, puede usar las etiquetas asociadas para identificar la parte pertinente del código de su aplicación y solucionar los problemas con las estadísticas de transacciones.
fprint | transaction_tag | avg_total_latency_sec | avg_commit_latency_sec | commit_attempt_count | commit_abort_count |
---|---|---|---|---|---|
7129109266372596045 | app=cart,service=order | 0,3508 | 0,0139 | 278802 | 142205 |
9353100217060788102 | app=cart,service=redis | 0,1633 | 0,0142 | 129012 | 27177 |
9353100217060788102 | app=product,service=payment | 0,1423 | 0,0133 | 5357 | 636 |
898069986622520747 | app=product,service=shipping | 0,0159 | 0,0118 | 4269 | 1 |
9521689070912159706 | app=frontend,service=ads | 0,0093 | 0,0045 | 164 | 0 |
11079878968512225881 | [empty string] | 0,031 | 0,015 | 14 | 0 |
Del mismo modo, la etiqueta de solicitud se puede usar para encontrar la fuente de una consulta problemática en la tabla estadísticas de consultas y la fuente de una lectura problemática en la tabla estadísticas de lecturas.
Consultar la latencia y otras estadísticas de las transacciones de una aplicación o un microservicio concretos
Si ha usado el nombre de la aplicación o del microservicio en la cadena de la etiqueta, le ayudará a filtrar la tabla de estadísticas de transacciones por etiquetas que contengan ese nombre.
Supongamos que has añadido nuevas transacciones a la aplicación Pagos y quieres ver las latencias y otras estadísticas de esas nuevas transacciones. Si ha usado el nombre de la aplicación de pago en la etiqueta, puede filtrar la tabla de estadísticas de transacciones para que solo se muestren las etiquetas que contengan app=payment
.
La siguiente consulta devuelve las estadísticas de transacciones de la aplicación de pago en intervalos de 10 minutos.
SELECT
transaction_tag,
avg_total_latency_sec,
avg_commit_latency_sec,
commit_attempt_count,
commit_abort_count
FROM SPANNER_SYS.TXN_STATS_TOP_10MINUTE
WHERE STARTS_WITH(transaction_tag, "app=payment")
LIMIT 3;
A continuación, se muestra un ejemplo de resultado:
transaction_tag | avg_total_latency_sec | avg_commit_latency_sec | commit_attempt_count | commit_abort_count |
---|---|---|---|---|
app=payment,action=update | 0,3508 | 0,0139 | 278802 | 142205 |
app=payment,action=transfer | 0,1633 | 0,0142 | 129012 | 27177 |
app=payment, action=retrieve | 0,1423 | 0,0133 | 5357 | 636 |
Del mismo modo, puedes encontrar consultas o lecturas de una aplicación específica en la tabla de estadísticas de consultas o en la de estadísticas de lecturas mediante etiquetas de solicitud.
Descubrir las transacciones implicadas en un conflicto de bloqueo
Para saber qué transacciones y claves de fila han experimentado tiempos de espera de bloqueo elevados, consultamos la tabla LOCK_STAT_TOP_10MINUTE
, que muestra las claves de fila, las columnas y las transacciones correspondientes que están implicadas en el conflicto de bloqueo.
SELECT CAST(s.row_range_start_key AS STRING) AS row_range_start_key,
t.total_lock_wait_seconds,
s.lock_wait_seconds,
s.lock_wait_seconds/t.total_lock_wait_seconds frac_of_total,
s.sample_lock_requests
FROM spanner_sys.lock_stats_total_10minute t, spanner_sys.lock_stats_top_10minute s
WHERE
t.interval_end = "2020-05-17T18:40:00" and s.interval_end = t.interval_end;
A continuación, se muestra un ejemplo de resultado de nuestra consulta:
row_range_start_key | total_lock_wait_seconds | lock_wait_seconds | frac_of_total | sample_lock_requests |
---|---|---|---|---|
Cantantes(32) | 2,37 | 1,76 | 1 | LOCK_MODE: WriterShared COLUMN: Singers.SingerInfo TRANSACTION_TAG: app=cart,service=order LOCK_MODE: ReaderShared COLUMN: Singers.SingerInfo TRANSACTION_TAG: app=cart,service=redis |
En esta tabla de resultados, podemos ver que el conflicto se ha producido en la Singers
tabla con la clave SingerId=32. La Singers.SingerInfo
es la columna en la que se produjo el conflicto de bloqueo entre ReaderShared
y WriterShared
. También puedes identificar las transacciones correspondientes (app=cart,service=order
y app=cart,service=redis
) que están experimentando el conflicto.
Una vez que se hayan identificado las transacciones que provocan los conflictos de bloqueo, puedes centrarte en ellas mediante Estadísticas de transacciones para hacerte una idea más clara de lo que hacen las transacciones y si puedes evitar un conflicto o reducir el tiempo durante el que se mantienen los bloqueos. Para obtener más información, consulta las prácticas recomendadas para reducir la contención de bloqueos.
Siguientes pasos
- Consulta información sobre otras herramientas de introspección.
- Consulta más información sobre los datos que almacena Spanner de cada base de datos en las tablas del esquema de información de la base de datos.
- Consulta más información sobre las prácticas recomendadas de SQL para Spanner.
- Consulta más información sobre cómo investigar el uso elevado de la CPU.