Ler estatísticas

O Spanner fornece tabelas incorporadas que armazenam estatísticas sobre leituras. Pode obter estatísticas destas tabelas SPANNER_SYS.READ_STATS* através de declarações SQL.

Quando usar estatísticas de leitura

As estatísticas de leitura fornecem estatísticas sobre a forma como uma aplicação está a usar a base de dados e são úteis quando investiga problemas de desempenho. Por exemplo, pode verificar que formas de leitura estão a ser executadas numa base de dados, com que frequência são executadas e explicar as caraterísticas de desempenho destas formas de leitura. Pode usar as estatísticas de leitura da sua base de dados para identificar formas de leitura que resultam num elevado uso da CPU. Em termos gerais, as estatísticas de leitura ajudam a compreender o comportamento do tráfego que entra numa base de dados em termos de utilização de recursos.

Limitações

  • Esta ferramenta é mais adequada para analisar streams de leituras semelhantes que representam a maior parte da utilização da CPU. Não é adequado para pesquisar leituras que foram executadas apenas uma vez.

  • A utilização da CPU monitorizada nestas estatísticas representa a utilização da CPU do lado do servidor do Spanner, excluindo a utilização da CPU de obtenção prévia e alguns outros custos gerais.

  • As estatísticas são recolhidas com base no melhor esforço. Como resultado, é possível que as estatísticas sejam perdidas se existirem problemas com os sistemas subjacentes. Por exemplo, se existirem problemas de rede internos, é possível que algumas estatísticas não sejam registadas.

Aceda às estatísticas de leitura

O Spanner fornece as estatísticas de leitura no esquema SPANNER_SYS. Pode usar as seguintes formas para aceder aos dados do SPANNER_SYS:

  • A página do Spanner Studio de uma base de dados na Google Cloud consola.

  • O comando gcloud spanner databases execute-sql.

  • O método executeSql ou o método executeStreamingSql.

Os seguintes métodos de leitura única fornecidos pelo Spanner não suportam o SPANNER_SYS:

  • Executar uma leitura forte a partir de uma única linha ou de várias linhas numa tabela.
  • Executar uma leitura desatualizada de uma única linha ou várias linhas numa tabela.
  • Leitura de uma única linha ou várias linhas num índice secundário.

Utilização da CPU agrupada por forma de leitura

As tabelas seguintes monitorizam as formas de leitura com a utilização mais elevada da CPU durante um período específico:

  • SPANNER_SYS.READ_STATS_TOP_MINUTE: leia as estatísticas de formas agregadas em intervalos de 1 minuto.
  • SPANNER_SYS.READ_STATS_TOP_10MINUTE: ler estatísticas de formas agregadas em intervalos de 10 minutos.
  • SPANNER_SYS.READ_STATS_TOP_HOUR: ler estatísticas de formas agregadas em intervalos de 1 hora.

Estas tabelas têm as seguintes propriedades:

  • Cada tabela contém dados para intervalos de tempo não sobrepostos com a duração especificada no nome da tabela.

  • Os intervalos baseiam-se nas horas do relógio. Os intervalos de 1 minuto terminam no minuto, os intervalos de 10 minutos terminam a cada 10 minutos a partir da hora, e os intervalos de 1 hora terminam na hora. Após cada intervalo, o Spanner recolhe dados de todos os servidores e, em seguida, disponibiliza os dados nas tabelas SPANNER_SYS pouco depois.

    Por exemplo, às 11:59:30, os intervalos mais recentes disponíveis para consultas SQL são:

    • 1 minuto: 11:58:00–11:58:59
    • 10 minutos: 11:40:00–11:49:59
    • 1 hora: 10:00:00–10:59:59
  • O Spanner agrupa as estatísticas por forma de leitura. Se estiver presente uma etiqueta, FPRINT é o hash da etiqueta. Caso contrário, é o hash do valor READ_COLUMNS.

  • Cada linha contém estatísticas para todas as execuções de um formato de leitura específico para o qual o Spanner captura estatísticas durante o intervalo especificado.

  • Se o Spanner não conseguir armazenar informações sobre cada forma de leitura distinta executada durante o intervalo, o sistema dá prioridade às formas de leitura com a utilização mais elevada da CPU durante o intervalo especificado.

Esquema da tabela

Nome da coluna Tipo Descrição
INTERVAL_END TIMESTAMP Fim do intervalo de tempo em que ocorreram as execuções de leitura incluídas.
REQUEST_TAG STRING A etiqueta de pedido opcional para esta operação de leitura. Para mais informações acerca da utilização de etiquetas, consulte Resolução de problemas com etiquetas de pedidos. As estatísticas de várias leituras que têm a mesma string de etiqueta são agrupadas numa única linha com a `REQUEST_TAG` correspondente a essa string de etiqueta.
READ_TYPE STRING Indica se uma leitura é um PARTITIONED_READ ou um READ. Uma leitura com um partitionToken obtido a partir da API PartitionRead é representado pelo PARTITIONED_READ tipo de leitura e as outras APIs de leitura por READ.
READ_COLUMNS ARRAY<STRING> O conjunto de colunas que foram lidas. Estes estão por ordem alfabética.
FPRINT INT64 O hash do valor REQUEST_TAG, se estiver presente; caso contrário, o hash do valor READ_COLUMNS.
EXECUTION_COUNT INT64 Número de vezes que o Spanner executou a forma de leitura durante o intervalo.
AVG_ROWS FLOAT64 Número médio de linhas devolvidas pela leitura.
AVG_BYTES FLOAT64 Número médio de bytes de dados devolvidos pela leitura, excluindo a sobrecarga de codificação de transmissão.
AVG_CPU_SECONDS FLOAT64 Número médio de segundos da CPU do lado do servidor do Spanner a executar a leitura, excluindo a CPU de obtenção prévia e outras sobrecargas.
AVG_LOCKING_DELAY_SECONDS FLOAT64 Número médio de segundos passados à espera devido ao bloqueio.
AVG_CLIENT_WAIT_SECONDS FLOAT64 Número médio de segundos passados à espera devido ao facto de o cliente não consumir dados tão rapidamente quanto o Spanner os podia gerar.
AVG_LEADER_REFRESH_DELAY_SECONDS FLOAT64 Número médio de segundos passados à espera da confirmação do líder do Paxos de que todas as escritas foram observadas.
RUN_IN_RW_TRANSACTION_EXECUTION_COUNT INT64 O número de vezes que a leitura foi executada como parte de uma transação de leitura/escrita. Esta coluna ajuda a determinar se pode evitar contestações de bloqueio movendo a leitura para uma transação só de leitura.
AVG_DISK_IO_COST FLOAT64

O custo médio desta consulta em termos de carregamento de disco do HDD do Spanner.

Use este valor para fazer comparações relativas de custos de E/S de HDD entre leituras que executa na base de dados. A consulta de dados no armazenamento de HDD incorre num custo relativo à capacidade de carregamento do disco HDD da instância. Um valor mais elevado indica que está a usar mais carga do disco rígido e que a sua consulta pode ser mais lenta do que se estivesse a ser executada num SSD. Além disso, se a carga do disco rígido estiver no limite da capacidade, o desempenho das suas consultas pode ser ainda mais afetado. Pode monitorizar o total da carga do disco rígido da instância como uma percentagem. Para adicionar mais capacidade de carga do disco rígido, pode adicionar mais unidades de processamento ou nós à sua instância. Para mais informações, consulte Altere a capacidade de computação. Para melhorar o desempenho das consultas, também pode considerar mover alguns dados para um SSD.

Para cargas de trabalho que consomem muitas E/S de disco, recomendamos que armazene dados acedidos com frequência no armazenamento SSD. Os dados acedidos a partir do SSD não consomem a capacidade de carga do disco rígido. Pode armazenar tabelas, colunas ou índices secundários seletivos no armazenamento SSD, conforme necessário, enquanto mantém os dados acedidos com pouca frequência no armazenamento HDD. Para mais informações, consulte o artigo Vista geral do armazenamento hierárquico.

Consultas de exemplo

Esta secção inclui vários exemplos de declarações SQL que obtêm estatísticas de leitura. Pode executar estas declarações SQL através das bibliotecas de cliente, do gcloud spanner ou da Google Cloud consola.

Indicar as estatísticas básicas de cada forma de leitura num determinado período

A seguinte consulta devolve os dados não processados das formas lidas principais nos intervalos de tempo de 1 minuto mais recentes.

SELECT fprint,
       read_columns,
       execution_count,
       avg_cpu_seconds,
       avg_rows,
       avg_bytes,
       avg_locking_delay_seconds,
       avg_client_wait_seconds
FROM spanner_sys.read_stats_top_minute
ORDER BY interval_end DESC LIMIT 3;
Resultado da consulta
fprint read_columns execution_count avg_cpu_seconds avg_rows avg_bytes avg_locking_delay_seconds avg_client_wait_seconds
125062082139 ["Singers.id", "Singers.name"] 8514387 0.000661355290396507 310.79 205 8.3232564943763752e-06 0
151238888745 ["Singers.singerinfo"] 3341542 6.5992827184280315e-05 12784 54 4.6859741349028595e-07 0
14105484 ["Albums.id", "Albums.title"] 9306619 0.00017855774721667873 1165.4 2964.71875 1.4328191393074178e-06 0

Apresente a lista das formas de leitura, ordenadas pela utilização total mais elevada da CPU

A consulta seguinte devolve as formas de leitura com a utilização da CPU mais elevada na hora mais recente:

SELECT read_columns,
       execution_count,
       avg_cpu_seconds,
       execution_count * avg_cpu_seconds AS total_cpu
FROM spanner_sys.read_stats_top_hour
WHERE interval_end =
  (SELECT MAX(interval_end)
   FROM spanner_sys.read_stats_top_hour)
ORDER BY total_cpu DESC LIMIT 3;
Resultado da consulta
read_columns execution_count avg_cpu_seconds total_cpu
["Singers.id", "Singers.name"] 1647 0.00023380297430622681 0.2579
["Albums.id", "Albums.title"] 720 0.00016738889440282034 0.221314999999999
["Singers.singerinfo""] 3223 0.00037764625882302246 0.188053

Estatísticas agregadas

SPANNER_SYS também contém tabelas para armazenar estatísticas de leitura agregadas captadas pelo Spanner num período específico:

  • SPANNER_SYS.READ_STATS_TOTAL_MINUTE: agregue estatísticas para todas as formas de leitura durante intervalos de 1 minuto.
  • SPANNER_SYS.READ_STATS_TOTAL_10MINUTE: agrega estatísticas para todas as formas de leitura durante intervalos de 10 minutos.
  • SPANNER_SYS.READ_STATS_TOTAL_HOUR: estatísticas agregadas para todas as formas lidas durante intervalos de 1 hora.

As tabelas de estatísticas agregadas têm as seguintes propriedades:

  • Cada tabela contém dados para intervalos de tempo não sobrepostos com a duração especificada no nome da tabela.

  • Os intervalos baseiam-se nas horas do relógio. Os intervalos de 1 minuto terminam no minuto, os intervalos de 10 minutos terminam a cada 10 minutos a partir da hora, e os intervalos de 1 hora terminam na hora.

    Por exemplo, às 11:59:30, os intervalos mais recentes disponíveis para consultas SQL sobre estatísticas de leitura agregadas são:

    • 1 minuto: 11:58:00–11:58:59
    • 10 minutos: 11:40:00–11:49:59
    • 1 hora: 10:00:00–10:59:59
  • Cada linha contém estatísticas de todas as formas de leitura executadas na base de dados durante o intervalo especificado, agregadas. Só existe uma linha por intervalo de tempo.

  • As estatísticas capturadas nas tabelas SPANNER_SYS.READ_STATS_TOTAL_* podem incluir formas de leitura que o Spanner não capturou nas tabelas SPANNER_SYS.READ_STATS_TOP_*.

  • Algumas colunas nestas tabelas são expostas como métricas no Cloud Monitoring. As métricas expostas são:

    • Contagem de linhas devolvidas
    • Ler contagem de execuções
    • Ler tempo da CPU
    • Atrasos no bloqueio
    • Tempo de espera do cliente
    • Atraso na atualização do líder
    • Contagem de bytes devolvidos

    Para mais informações, consulte o artigo Métricas do Spanner.

Esquema da tabela

Nome da coluna Tipo Descrição
INTERVAL_END TIMESTAMP Fim do intervalo de tempo em que as execuções de formas de leitura incluídas ocorreram.
EXECUTION_COUNT INT64 Número de vezes que o Spanner executou a forma de leitura durante o intervalo.
AVG_ROWS FLOAT64 Número médio de linhas devolvidas pelas leituras.
AVG_BYTES FLOAT64 O número médio de bytes de dados devolvidos pelas leituras, excluindo a sobrecarga de codificação de transmissão.
AVG_CPU_SECONDS FLOAT64 Número médio de segundos da CPU do lado do servidor do Spanner a executar a leitura, excluindo a CPU de obtenção prévia e outras sobrecargas.
AVG_LOCKING_DELAY_SECONDS FLOAT64 Número médio de segundos passados à espera devido ao bloqueio.
AVG_CLIENT_WAIT_SECONDS FLOAT64 Número médio de segundos passados à espera devido à limitação.
AVG_LEADER_REFRESH_DELAY_SECONDS FLOAT64 Número médio de segundos gastos na coordenação das leituras em instâncias nas configurações multirregionais.
RUN_IN_RW_TRANSACTION_EXECUTION_COUNT INT64 O número de vezes que as leituras foram executadas como parte de transações de leitura/escrita. Esta coluna ajuda a determinar se pode evitar contestações de bloqueio movendo algumas leituras para transações só de leitura.

Consultas de exemplo

Esta secção inclui vários exemplos de declarações SQL que obtêm estatísticas de leitura agregadas. Pode executar estas declarações SQL através das bibliotecas de cliente, do gcloud spanner ou da Google Cloud consola.

Encontre a utilização total da CPU em todas as formas de leitura

A seguinte consulta devolve o número de horas de CPU consumidas por formas de leitura na hora mais recente:

SELECT (avg_cpu_seconds * execution_count / 60 / 60)
  AS total_cpu_hours
FROM spanner_sys.read_stats_total_hour
WHERE interval_end =
  (SELECT MAX(interval_end)
   FROM spanner_sys.read_stats_total_hour);
Resultado da consulta
total_cpu_hours
0.00026186111111111115

Encontre a quantidade total de execuções num determinado período

A consulta seguinte devolve o número total de formas lidas executadas no intervalo de 1 minuto completo mais recente:

SELECT interval_end,
       execution_count
FROM spanner_sys.read_stats_total_minute
WHERE interval_end =
  (SELECT MAX(interval_end)
   FROM spanner_sys.read_stats_total_minute);
Resultado da consulta
interval_end execution_count
2020-05-28 11:02:00-07:00 12861966

Retenção de dados

No mínimo, o Spanner mantém os dados de cada tabela durante os seguintes períodos:

  • SPANNER_SYS.READ_STATS_TOP_MINUTE e SPANNER_SYS.READ_STATS_TOTAL_MINUTE: intervalos que abrangem as 6 horas anteriores.

  • SPANNER_SYS.READ_STATS_TOP_10MINUTE e SPANNER_SYS.READ_STATS_TOTAL_10MINUTE: intervalos que abrangem os 4 dias anteriores.

  • SPANNER_SYS.READ_STATS_TOP_HOUR e SPANNER_SYS.READ_STATS_TOTAL_HOUR: intervalos que abrangem os 30 dias anteriores.

Resolva problemas de utilização elevada da CPU com estatísticas de leitura

As estatísticas de leitura do Spanner são úteis nos casos em que precisa de investigar a elevada utilização da CPU na sua base de dados do Spanner ou quando está apenas a tentar compreender as formas de leitura com elevada utilização da CPU na sua base de dados. A inspeção de formas de leitura que usam quantidades significativas de recursos da base de dados oferece aos utilizadores do Spanner uma forma potencial de reduzir os custos operacionais e, possivelmente, melhorar as latências gerais do sistema. Nos passos seguintes, vamos mostrar-lhe como usar as estatísticas de leitura para investigar a utilização elevada da CPU na sua base de dados.

Selecione um período para investigar

Comece a sua investigação procurando uma altura em que a sua aplicação começou a ter uma utilização elevada da CPU. Por exemplo, no cenário seguinte, o problema começou a ocorrer por volta das 17:20 a 28 de maio de 2020.

Recolher estatísticas de leitura para o período selecionado

Depois de selecionar um período para iniciar a nossa investigação, vamos analisar as estatísticas recolhidas na tabela READ_STATS_TOTAL_10MINUTE nesse período. Os resultados desta consulta podem dar-nos pistas sobre como a CPU e outras estatísticas de leitura mudaram durante esse período. A seguinte consulta devolve as estatísticas de leitura agregadas de 4:30 pm a 7:30 pm (inclusive).

SELECT
  interval_end,
  ROUND(avg_cpu_seconds,4) as avg_cpu_seconds,
  execution_count,
  avg_locking_delay_seconds
FROM SPANNER_SYS.READ_STATS_TOTAL_10MINUTE
WHERE
  interval_end >= "2020-05-28T16:30:00"
  AND interval_end <= "2020-05-28T19:30:00"
ORDER BY interval_end;

Os seguintes dados são um exemplo do resultado que recebemos da nossa consulta.

interval_end avg_cpu_seconds execution_count avg_locking_delay_seconds
2020-05-28 16:40:00-07:00 0,0004 11111421 8.3232564943763752e-06
2020-05-28 16:50:00-07:00 0,0002 8815637 8,98734051776406e-05
2020-05-28 17:00:00-07:00 0,0001 8260215 6,039129247846453e-06
2020-05-28 17:10:00-07:00 0,0001 8514387 9,0535466616680686e-07
2020-05-28 17:20:00-07:00 0,0006 13715466 2.6801485272173765e-06
2020-05-28 17:30:00-07:00 0,0007 12861966 4.6859741349028595e-07
2020-05-28 17:40:00-07:00 0,0007 3755954 2.7131391918005383e-06
2020-05-28 17:50:00-07:00 0,0006 4248137 1.4328191393074178e-06
2020-05-28 18:00:00-07:00 0,0006 3986198 2.6973481999639748e-06
2020-05-28 18:10:00-07:00 0,0006 3510249 3.7577083563017905e-06
2020-05-28 18:20:00-07:00 0,0004 3341542 4,0940589703795433e-07
2020-05-28 18:30:00-07:00 0,0002 8695147 1,9914494947583975e-05
2020-05-28 18:40:00-07:00 0,0003 11679702 1,8331461539001595e-05
2020-05-28 18:50:00-07:00 0,0003 9306619 1,2527332321222135e-05
2020-05-28 19:00:00-07:00 0,0002 8520508 6,2268448078447915e-06
2020-05-28 19:10:00-07:00 0,0006 13715466 2.6801485272173765e-06
2020-05-28 19:20:00-07:00 0,0005 11947323 3.3029114639321295e-05
2020-05-28 19:30:00-07:00 0,0002 8514387 9,0535466616680686e-07

Aqui, vemos que o tempo médio da CPU, avg_cpu_seconds, é superior nos intervalos realçados. O interval_end com o valor 2020-05-28 19:20:00 tem um tempo de CPU mais elevado, por isso, vamos escolher esse intervalo para investigar mais detalhadamente no passo seguinte.

Descubra que formas de leitura estão a causar uma utilização elevada da CPU

Aprofundando um pouco mais, consultamos agora a tabela READ_STATS_TOP_10MINUTE para o intervalo que foi escolhido no passo anterior. Os resultados desta consulta podem ajudar a indicar que formas de leitura causam uma utilização elevada da CPU.

SELECT
  read_columns,
  ROUND(avg_cpu_seconds,4) as avg_cpu_seconds,
  execution_count,
  avg_rows
FROM SPANNER_SYS.READ_STATS_TOP_10MINUTE
WHERE
  interval_end = "2020-05-28T19:20:00"
ORDER BY avg_cpu_seconds DESC LIMIT 3;

Os seguintes dados são um exemplo do resultado que recebemos da nossa consulta, que devolve informações sobre as três principais formas de leitura classificadas por avg_cpu_seconds. Repare na utilização de ROUND na nossa consulta para restringir o resultado de avg_cpu_seconds a 4 casas decimais.

read_columns avg_cpu_seconds execution_count avg_rows
[TestHigherLatency._exists,TestHigherLatency.lang_status,TestHigherLatency.score,globalTagAffinity.shares]1 0,4192 1182 11650.42216582
[TestHigherLatency._exists,TestHigherLatency.lang_status,TestHigherLatency.likes,globalTagAffinity.score] 0,0852 4 12784
[TestHigherLatency._exists,TestHigherLatency.lang_status,TestHigherLatency.score,globalTagAffinity.ugcCount] 0,0697 1140 310.7921052631

1 _exists é um campo interno usado para verificar se existe ou não uma determinada linha.

Um dos motivos para a elevada utilização da CPU pode ser o facto de começar a executar algumas formas de leitura com maior frequência (execution_count). Talvez o número médio de linhas devolvidas pela leitura tenha aumentado (avg_rows). Se nenhuma dessas propriedades da forma de leitura revelar nada de interessante, pode examinar outras propriedades, como avg_locking_delay_seconds, avg_client_wait_seconds ou avg_bytes.

Aplique práticas recomendadas para reduzir a elevada utilização da CPU

Depois de seguir os passos anteriores, considere se a aplicação de alguma destas práticas recomendadas ajuda a resolver a sua situação.

  • O número de vezes que o Spanner executou formas de leitura durante o intervalo é um bom exemplo de uma métrica que precisa de uma base para lhe dizer se uma medição é razoável ou um sinal de um problema. Depois de estabelecer uma base para a métrica, pode detetar e investigar a causa de desvios inesperados do comportamento normal.

  • Se a utilização da CPU for relativamente constante na maioria das vezes, mas apresentar subitamente um pico que possa ser correlacionado com um pico repentino semelhante nos pedidos dos utilizadores ou no comportamento da aplicação, pode ser um indicador de que tudo está a funcionar como esperado.

  • Experimente a seguinte consulta para encontrar as formas de leitura mais lidas classificadas pelo número de vezes que o Spanner executou para cada forma de leitura:

    SELECT interval_end, read_columns, execution_count
    FROM SPANNER_SYS.READ_STATS_TOP_MINUTE
    ORDER BY execution_count DESC
    LIMIT 10;
    
  • Se procura as latências de leitura mais baixas possíveis, especialmente quando usa configurações de instâncias de várias regiões, use leituras desatualizadas em vez de leituras fortes para reduzir ou remover o componente AVG_LEADER_REFRESH_DELAY_SECONDS da latência de leitura.

  • Se estiver apenas a fazer leituras e puder expressar a sua leitura através de um método de leitura único, deve usar esse método de leitura único. As leituras únicas não bloqueiam, ao contrário das transações de leitura/escrita. Por isso, deve usar transações só de leitura em vez de transações de leitura/escrita mais caras quando não estiver a escrever dados.

O que se segue?