O Spanner oferece um conjunto de tabelas de estatísticas incorporadas para ajudar a obter estatísticas sobre as suas consultas, leituras e transações. Para correlacionar estatísticas com o código da aplicação e melhorar a resolução de problemas, pode adicionar uma etiqueta (uma string de forma livre) às operações de leitura, consulta e transação do Spanner no código da aplicação. Estas etiquetas são preenchidas em tabelas de estatísticas, o que ajuda a correlacionar e pesquisar com base nas etiquetas.
O Spanner suporta dois tipos de etiquetas: etiquetas de pedido e etiquetas de transação. Como os nomes sugerem, pode adicionar etiquetas de transações a transações e etiquetas de pedidos a consultas individuais e APIs de leitura. Pode definir uma etiqueta de transação ao nível da transação e definir etiquetas de pedidos individuais para cada pedido de API aplicável na transação. As etiquetas de pedidos e as etiquetas de transações definidas no código da aplicação são preenchidas nas colunas das seguintes tabelas de estatísticas.
Tabela de estatísticas | Tipo de etiquetas preenchidas na tabela de estatísticas |
---|---|
Estatísticas de consultas TopN | Etiquetas de pedidos |
Estatísticas de leitura TopN | Etiquetas de pedidos |
Estatísticas de transações TopN | Etiquetas de transação |
Estatísticas de bloqueio TopN | Etiquetas de transação |
Etiquetas de pedidos
Pode adicionar uma etiqueta de pedido opcional a uma consulta ou a um pedido de leitura. O Spanner agrupa as estatísticas por etiqueta de pedido, que é visível no campo REQUEST_TAG
das tabelas de estatísticas de consultas e estatísticas de leitura.
Quando usar etiquetas de pedidos
Seguem-se alguns dos cenários que beneficiam da utilização de etiquetas de pedidos.
- Encontrar a origem de uma consulta ou leitura problemática: o Spanner recolhe estatísticas para leituras e consultas em tabelas de estatísticas incorporadas. Quando encontrar as consultas lentas ou as leituras que consomem muita CPU na tabela de estatísticas, se já tiver atribuído etiquetas a essas consultas, pode identificar a origem (aplicação/microsserviço) que está a chamar estas operações com base nas informações na etiqueta.
- Identificar leituras ou consultas em tabelas de estatísticas: a atribuição de etiquetas de pedidos ajuda a filtrar linhas na tabela de estatísticas com base nas etiquetas que lhe interessam.
- Saber se as consultas de uma determinada aplicação ou microsserviço são lentas: as etiquetas de pedidos podem ajudar a identificar se as consultas de uma determinada aplicação ou microsserviço têm latências mais elevadas.
- Agrupar estatísticas para um conjunto de leituras ou consultas: pode usar etiquetas de pedidos para monitorizar, comparar e comunicar o desempenho num conjunto de leituras ou consultas semelhantes. Por exemplo, se várias consultas estiverem a aceder a uma tabela/conjunto de tabelas com o mesmo padrão de acesso, pode considerar adicionar a mesma etiqueta a todas essas consultas para as acompanhar em conjunto.
Como atribuir etiquetas de pedidos
O exemplo seguinte mostra como definir etiquetas de pedidos através das bibliotecas cliente do Spanner.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Como ver etiquetas de pedidos na tabela de estatísticas
A seguinte consulta devolve as estatísticas de consultas em 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;
Vamos usar os seguintes dados como exemplo dos resultados que recebemos da nossa consulta.
text | 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; | [string vazia] | 154 | 0,048 | 42 | 486,33 |
A partir desta tabela de resultados, podemos ver que, se tiver atribuído um REQUEST_TAG
a uma consulta, este é preenchido na tabela de estatísticas. Se não existir nenhuma etiqueta de pedido atribuída, é apresentada como uma string vazia.
Para as consultas etiquetadas, as estatísticas são agregadas por etiqueta (por exemplo, a etiqueta de pedido
app=concert,env=dev,action=select
tem uma latência média de 0,025
segundos). Se não for atribuída nenhuma etiqueta, as estatísticas são agregadas por consulta (por exemplo, a consulta na terceira linha tem uma latência média de 0,048 segundos).
Etiquetas de transação
Pode adicionar uma etiqueta de transação opcional a transações individuais.
O Spanner agrupa as estatísticas por etiqueta de transação, que é visível no campo TRANSACTION_TAG
das tabelas de estatísticas de transações.
Quando usar etiquetas de transações
Seguem-se alguns dos cenários que beneficiam da utilização de etiquetas de transação.
- Encontrar a origem de uma transação problemática: o Spanner recolhe estatísticas para transações de leitura/escrita na tabela de estatísticas de transações. Quando encontra transações lentas na tabela de estatísticas de transações, se já lhes tiver atribuído etiquetas, pode identificar a origem (aplicação/microsserviço) que está a chamar estas transações com base nas informações na etiqueta.
- Identificar transações em tabelas de estatísticas: a atribuição de etiquetas de transação ajuda a filtrar linhas na tabela de estatísticas de transações com base nas etiquetas que lhe interessam. Sem etiquetas de transações, descobrir que operações são representadas por uma estatística pode ser um processo complicado. Por exemplo, para as estatísticas de transações, teria de examinar as tabelas e as colunas envolvidas para identificar a transação não etiquetada.
- Saber se as transações de uma determinada aplicação ou microsserviço são lentas: as etiquetas de transações podem ajudar a identificar se as transações de uma determinada aplicação ou microsserviço têm latências mais elevadas.
- Agrupar estatísticas para um conjunto de transações: pode usar etiquetas de transações para monitorizar, comparar e comunicar o desempenho de um conjunto de transações semelhantes.
- Determinar que transações estão a aceder às colunas envolvidas no conflito de bloqueio: as etiquetas de transações podem ajudar a identificar transações individuais que causam conflitos de bloqueio nas tabelas de estatísticas de bloqueio.
- Transmitir dados de alterações de utilizadores do Spanner através de streams de alterações: os registos de dados de streams de alterações contêm etiquetas de transações para as transações que modificaram os dados do utilizador. Isto permite que o leitor de um fluxo de alterações associe as alterações ao tipo de transação com base em etiquetas.
Como atribuir etiquetas de transações
O exemplo seguinte mostra como definir etiquetas de transações através das bibliotecas de cliente do Spanner. Quando usa uma biblioteca de cliente, pode definir uma etiqueta de transação no início da chamada de transação, que é aplicada a todas as operações individuais nessa transação.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Como ver etiquetas de transações na tabela de estatísticas de transações
A seguinte consulta devolve as estatísticas de transações em 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;
Vamos usar os seguintes dados como exemplo dos resultados que recebemos da nossa 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 | [string vazia] | [Singers.FirstName, Singers.LastName, Singers._exists] | 5357 | 0,048 |
A partir desta tabela de resultados, podemos ver que, se tiver atribuído um
TRANSACTION_TAG
a uma transação, este é preenchido na tabela de estatísticas
de transações. Se não existir nenhuma etiqueta de transação atribuída, é apresentado como uma string vazia.
Para as transações etiquetadas, as estatísticas são agregadas por etiqueta de transação (por exemplo, a etiqueta de transação app=concert,env=dev
a tem uma latência média de 0,3508 segundos). Se não existir nenhuma etiqueta atribuída, as estatísticas são agregadas por FPRINT
(por exemplo, 77848338483 na terceira linha tem uma latência média de 0,048 segundos).
Como ver etiquetas de transações na tabela de estatísticas de bloqueios
A seguinte consulta devolve as estatísticas de bloqueio em intervalos de 10 minutos.
A função CAST()
converte o campo BYTES num STRING.row_range_start_key
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;
Vamos usar os seguintes dados como exemplo dos resultados que recebemos da nossa consulta.
row_range_start_key | lock_wait_seconds | sample_lock_requests |
---|---|---|
Músicas(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 |
álbuns(2,1+) | 0,48 | LOCK_MODE: ReaderShared COLUMN: users._exists1 TRANSACTION_TAG: [empty string] LOCK_MODE: WriterShared COLUMN: users._exists TRANSACTION_TAG: [empty string] |
A partir desta tabela de resultados, podemos ver que, se tiver atribuído um
TRANSACTION_TAG
a uma transação, este é preenchido na tabela de estatísticas de bloqueio. Se não estiver atribuída nenhuma etiqueta de transação, é apresentada
como uma string vazia.
Mapeamento entre métodos da API e etiqueta de pedido/transação
As etiquetas de pedidos e as etiquetas de transações são aplicáveis a métodos de API específicos com base no facto de o modo de transação ser uma transação só de leitura ou uma transação de leitura/escrita. Geralmente, as etiquetas de transação são aplicáveis a transações de leitura/escrita, enquanto as etiquetas de pedido são aplicáveis a transações só de leitura. A tabela seguinte mostra o mapeamento dos métodos da API para os tipos de etiquetas aplicáveis.
Métodos da API | Modos de transação | Etiqueta de pedido | Etiqueta de transação |
---|---|---|---|
Ler, StreamingRead |
Transação só de leitura | Sim | Não |
Transação de leitura/escrita | Sim | Sim | |
ExecuteSql, ExecuteStreamingSql1 |
Transação só de leitura1 | Sim1 | Não |
Transação de leitura/escrita | Sim | Sim | |
ExecuteBatchDml | Transação de leitura/escrita | Sim | Sim |
BeginTransaction | Transação de leitura/escrita | Não | Sim |
Consolidação | Transação de leitura/escrita | Não | Sim |
1 Para consultas de streams de alterações executadas através do conetor Dataflow do SpannerIO, o REQUEST_TAG
contém um nome de tarefa do Dataflow.
Limitações
Quando adicionar etiquetas às suas leituras, consultas e transações, tenha em atenção as seguintes limitações:
- O comprimento de uma string de etiqueta está limitado a 50 carateres. As strings que excedam este limite são truncadas.
- Apenas são permitidos carateres ASCII (32-126) numa etiqueta. Os carateres Unicode arbitrários são substituídos por sublinhados.
- Todos os carateres de sublinhado (_) iniciais são removidos da string.
- As etiquetas são sensíveis a maiúsculas e minúsculas. Por exemplo, se adicionar a etiqueta de pedido
APP=cart,ENV=dev
a um conjunto de consultas e adicionarapp=cart,env=dev
a outro conjunto de consultas, o Spanner agrega estatísticas separadamente para cada etiqueta. As etiquetas podem estar em falta nas tabelas de estatísticas na seguinte circunstância:
- Se o Spanner não conseguir armazenar estatísticas para todas as operações etiquetadas executadas durante o intervalo nas tabelas, o sistema dá prioridade às operações com os recursos de consumo mais elevados durante o intervalo especificado.
Nomenclatura das etiquetas
Quando atribui etiquetas às operações da base de dados, é importante considerar que informações quer transmitir em cada string de etiqueta. A convenção ou o padrão que escolher torna as suas etiquetas mais eficazes. Por exemplo, a atribuição de nomes adequados às etiquetas facilita a correlação das estatísticas com o código da aplicação.
Pode escolher qualquer etiqueta que quiser dentro das limitações indicadas. No entanto, recomendamos que crie uma string de etiqueta como um conjunto de pares chave-valor separados por vírgulas.
Por exemplo, suponha que está a usar uma base de dados do Spanner para um exemplo de utilização de comércio eletrónico. Recomendamos que inclua informações sobre a aplicação, o ambiente de desenvolvimento e a ação realizada pela consulta na etiqueta de pedido que vai atribuir a uma consulta específica. Pode considerar atribuir a string da etiqueta no formato de chave-valor como app=cart,env=dev,action=update
.Isto significa que a consulta é chamada a partir da aplicação de carrinho no ambiente de desenvolvimento e é usada para atualizar o carrinho.
Suponhamos que tem outra consulta de uma aplicação de pesquisa de catálogo e atribui a string de etiquetas como app=catalogsearch,env=dev,action=list
. Agora, se alguma destas consultas aparecer na tabela de estatísticas de consultas como consultas de latência elevada, pode identificar facilmente a origem através da etiqueta.
Seguem-se alguns exemplos de como um padrão de etiquetagem pode ser usado para organizar as estatísticas de operações. Estes exemplos não se destinam a ser exaustivos. Também pode combiná-los na string da etiqueta usando um delimitador, como uma vírgula.
Chaves de etiquetas | Exemplos de par de etiqueta-valor | Descrição |
---|---|---|
Aplicação | app=cart app=frontend app=catalogsearch |
Ajuda a identificar a aplicação que está a chamar a operação. |
Ambiente | env=prod env=dev env=test env=staging |
Ajuda a identificar o ambiente associado à operação. |
Framework | framework=spring framework=django framework=jetty |
Ajuda a identificar a estrutura associada à operação. |
Ação | action=list action=retrieve action=update |
Ajuda a identificar a ação realizada pela operação. |
Serviço | service=payment service=shipping |
Ajuda a identificar o microsserviço que está a chamar a operação. |
Aspetos a ter em conta
- Quando atribui um
REQUEST_TAG
, as estatísticas de várias consultas que têm a mesma string de etiqueta são agrupadas numa única linha na tabela de estatísticas de consultas. Apenas o texto de uma dessas consultas é apresentado no campoTEXT
. - Quando atribui um
REQUEST_TAG
, as estatísticas de várias leituras que têm a mesma string de etiqueta são agrupadas numa única linha na tabela de estatísticas de leitura. O conjunto de todas as colunas lidas é adicionado ao campoREAD_COLUMNS
. - Quando atribui um
TRANSACTION_TAG
, as estatísticas das transações que têm a mesma string de etiqueta são agrupadas numa única linha na tabela de estatísticas de transações. O conjunto de todas as colunas escritas pelas transações é adicionado ao campoWRITE_CONSTRUCTIVE_COLUMNS
e o conjunto de todas as colunas lidas é adicionado ao campoREAD_COLUMNS
.
Cenários de resolução de problemas com etiquetas
Encontrar a origem de uma transação problemática
A seguinte consulta devolve os dados não processados das principais transações no período selecionado.
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;
A tabela seguinte apresenta exemplos de dados devolvidos pela nossa consulta, onde temos três aplicações, nomeadamente carrinho, produto e frontend, que são proprietárias ou consultam a mesma base de dados.
Depois de identificar as transações com latência elevada, pode usar as etiquetas associadas para identificar a parte relevante do código da aplicação e resolver problemas adicionais com as estatísticas de transações.
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 | [string vazia] | 0,031 | 0,015 | 14 | 0 |
Da mesma forma, a etiqueta de pedido pode ser usada para encontrar a origem de uma consulta problemática na tabela de estatísticas de consultas e a origem de uma leitura problemática na tabela de estatísticas de leitura.
Encontrar a latência e outras estatísticas para transações de uma aplicação ou um microsserviço específico
Se usou o nome da aplicação ou o nome do microsserviço na string da etiqueta, ajuda a filtrar a tabela de estatísticas de transações por etiquetas que contenham esse nome da aplicação ou nome do microsserviço.
Suponhamos que adicionou novas transações à app de pagamento e quer ver as latências e outras estatísticas dessas novas transações. Se tiver usado o nome da aplicação de pagamentos na etiqueta, pode filtrar a tabela de estatísticas de transações apenas para as etiquetas que contenham app=payment
.
A seguinte consulta devolve as estatísticas de transações para a app de pagamentos em 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;
Segue-se um exemplo 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 |
Da mesma forma, pode encontrar consultas ou leituras de uma aplicação específica na tabela de estatísticas de consultas ou estatísticas de leituras através de etiquetas de pedidos.
Descobrir as transações envolvidas no conflito de bloqueio
Para saber que transações e chaves de linhas registaram os tempos de espera de bloqueio elevados, consultamos a tabela LOCK_STAT_TOP_10MINUTE
, que lista as chaves de linhas, as colunas e as transações correspondentes envolvidas no conflito de bloqueio.
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;
Seguem-se alguns exemplos de saída da nossa consulta:
row_range_start_key | total_lock_wait_seconds | lock_wait_seconds | frac_of_total | sample_lock_requests |
---|---|---|---|---|
Cantores(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 |
A partir desta tabela de resultados, podemos ver que o conflito ocorreu na tabela Singers
na chave SingerId=32. Singers.SingerInfo
é a coluna onde ocorreu o conflito de bloqueio entre ReaderShared
e WriterShared
. Também pode identificar as transações correspondentes (app=cart,service=order
e app=cart,service=redis
) que estão a ter o conflito.
Depois de identificar as transações que causam os conflitos de bloqueio, pode concentrar-se nestas transações usando as estatísticas de transações para compreender melhor o que as transações estão a fazer e se pode evitar um conflito ou reduzir o tempo durante o qual os bloqueios são mantidos. Para mais informações, consulte o artigo Práticas recomendadas para reduzir a contenção de bloqueios.
O que se segue?
- Saiba mais acerca de outras ferramentas de introspeção.
- Saiba mais sobre outras informações que o Spanner armazena para cada base de dados nas tabelas do esquema de informações da base de dados.
- Saiba mais sobre as práticas recomendadas de SQL para o Spanner.
- Saiba mais sobre a investigação da utilização elevada da CPU.