Statistiche sulle letture

Spanner fornisce tabelle integrate che memorizzano statistiche sulle letture. Puoi recuperare le statistiche da queste tabelle SPANNER_SYS.READ_STATS* utilizzando le istruzioni SQL.

Quando utilizzare le statistiche di lettura

Le statistiche di lettura forniscono informazioni su come un'applicazione utilizza il database e sono utili per esaminare i problemi di prestazioni. Ad esempio, puoi controllare quali forme di lettura vengono eseguite su un database, la frequenza con cui vengono eseguite e spiegare le caratteristiche di rendimento di queste forme di lettura. Puoi utilizzare le statistiche di lettura per il tuo database per identificare le forme di lettura che comportano un elevato utilizzo della CPU. A livello generale, le statistiche di lettura ti aiuteranno a comprendere il comportamento del traffico in entrata in un database in termini di utilizzo delle risorse.

Limitazioni

  • Questo strumento è ideale per analizzare stream di letture simili che rappresentano gran parte dell'utilizzo della CPU. Non è adatto per la ricerca di letture eseguite solo una volta.

  • L'utilizzo della CPU monitorato in queste statistiche rappresenta l'utilizzo della CPU lato server di Spanner, escluso l'utilizzo della CPU per il prefetch e alcuni altri overhead.

  • Le statistiche vengono raccolte secondo il criterio del "best effort". Di conseguenza, è possibile che alcune statistiche non vengano registrate se si verificano problemi con i sistemi di base. Ad esempio, se si verificano problemi di rete interna, è possibile che alcune statistiche non vengano registrate.

Disponibilità

I dati di SPANNER_SYS sono disponibili solo tramite interfacce SQL, ad esempio:

  • Pagina Spanner Studio di un database nella console Google Cloud

  • Il comando gcloud spanner databases execute-sql

  • L'API executeQuery

Gli altri metodi di lettura singola forniti da Spanner non supportanoSPANNER_SYS.

Utilizzo della CPU raggruppato per forma di lettura

Le tabelle seguenti monitorano le forme di lettura con il maggiore utilizzo della CPU durante un periodo di tempo specifico:

  • SPANNER_SYS.READ_STATS_TOP_MINUTE: leggi le statistiche sulle forme aggregate in intervalli di 1 minuto.
  • SPANNER_SYS.READ_STATS_TOP_10MINUTE: leggi le statistiche sulle forme aggregate su intervalli di 10 minuti.
  • SPANNER_SYS.READ_STATS_TOP_HOUR: leggi le statistiche sulle forme aggregate in intervalli di 1 ora.

Queste tabelle hanno le seguenti proprietà:

  • Ogni tabella contiene dati per intervalli di tempo non sovrapposti della durata specificata dal nome della tabella.

  • Gli intervalli si basano sull'ora dell'orologio. Gli intervalli di 1 minuto terminano al minuto, gli intervalli di 10 minuti terminano ogni 10 minuti a partire dall'ora e gli intervalli di 1 ora terminano all'ora. Dopo ogni intervallo, Spanner raccoglie i dati da tutti i server e li rende disponibili nelle tabelle SPANNER_SYS poco dopo.

    Ad esempio, alle 00:59:30, gli intervalli più recenti disponibili per le query SQL sono:

    • 1 minuto: dalle 00:58:00 alle 00:58:59
    • 10 minuti: 11:40:00-11:49:59
    • 1 ora: dalle 10:00:00 alle 10:59:59 AM
  • Spanner raggruppa le statistiche in base alla forma di lettura. Se è presente un tag, FPRINT è l'hash del tag. In caso contrario, è l'hash del valore READ_COLUMNS.

  • Ogni riga contiene le statistiche per tutte le esecuzioni di una determinata forma di lettura per la quale Spanner acquisisce le statistiche durante l'intervallo specificato.

  • Se Spanner non è in grado di memorizzare le informazioni su ogni forma di lettura distinta eseguita durante l'intervallo, il sistema dà la priorità alle forme di lettura con l'utilizzo della CPU più elevato durante l'intervallo specificato.

Schema tabella

Nome colonna Tipo Descrizione
INTERVAL_END TIMESTAMP Fine dell'intervallo di tempo in cui si sono verificate le esecuzioni di lettura incluse.
REQUEST_TAG STRING Il tag richiesta facoltativo per questa operazione di lettura. Per saperne di più sull'utilizzo dei tag, consulta Risoluzione dei problemi relativi ai tag di richiesta. Le statistiche relative a più letture che hanno la stessa stringa di tag sono raggruppate in un'unica riga con il valore "REQUEST_TAG" corrispondente a quella stringa di tag.
READ_TYPE STRING Indica se una lettura è PARTITIONED_READ o READ. Una lettura con un partitionToken ottenuto dall'API PartitionRead è rappresentata dal tipo di lettura PARTITIONED_READ e dalle altre API di lettura da READ.
READ_COLUMNS ARRAY<STRING> L'insieme di colonne lette. Sono in ordine alfabetico.
FPRINT INT64 L'hash del valore REQUEST_TAG, se presente; in caso contrario, l'hash del valore READ_COLUMNS.
EXECUTION_COUNT INT64 Numero di volte in cui Spanner ha eseguito la forma di lettura durante l'intervallo.
AVG_ROWS FLOAT64 Numero medio di righe restituite dalla lettura.
AVG_BYTES FLOAT64 Numero medio di byte di dati restituiti dalla lettura, escluso il sovraccarico della codifica di trasmissione.
AVG_CPU_SECONDS FLOAT64 Numero medio di secondi di CPU lato server Spanner per l'esecuzione della lettura, esclusa la CPU di prefetch e altri overhead.
AVG_LOCKING_DELAY_SECONDS FLOAT64 Numero medio di secondi di attesa a causa del blocco.
AVG_CLIENT_WAIT_SECONDS FLOAT64 Numero medio di secondi di attesa dovuti al fatto che il client non consuma i dati con la stessa velocità con cui Spanner potrebbe generarli.
AVG_LEADER_REFRESH_DELAY_SECONDS FLOAT64 Numero medio di secondi di attesa per confermare con il leader Paxos che tutte le scritture sono state osservate.
RUN_IN_RW_TRANSACTION_EXECUTION_COUNT INT64 Il numero di volte in cui la lettura è stata eseguita nell'ambito di una transazione di lettura-scrittura. Questa colonna ti aiuta a determinare se puoi evitare le contese per i blocchi spostando la lettura in una transazione di sola lettura.

Esempi di query

Questa sezione include diversi esempi di istruzioni SQL che recuperano le statistiche di lettura. Puoi eseguire queste istruzioni SQL utilizzando le librerie client, gcloud spanner o la console Google Cloud.

Elenca le statistiche di base per ogni forma di lettura in un determinato periodo di tempo

La seguente query restituisce i dati non elaborati per le forme di lettura principali negli intervalli di tempo di un minuto più recenti.

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;
Output della query
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

Elenca le forme lette, ordinate in base all'utilizzo totale della CPU più elevato

La seguente query restituisce le forme di lettura con il maggiore utilizzo della CPU nell'ora più 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;
Output della query
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

Statistiche aggregate

SPANNER_SYS contiene anche tabelle per memorizzare le statistiche di lettura aggregate acquisite da Spanner in un periodo di tempo specifico:

  • SPANNER_SYS.READ_STATS_TOTAL_MINUTE: statistiche aggregate per tutte le forme di lettura durante intervalli di 1 minuto.
  • SPANNER_SYS.READ_STATS_TOTAL_10MINUTE: statistiche aggregate per tutte le forme di lettura durante intervalli di 10 minuti.
  • SPANNER_SYS.READ_STATS_TOTAL_HOUR: statistiche aggregate per tutte le forme di lettura durante intervalli di 1 ora.

Le tabelle delle statistiche aggregate hanno le seguenti proprietà:

  • Ogni tabella contiene dati per intervalli di tempo non sovrapposti della durata specificata dal nome della tabella.

  • Gli intervalli si basano sull'ora dell'orologio. Gli intervalli di 1 minuto terminano al minuto, quelli di 10 minuti terminano ogni 10 minuti a partire dall'ora e quelli di 1 ora terminano all'ora.

    Ad esempio, alle 00:59:30, gli intervalli più recenti disponibili per le query SQL sulle statistiche di lettura aggregate sono:

    • 1 minuto: dalle 00:58:00 alle 00:58:59
    • 10 minuti: 11:40:00-11:49:59
    • 1 ora: dalle 10:00:00 alle 10:59:59 AM
  • Ogni riga contiene le statistiche relative a tutti gli schemi di lettura eseguiti sul database durante l'intervallo specificato, aggregate insieme. Esiste una sola riga per intervallo di tempo.

  • Le statistiche acquisite nelle tabelle SPANNER_SYS.READ_STATS_TOTAL_* potrebbero includere forme di lettura che Spanner non ha acquisito nelle tabelle SPANNER_SYS.READ_STATS_TOP_*.

  • Alcune colonne di queste tabelle sono esposte come metriche in Cloud Monitoring. Le metriche esposte sono:

    • Conteggio delle righe restituite
    • Conteggio esecuzioni lettura
    • Tempo di CPU di lettura
    • Ritardi nella chiusura
    • Tempo di attesa del cliente
    • Ritardo nell'aggiornamento del leader
    • Conteggio byte restituiti

    Per ulteriori informazioni, consulta Metriche di Spanner.

Schema tabella

Nome colonna Tipo Descrizione
INTERVAL_END TIMESTAMP Fine dell'intervallo di tempo in cui si sono verificate le esecuzioni della forma di lettura incluse.
EXECUTION_COUNT INT64 Numero di volte in cui Spanner ha eseguito la forma di lettura durante l'intervallo.
AVG_ROWS FLOAT64 Numero medio di righe restituite dalle letture.
AVG_BYTES FLOAT64 Numero medio di byte di dati restituiti dalle letture, escluso il sovraccarico della codifica di trasmissione.
AVG_CPU_SECONDS FLOAT64 Numero medio di secondi di CPU lato server Spanner per l'esecuzione della lettura, esclusa la CPU di prefetch e altri overhead.
AVG_LOCKING_DELAY_SECONDS FLOAT64 Numero medio di secondi di attesa a causa del blocco.
AVG_CLIENT_WAIT_SECONDS FLOAT64 Numero medio di secondi di attesa a causa del throttling.
AVG_LEADER_REFRESH_DELAY_SECONDS FLOAT64 Numero medio di secondi impiegati per coordinare le letture tra le istanze nelle configurazioni multiregionali.
RUN_IN_RW_TRANSACTION_EXECUTION_COUNT INT64 Il numero di volte in cui le letture sono state eseguite nell'ambito di transazioni di lettura/scrittura. Questa colonna ti aiuta a determinare se puoi evitare le contese sui blocchi spostando alcune letture in transazioni di sola lettura.

Esempi di query

Questa sezione include diversi esempi di istruzioni SQL che recuperano le statistiche di lettura aggregate. Puoi eseguire queste istruzioni SQL utilizzando le librerie client, gcloud spanner o la console Google Cloud.

Trovare l'utilizzo totale della CPU in tutti i shape di lettura

La seguente query restituisce il numero di ore CPU consumate dalle forme di lettura nell'ora più 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);
Output della query
total_cpu_hours
0.00026186111111111115

Trovare il conteggio totale delle esecuzioni in un determinato periodo di tempo

La seguente query restituisce il numero totale di forme di lettura eseguite nell'intervallo di 1 minuto completo più 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);
Output della query
interval_end execution_count
2020-05-28 11:02:00-07:00 12861966

Conservazione dei dati

Come minimo, Spanner conserva i dati per ogni tabella per i seguenti periodi di tempo:

  • SPANNER_SYS.READ_STATS_TOP_MINUTE e SPANNER_SYS.READ_STATS_TOTAL_MINUTE: intervalli che coprono le 6 ore precedenti.

  • SPANNER_SYS.READ_STATS_TOP_10MINUTE e SPANNER_SYS.READ_STATS_TOTAL_10MINUTE: intervalli che coprono i 4 giorni precedenti.

  • SPANNER_SYS.READ_STATS_TOP_HOUR e SPANNER_SYS.READ_STATS_TOTAL_HOUR: intervalli che coprono i 30 giorni precedenti.

Risolvere i problemi di utilizzo elevato della CPU con le statistiche di lettura

Le statistiche di lettura di Spanner sono utili nei casi in cui è necessario esaminare un utilizzo elevato della CPU nel database Spanner o quando si sta semplicemente cercando di comprendere le forme di lettura che richiedono molta CPU nel database. L'ispezione delle forme di lettura che utilizzano quantità significative di risorse di database offre agli utenti di Spanner un potenziale modo per ridurre i costi operativi e possibilmente migliorare le latenze generali del sistema. Con i passaggi che seguono, ti mostreremo come utilizzare le statistiche di lettura per esaminare l'utilizzo elevato della CPU nel tuo database.

Seleziona un periodo di tempo da esaminare

Inizia la tua indagine cercando un momento in cui l'applicazione ha iniziato a registrare un utilizzo elevato della CPU. Ad esempio, nel seguente scenario, il problema ha iniziato a verificarsi intorno alle 17:20 del 28 maggio 2020.

Raccogliere le statistiche di lettura per il periodo di tempo selezionato

Dopo aver selezionato un periodo di tempo per iniziare la nostra indagine, esamineremo le statistiche raccolte nella tabella READ_STATS_TOTAL_10MINUTE in quel periodo. I risultati di questa query potrebbero fornirci indizi su come la CPU e altre statistiche di lettura sono cambiate in quel periodo di tempo. La seguente query restituisce le statistiche di lettura aggregate dal giorno 4:30 pm al giorno 7:30 pm (inclusi).

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;

I seguenti dati sono un esempio del risultato restituito dalla nostra query.

interval_end avg_cpu_seconds execution_count avg_locking_delay_seconds
28-05-2020 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
28-05-2020 17:20:00-07:00 0,0006 13715466 2.6801485272173765e-06
28-05-2020 17:30:00-07:00 0,0007 12861966 4.6859741349028595e-07
28-05-2020 17:40:00-07:00 0,0007 3755954 2.7131391918005383e-06
28-05-2020 17:50:00-07:00 0,0006 4248137 1.4328191393074178e-06
28-05-2020 18:00:00-07:00 0,0006 3986198 2.6973481999639748e-06
28-05-2020 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
28-05-2020 19:10:00-07:00 0,0006 13715466 2.6801485272173765e-06
28-05-2020 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

Qui vediamo che il tempo di CPU medio, avg_cpu_seconds, è più elevato negli intervalli evidenziati. Il valore interval_end con valore 2020-05-28 19:20:00 ha un tempo CPU più elevato, quindi sceglieremo questo intervallo per approfondire nel passaggio successivo.

Trovare le forme di lettura che causano un elevato utilizzo della CPU

Per approfondire, ora eseguiamo una query sulla tabella READ_STATS_TOP_10MINUTE per recuperare l'intervallo selezionato nel passaggio precedente. I risultati di questa query possono indicare quali forme di lettura causano un utilizzo elevato della 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;

I seguenti dati sono un esempio del risultato restituito dalla nostra query, che fornisce informazioni sulle tre forme di lettura principali classificate in base a avg_cpu_seconds. Tieni presente l'utilizzo di ROUND nella nostra query per limitare l'output di avg_cpu_seconds a 4 cifre decimali.

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 è un campo interno utilizzato per verificare se una determinata riga esiste o meno.

Un motivo dell'utilizzo elevato della CPU potrebbe essere che inizi a eseguire alcune forme di lettura più di frequente (execution_count). Forse il numero medio di righe che la lettura ha restituito è aumentato (avg_rows). Se nessuna di queste proprietà della forma di lettura rivela nulla di interessante, puoi esaminare altre proprietà come avg_locking_delay_seconds, avg_client_wait_seconds o avg_bytes.

Applica le best practice per ridurre l'utilizzo elevato della CPU

Dopo aver completato i passaggi precedenti, valuta se l'applicazione di una di queste best practice può aiutarti a risolvere il problema.

  • Il numero di volte in cui Spanner ha eseguito forme di lettura durante l'intervallo è un buon esempio di metrica che richiede una baseline per indicare se una misurazione è ragionevole o indica un problema. Dopo aver stabilito una base di riferimento per la metrica, potrai rilevare e analizzare la causa di eventuali deviazioni impreviste dal comportamento normale.

  • Se l'utilizzo della CPU è relativamente costante per la maggior parte del tempo, ma mostra improvvisamente un picco che può essere correlato a un picco improvviso simile nelle richieste degli utenti o nel comportamento dell'applicazione, potrebbe indicare che tutto funziona come previsto.

  • Prova la seguente query per trovare le principali forme di lettura classificate in base al numero di volte in cui Spanner è stato eseguito per ogni forma di lettura:

    SELECT interval_end, read_columns, execution_count
    FROM SPANNER_SYS.READ_STATS_TOP_MINUTE
    ORDER BY execution_count DESC
    LIMIT 10;
    
  • Se cerchi le latenze di lettura più basse possibili, in particolare quando utilizzi configurazioni di istanze multiregione, utilizza le letture non aggiornate anziché le letture sicure per ridurre o rimuovere il componente AVG_LEADER_REFRESH_DELAY_SECONDS della latenza di lettura.

  • Se esegui solo letture e puoi esprimerle utilizzando un metodo di lettura singola, devi utilizzare questo metodo. Le letture singole non vengono bloccate, a differenza delle transazioni di lettura/scrittura, pertanto devi utilizzare le transazioni di sola lettura anziché le transazioni di lettura/scrittura più costose quando non scrivi dati.

Passaggi successivi