Ler estatísticas

O Cloud Spanner fornece tabelas integradas que armazenam estatísticas sobre leituras. É possível recuperar estatísticas dessas tabelas SPANNER_SYS.READ_STATS* usando instruções SQL.

Quando usar as estatísticas de leitura

As estatísticas de leitura fornecem insights sobre como um aplicativo está usando o banco de dados e são úteis para investigar problemas de desempenho. Por exemplo, é possível verificar quais formas de leitura estão sendo executadas em um banco de dados, a frequência com que são executadas e explicar as características de desempenho dessas formas de leitura. Use as estatísticas de leitura do banco de dados para identificar formas de leitura que resultam em alto uso da CPU. Em um nível elevado, as estatísticas de leitura ajudarão você a entender o comportamento do tráfego que entra em um banco de dados em termos de uso de recursos.

Limitações

  • Essa ferramenta é mais adequada para analisar streams de leituras semelhantes que representam a maior parte do uso da CPU. Não é bom para procurar leituras que foram executadas apenas uma vez.

  • O uso da CPU rastreado nessas estatísticas representa o uso de CPU do lado do servidor do Spanner, excluindo o uso de CPU de pré-busca e algumas outras sobrecargas.

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

Disponibilidade

Os dados do SPANNER_SYS estão disponíveis somente por meio de interfaces SQL. Por exemplo:

  • Página do Spanner Studio de um banco de dados no console do Google Cloud

  • O comando gcloud spanner databases execute-sql

  • A API executeQuery

Outros métodos de leitura única fornecidos pelo Spanner não são compatíveis com SPANNER_SYS.

Uso de CPU agrupado por forma de leitura

As tabelas a seguir rastreiam as formas de leitura com o maior uso de CPU durante um período específico:

  • SPANNER_SYS.READ_STATS_TOP_MINUTE: lê estatísticas de forma agregadas em intervalos de 1 minuto.
  • SPANNER_SYS.READ_STATS_TOP_10MINUTE: lê estatísticas de forma agregadas em intervalos de 10 minuto.
  • SPANNER_SYS.READ_STATS_TOP_HOUR: lê estatísticas de forma agregadas em intervalos de 1 hora.

Essas tabelas têm as seguintes propriedades:

  • Cada uma contém dados para intervalos de tempo não sobrepostos do comprimento que o nome da tabela específica.

  • Os intervalos são baseados em horas. Os intervalos de 1 minuto terminam no minuto, os de 10 minutos terminam a cada 10 minutos, começando na hora, e os intervalos de 1 hora terminam na hora. Após cada intervalo, o Spanner coleta dados de todos os servidores e os disponibiliza nas tabelas SPANNER_SYS logo depois.

    Por exemplo, às 11:59:30, os intervalos mais recentes disponíveis para as 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 formato de leitura. Se houver uma tag, F referentes será o hash dela. Caso contrário, será o hash do valor de READ_COLUMNS.

  • Cada linha contém estatísticas para todas as execuções de uma forma de leitura específica para a qual o Spanner captura estatísticas durante o intervalo especificado.

  • Se o Spanner não conseguir armazenar informações sobre cada execução de forma de leitura distinta durante o intervalo, o sistema priorizará as formas de leitura com o maior uso de CPU durante o intervalo especificado.

Esquema de tabela

Nome da coluna Tipo Descrição
INTERVAL_END TIMESTAMP Fim do intervalo de tempo em que as execuções de leitura incluídas ocorreram.
REQUEST_TAG STRING A tag de solicitação opcional para essa operação de leitura. Para mais informações sobre como usar tags, consulte Solução de problemas com tags de solicitação. As estatísticas de várias leituras com a mesma string de tags são agrupadas em uma única linha com "REQUEST_TAG" correspondente a essa string de tag.
READ_TYPE STRING Indica se uma leitura é PARTITIONED_READ ou READ. Uma leitura com um partitionToken recebido da API OverlayRead é representada pelo tipo de leitura PARTITIONED_READ e as outras APIs de leitura por READ.
READ_COLUMNS ARRAY<STRING> O conjunto de colunas que foram lidas. Elas estão em ordem alfabética.
FPRINT INT64 O hash do valor REQUEST_TAG, se 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 que a leitura retornou.
AVG_BYTES FLOAT64 Número médio de bytes de dados que a leitura retornou, 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 executando a leitura, excluindo a CPU de pré-busca e outras sobrecargas.
AVG_LOCKING_DELAY_SECONDS FLOAT64 Número médio de segundos gastos em espera devido ao bloqueio.
AVG_CLIENT_WAIT_SECONDS FLOAT64 Número médio de segundos gastos na espera porque o cliente não consumiu dados tão rápido quanto o Spanner poderia gerá-los.
AVG_LEADER_REFRESH_DELAY_SECONDS FLOAT64 Número médio de segundos gastos esperando a confirmação com o líder do Paxos que todas as gravações 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/gravação. Esta coluna ajuda a determinar se você pode evitar contenções de bloqueio movendo a leitura para uma transação somente leitura.

Exemplo de consultas

Nesta seção, há várias instruções SQL de exemplo que recuperam estatísticas de leitura. É possível executar essas instruções SQL usando as bibliotecas de cliente, a ferramenta de linha de comando gcloud ou o console do Google Cloud.

Listar as estatísticas básicas de cada forma de leitura em um determinado período

Com a consulta a seguir, você retorna os dados brutos para as principais formas de leitura 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;
Saída 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

Listar as formas de leitura pedidas pelo maior uso total da CPU

Com a consulta a seguir, você retorna as formas de leitura com o uso mais alto da CPU 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;
Saída 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

Agregar estatísticas

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

  • SPANNER_SYS.READ_STATS_TOTAL_MINUTE: agregar estatísticas de todas as formas de leitura durante intervalos de 1 minuto.
  • SPANNER_SYS.READ_STATS_TOTAL_10MINUTE: agregar estatísticas de todas as formas de leitura durante intervalos de 10 minutos.
  • SPANNER_SYS.READ_STATS_TOTAL_HOUR: agregar estatísticas de todas as formas de leitura durante intervalos de 1 hora.

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

  • Cada uma contém dados para intervalos de tempo não sobrepostos do comprimento que o nome da tabela específica.

  • Os intervalos são baseados em horas. Os intervalos de 1 minuto terminam no minuto, os de 10 minutos terminam a cada 10 minutos, começando na hora, e os intervalos de 1 hora terminam na hora.

    Por exemplo, às 11h59m30s, os intervalos mais recentes disponíveis para consultas SQL em 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 para todas as formas de leitura executadas no banco de dados durante o intervalo especificado, agregadas juntas. Há apenas 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 retornadas
    • Ler contagem de execução
    • Ler tempo de CPU
    • Atrasos de bloqueio
    • Tempo de espera do cliente
    • Atraso na atualização do líder
    • Contagem de bytes retornados

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

Esquema de 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 que as leituras retornaram.
AVG_BYTES FLOAT64 Número médio de bytes de dados que as leituras retornaram, 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 executando a leitura, excluindo a CPU de pré-busca e outras sobrecargas.
AVG_LOCKING_DELAY_SECONDS FLOAT64 Número médio de segundos gastos em espera devido ao bloqueio.
AVG_CLIENT_WAIT_SECONDS FLOAT64 Número médio de segundos gastos em espera devido à limitação.
AVG_LEADER_REFRESH_DELAY_SECONDS FLOAT64 Número médio de segundos gastos coordenando as leituras em instâncias em 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/gravação. Esta coluna ajuda a determinar se você pode evitar contenções de bloqueio movendo algumas leituras para transações somente leitura.

Exemplo de consultas

Nesta seção, há várias instruções SQL de exemplo que recuperam estatísticas de leitura agregadas. É possível executar essas instruções SQL usando as bibliotecas de cliente, a ferramenta de linha de comando gcloud ou o console do Google Cloud.

Encontrar o uso total da CPU em todas as formas de leitura

A consulta a seguir retorna 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);
Saída da consulta
total_cpu_hours
0.00026186111111111115

Encontrar a contagem total de execuções em um determinado período

A consulta a seguir retorna o número total de formas de leitura executadas no intervalo completo de 1 minuto 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);
Saída da consulta
interval_end execution_count
2020-05-28 11:02:00-07:00 12861966

Retenção de dados

O Spanner mantém dados de cada tabela, no mínimo, para os períodos a seguir:

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

  • SPANNER_SYS.READ_STATS_TOP_10MINUTE e SPANNER_SYS.READ_STATS_TOTAL_10MINUTE: intervalos abrangendo os quatro dias anteriores.

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

Resolver problemas de alto uso da CPU com estatísticas de leitura

As estatísticas de leitura do Spanner são úteis nos casos em que você precisa investigar o alto uso da CPU no banco de dados do Spanner ou quando está apenas tentando entender as formas de leitura com uso intenso da CPU no banco de dados. A inspeção de formas de leitura que usam quantidades significativas de recursos de banco de dados oferece aos usuários do Spanner uma possível maneira de reduzir os custos operacionais e melhorar as latências gerais do sistema. Nas etapas a seguir, mostraremos como usar estatísticas de leitura para investigar o alto uso da CPU no banco de dados.

Selecione um período para a investigação

Inicie a investigação procurando um horário em que o aplicativo começou a apresentar uso elevado da CPU. Por exemplo, no cenário a seguir, o problema começou a ocorrer por volta das 17h20 do dia 28 de maio de 2020.

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

Depois de selecionar um período para iniciar nossa investigação, analisaremos as estatísticas coletadas na tabela READ_STATS_TOTAL_10MINUTE desse período. Os resultados dessa consulta podem dar pistas sobre como a CPU e outras estatísticas de leitura mudaram nesse período. A consulta a seguir retorna 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 dados a seguir são um exemplo do resultado que obtemos 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

Observe que o tempo médio da CPU, avg_cpu_seconds, é maior nos intervalos destacados. O interval_end com o valor 2020-05-28 19:20:00 tem um tempo de CPU maior. Por isso, escolhemos esse intervalo para investigar mais na próxima etapa.

Descobrir quais formas de leitura estão causando alto uso da CPU

Ao se aprofundar mais, consultamos a tabela READ_STATS_TOP_10MINUTE sobre o intervalo escolhido na etapa anterior. Os resultados dessa consulta podem ajudar a indicar quais formas de leitura causam alto uso 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 dados a seguir são um exemplo do resultado que recebemos da nossa consulta, retornando informações sobre as três principais formas de leitura classificadas por avg_cpu_seconds. Observe o uso de ROUND em nossa consulta para restringir a saída 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 uma determinada linha existe ou não.

Um motivo para o alto uso da CPU pode ser que você comece a executar algumas formas de leitura com mais frequência (execution_count). Talvez o número médio de linhas que a leitura retornou aumentou (avg_rows). Se nenhuma dessas propriedades da forma de leitura revelar algo interessante, você poderá examinar outras propriedades como avg_locking_delay_seconds, avg_client_wait_seconds ou avg_bytes.

Aplicar as práticas recomendadas para reduzir o uso elevado da CPU

Depois de concluir as etapas anteriores, pense se fornecer alguma destas práticas recomendadas ajudará sua situação.

  • O número de vezes que o Spanner executou formas lidas durante o intervalo é um bom exemplo de métrica que precisa de um valor de referência para informar se uma medição é razoável ou um sinal de problema. Após estabelecer uma linha de base para a métrica, será possível detectar e investigar a causa de um desvio inesperado de comportamento normal.

  • Se o uso da CPU for relativamente constante na maioria das vezes, mas repentinamente mostrar um pico que possa ser correlacionado com um pico repentino semelhante nas solicitações de usuários ou no comportamento do aplicativo, pode ser uma indicação de que tudo está funcionando como esperado.

  • Tente a consulta a seguir para encontrar as principais formas de leitura classificadas pelo número de vezes que o Spanner é executado 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 você estiver procurando as menores latências de leitura possíveis, especialmente ao usar configurações de instâncias multirregionais, 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 você está apenas fazendo leituras e pode expressá-las usando um método de leitura única, use esse método. Leituras únicas não são bloqueadas, ao contrário das transações de leitura/gravação. Portanto, use transações somente leitura em vez de transações de leitura/gravação mais caras quando não estiver gravando dados.

A seguir