Einführung in Query Insights for Cloud SQL

1. Hinweis

Mit Query Insights für Cloud SQL können Sie Probleme bei der Abfrageleistung in Cloud SQL-Datenbanken ermitteln, diagnostizieren und verhindern. Es bietet intuitives Self-Service-Monitoring sowie Diagnoseinformationen, die über die Erkennung hinausgehen, sodass Sie die Ursache von Leistungsproblemen ermitteln können.

In diesem Codelab erfahren Sie, wie Sie eine Cloud SQL for PostgreSQL-Instanz einrichten, eine Node.js-App bereitstellen, die die Cloud SQL-Instanz als Back-End-Speicher verwendet, und dann Query Insights verwenden, um Abfragen anzusehen und zu überwachen.

Voraussetzungen

  • Grundkenntnisse der Programmiersprache und der Tools von Node.js

Aufgaben

  • Cloud SQL in einer Node.js-App verwenden
  • SQL Commenter in einer Node.js-Anwendung aktivieren
  • Mit Query Insights für Cloud SQL können Sie die Abfrageleistung im Blick behalten und untersuchen.

Voraussetzungen

  • Ein Google Cloud-Konto, in dem Sie Berechtigungen zum Aktivieren von APIs und zum Erstellen von Diensten haben

2. Einrichtung und Anforderungen

Umgebung zum selbstbestimmten Lernen einrichten

  1. Melden Sie sich in der Cloud Console an und erstellen Sie ein neues Projekt oder verwenden Sie ein vorhandenes Projekt. Wenn Sie noch kein Gmail- oder Google Workspace-Konto haben, müssen Sie eines erstellen.

Merken Sie sich die Projekt-ID des Projekts, das Sie verwenden. Sie wird später in diesem Codelab als PROJECT-ID bezeichnet.

  1. Als Nächstes müssen Sie die Abrechnung in der Cloud Console aktivieren, um Google Cloud-Ressourcen verwenden zu können.

Die Durchführung dieses Codelabs sollte keine oder nur geringe Kosten verursachen. Folgen Sie unbedingt der Anleitung im Abschnitt „Bereinigen und weitere Informationen“, in der Sie erfahren, wie Sie Ressourcen herunterfahren können, damit nach Abschluss dieser Anleitung keine Gebühren anfallen. Neue Nutzer von Google Cloud kommen für das Programm für den kostenlosen Testzeitraum mit einem Guthaben von 300$ infrage.

Cloud Shell aktivieren

  1. Klicken Sie in der Cloud Console auf Cloud Shell aktivieren:

Cloud Shell aktivieren

Wenn Sie Cloud Shell noch nie gestartet haben, wird ein Fenster mit einer Beschreibung eingeblendet. Klicken Sie in diesem Fall einfach auf Weiter. So sieht dieses Fenster aus:

Cloud Shell-Dialogfenster

Das Herstellen der Verbindung mit der Cloud Shell sollte nur wenige Augenblicke dauern.

Cloud Shell-Terminal

Diese virtuelle Maschine verfügt über sämtliche Entwicklertools, die Sie benötigen. Sie bietet ein Basisverzeichnis mit 5 GB nichtflüchtigem Speicher und läuft in Google Cloud, was die Netzwerkleistung und Authentifizierung erheblich verbessert.

  1. Führen Sie in Cloud Shell den folgenden Befehl aus, um zu bestätigen, dass Sie das richtige Projekt verwenden:

Sobald die Verbindung mit der Cloud Shell hergestellt ist, sehen Sie, dass Sie bereits authentifiziert sind und für das Projekt schon Ihre Projekt-ID eingestellt ist.

Führen Sie den folgenden Befehl aus, um zu bestätigen, dass Sie das richtige Projekt verwenden.

gcloud config list project

Wenn Sie ein anderes Projekt als das verwenden möchten, das beim Öffnen von Cloud Shell ausgewählt war, können Sie ein neues Projekt festlegen, indem Sie Folgendes ausführen:

gcloud config set project <PROJECT-ID>;

3. Cloud SQL for PostgreSQL-Instanz mit aktiviertem Query Insights einrichten

  1. Nachdem Cloud Shell gestartet wurde, können Sie über die Befehlszeile eine neue Cloud SQL-Instanz mit dem Namen my-instance erstellen, für die Query Insights aktiviert ist:
gcloud sql instances create my-instance --tier db-f1-micro --database-version=POSTGRES_12 --region=us-central --root-password=<PASSWORD> --insights-config-query-insights-enabled --insights-config-record-application-tags --insights-config-record-client-address

Hier eine kurze Erklärung der Flags und ihrer Bedeutung:

  • Mit dem Flag --tier db-f1-micro wird ein Maschinentyp mit minimalen Ressourcen angegeben, da dies für Entwicklungszwecke geschieht und Sie für das Codelab nicht viele Ressourcen benötigen. Weitere Informationen zu Stufen
  • Mit dem Flag --database-version=POSTGRES_12 wird eine Instanz mit PostgreSQL-Version 12 erstellt.
  • Mit dem Flag --region=us-central wird die Region angegeben, in der die Instanz erstellt wird.
  • Mit dem Flag --root-password=<PASSWORD> können Sie das Passwort für den Root-Nutzer postgres angeben. Ersetzen Sie <PASSWORD> durch ein Passwort Ihrer Wahl.
  • Das Flag --insights-config-query-insights-enabled aktiviert Query Insights für Ihre Instanz.
  • Mit dem Flag --insights-config-record-application-tags können Anwendungstags aufgezeichnet werden. Weitere Informationen zu Anwendungs-Tags finden Sie in späteren Abschnitten.
  • Mit dem Flag --insights-config-record-client-address können Client-IP-Adressen von Query Insights aufgezeichnet werden.

Möglicherweise werden Sie aufgefordert, die API sqladmin.googleapis.com für Ihr Projekt zu aktivieren. Wenn Sie dazu aufgefordert werden, wählen Sie y aus, um die API zu aktivieren.

Das Erstellen der Instanz dauert einige Minuten. Nach Abschluss dieses Vorgangs ist Ihre Instanz einsatzbereit.

  1. Erstellen Sie nun eine Datenbank, die Sie für die Beispiel-App verwenden:
gcloud sql databases create votesdb --instance my-instance

Sie können auch über die Cloud Console auf die Instanz zugreifen und sie konfigurieren.

  1. Rufen Sie den Namen der Instanzverbindung im Format PROJECT-ID:ZONE-ID:INSTANCE-ID mit dem folgenden Befehl ab. Sie verwenden sie später bei der Konfiguration Ihrer Node.js-App.
gcloud sql instances describe my-instance | grep connectionName

4. Dienstkonto für die App erstellen

Mit Dienstkonten werden Berechtigungen für die Verwendung verschiedener Dienste in Ihrem GCP-Projekt erteilt. Für dieses Codelab benötigen Sie eine, um dem Cloud SQL-Proxy die Berechtigung zum Herstellen einer Verbindung zu Ihrer Cloud SQL-Instanz zu erteilen.

Dienstkonto in der Console erstellen

  1. Rufen Sie die Seite „IAM-Dienstkonten“ auf und klicken Sie oben auf der Seite auf die Schaltfläche -PCvKR3aQ2zKaUcml8w9lW4JNlmYtN5-r2--mC6kMUp6HOXW8wT1wUvLoYEPU-aA-oGskT3XkAqfNwRAKkZkllwTe6ugdrUVFwaeKT0M9Y1RwHA8JPZeGmCWYBfr8d9TSycNMIRsLw.
  2. Geben Sie Ihrem Dienstkonto einen eindeutigen Namen und eine eindeutige ID und klicken Sie auf ERSTELLEN.
  3. Klicken Sie auf der nächsten Seite auf das Drop-down-Menü „Rolle auswählen“. Filtern Sie nach „Cloud SQL“ und wählen Sie die Rolle „Cloud SQL-Client“ aus. Klicken Sie auf WEITER und dann auf FERTIG.
  4. Klicken Sie nach dem Erstellen des Dienstkontos unter Aktionen für das neue Dienstkonto auf das Dreipunkt-Menü und wählen Sie „Schlüssel verwalten“ aus. Wählen Sie auf der nächsten Seite SCHLÜSSEL HINZUFÜGEN und dann Neuen Schlüssel erstellen aus. JSON ist ausgewählt. Behalten Sie diese Standardeinstellung bei und klicken Sie auf ERSTELLEN. Dadurch wird eine JSON-Datei mit dem privaten Schlüssel heruntergeladen. Klicken Sie auf SCHLIESSEN.
  5. Klicken Sie in Cloud Shell auf das Dreipunkt-Menü Mehr und wählen Sie Datei hochladen aus. Suchen Sie auf Ihrem lokalen Computer nach der heruntergeladenen JSON-Datei und wählen Sie sie aus. Dadurch wird die JSON-Datei in Ihr Basisverzeichnis in Cloud Shell hochgeladen.

5. Cloud SQL-Proxy installieren und starten

Sie verwenden den Cloud SQL-Proxy für die Kommunikation zwischen der Anwendung und der Datenbankinstanz.

  1. Laden Sie den Cloud SQL-Proxy herunter. In Cloud Shell können Sie Folgendes ausführen:
wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy && chmod +x cloud_sql_proxy
  1. Führen Sie den Proxy so aus, nachdem Sie <INSTANCE_CONNECTION_NAME> durch den Namen der Instanzverbindung ersetzt haben, den Sie auf der Seite „Übersicht“ der Cloud SQL-Instanz kopiert haben.
./cloud_sql_proxy -instances=<INSTANCE_CONNECTION_NAME>=tcp:5432 &

Wenn der Vorgang erfolgreich war, sollten einige Zeilen mit Ausgabe angezeigt werden, die mit der Meldung Ready for new connections enden.

6. App lokal klonen und testen

  1. Klonen Sie das Repository für die Beispielanwendung und installieren Sie die zum Ausführen der App erforderlichen Pakete.
git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples/

cd nodejs-docs-samples/cloud-sql/postgres/knex

npm install
  1. Legen Sie die folgenden Umgebungsvariablen fest:
export INSTANCE_CONNECTION_NAME='<PROJECT-ID>:<ZONE-ID>:<INSTANCE-ID>'
export DB_HOST='127.0.0.1:5432'
export DB_USER='postgres'
export DB_PASS='<PASSWORD>'
export DB_NAME='votesdb'
  1. Starten Sie die Beispiel-App.
npm start
  1. Klicken Sie in Cloud Shell auf WebvorschauSymbol für Webvorschau und wählen Sie dann Vorschau auf Port 8080 aus.

Menüpunkt „Vorschau auf Port 8080“

Die Abstimmungs-App „Tabs vs Spaces“ sollte in Ihrem Browser wie hier dargestellt angezeigt werden:

Screenshot der Abstimmungs-App mit Tabs und Bereichen

  1. Klicken Sie auf die Schaltflächen, um einige Stimmen abzugeben und Daten in der Datenbank zu speichern.

7. Seite zum Anzeigen aller Abstimmungen hinzufügen

Da diese Beispielanwendung sehr einfach ist, fügen Sie eine zusätzliche Seite hinzu, auf der alle Stimmen angezeigt werden. Der Hauptgrund dafür ist, dass Sie später mehr Daten zur Verfügung haben, wenn Sie Query Insights verwenden.

  1. Geben Sie in Cloud Shell Ctrl+c ein, um die Beispielanwendung zu beenden.
  2. Klicken Sie in Cloud Shell auf die Schaltfläche Schaltfläche „Editor öffnen“, um den Cloud Shell-Editor zu starten.
  3. Suchen Sie im Datei-Explorer nach nodejs-docs-samples/cloud-sql/postgres/knex/server.js und klicken Sie darauf, um die Datei server.js im Editor zu laden.

Fügen Sie den folgenden Code nach der Definition der Funktion getVotes ein:

/**
 * Retrieve all vote records from the database.
 *
 * @param {object} pool The Knex connection object.
 * @returns {Promise}
 */
const getAllVotes = async pool => {
  return await pool
    .select('candidate', 'time_cast')
    .from('votes')
    .orderBy('time_cast', 'desc');
};
  1. Fügen Sie den folgenden Code für die '/getAllVotes'-Route unterhalb der Definitionen der anderen Routen ein:
app.get('/getAllVotes', async (req, res) => {
  pool = pool || createPool();
  try {
    // Query all votes from the database.
    const votes = await getAllVotes(pool);

    res.render('allvotes.pug', {
      votes: votes,
    });
  } catch (err) {
    console.error(err);
    res
      .status(500)
      .send('Unable to load page; see logs for more details.')
      .end();
  }
});
  1. Erstellen Sie im Verzeichnis nodejs-docs-samples/cloud-sql/postgres/knex/views eine neue Datei mit dem Namen allvotes.pug. Fügen Sie den folgenden Code ein:
doctype html
html(lang="en")
  head
    title Tabs VS Spaces

    link(rel="stylesheet", href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css")
    link(rel="stylesheet", href="https://fonts.googleapis.com/icon?family=Material+Icons")
    script(src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js")
  body

    nav(class="red lighten-1")
      div(class="nav-wrapper")
        a(href="#" class="brand-logo center") Tabs VS Spaces

    div(class="section")

      h4(class="header center") Recent Votes
      ul(class="container collection center")
        each vote in votes
          li(class="collection-item avatar")
            if vote.candidate.trim() === 'TABS'
              i(class="material-icons circle green") keyboard_tab
            else
              i(class="material-icons circle blue") space_bar
            span(class="title") A vote for <b>#{vote.candidate}</b>
            p was cast at #{vote.time_cast}.
  1. Klicken Sie auf die Schaltfläche Schaltfläche „Terminal öffnen“, um zu Cloud Shell zurückzukehren und Folgendes auszuführen:
npm start
  1. Öffnen Sie die App über die Webvorschau, um zu prüfen, ob sie funktioniert. Fügen Sie der URL im Browser /getAllVotes hinzu, um die neue Seite aufzurufen.

8. SQL Commenter in der App aktivieren

Als Nächstes installieren und aktivieren Sie SQL Commenter, eine Open-Source-Bibliothek, mit der ORMs SQL-Anweisungen vor der Ausführung mit Kommentaren ergänzen können. SQLcommenter unterstützt mehrere ORMs und Frameworks, einschließlich des von der Beispielanwendung verwendeten: Knex.js. Query Insights verwendet die Informationen in diesen Kommentaren, um eine anwendungsorientierte Sicht auf die Datenbankleistung zu bieten und zu ermitteln, welcher Anwendungscode Probleme verursacht. Die Leistungskosten dürften gering sein. Weitere Informationen finden Sie in der Dokumentation zu Query Insights.

  1. Geben Sie in Cloud Shell Ctrl+c ein, um die Beispielanwendung zu beenden.
  2. Führen Sie den folgenden Befehl aus, um die für SQLcommenter erforderlichen Pakete zu installieren:
  npm install @google-cloud/sqlcommenter-knex @opencensus/nodejs @opencensus/propagation-tracecontext @opentelemetry/api @opentelemetry/core --save
  1. Klicken Sie in Cloud Shell auf die Schaltfläche Schaltfläche „Editor öffnen“, um den Cloud Shell-Editor zu starten.
  2. Suchen Sie im Datei-Explorer nach nodejs-docs-samples/cloud-sql/postgres/knex/server.js und klicken Sie darauf, um die Datei server.js im Editor zu laden.
  3. Suchen Sie in der Datei nach diesem Code:
const process = require('process');

Fügen Sie darunter den folgenden Code ein:

const {wrapMainKnexAsMiddleware} = require('@google-cloud/sqlcommenter-knex');
  1. Suchen Sie in der Datei nach diesem Code:
// Set Content-Type for all responses for these routes.
app.use((req, res, next) => {
  res.set('Content-Type', 'text/html');
  next();
});

Fügen Sie darunter den folgenden Code ein:

app.use(wrapMainKnexAsMiddleware(Knex, {
    traceparent: true,
    tracestate: true,
    route: true,
    db_driver: true
}));

Danach sollte Ihr Code in etwa so aussehen:

...
// Require process, so we can mock environment variables.
const process = require('process');

const {wrapMainKnexAsMiddleware} = require('@google-cloud/sqlcommenter-knex');
const express = require('express');
const Knex = require('knex');
const fs = require('fs');

const app = express();
app.set('view engine', 'pug');
app.enable('trust proxy');

// Automatically parse request body as form data.
app.use(express.urlencoded({extended: false}));
// This middleware is available in Express v4.16.0 onwards
app.use(express.json());

// Set Content-Type for all responses for these routes.
app.use((req, res, next) => {
  res.set('Content-Type', 'text/html');
  next();
});

app.use(wrapMainKnexAsMiddleware(Knex, {
    traceparent: true,
    tracestate: true,
    route: true,
    db_driver: true
}));
...
  1. Klicken Sie auf die Schaltfläche Schaltfläche „Terminal öffnen“, um zu Cloud Shell zurückzukehren und Folgendes auszuführen:
npm start
  1. Klicken Sie in der Anwendung „Tabs vs Spaces“ auf die Schaltflächen, um weitere Stimmen abzugeben und der Datenbank mehr Daten hinzuzufügen.

9. Mit Insights die Abfrageleistung und das End-to-End-Tracing ansehen

Mit dem Query Insights-Dashboard können Sie Fehler in Cloud SQL-Abfragen beheben, um Leistungsprobleme zu erkennen. Wenn Sie auf Statistiken zugreifen möchten, wählen Sie in der linken Navigationsleiste für Ihre Cloud SQL-Instanz Query Insights aus.

Diagramm zur Datenbanklast – alle Abfragen

Das Dashboard „Query Insights“ der obersten Ebene zeigt das Diagramm Datenbanklast – alle Abfragen.

Diagramm „Alle Anfragen“

Das Diagramm enthält Informationen zur CPU-Kapazität, CPU- und CPU-Wartezeit, E/A-Wartezeit und Wartezeit nach Sperrung. Weitere Informationen dazu, was diese Messwerte bedeuten, wo sie gespeichert werden und wie das Diagramm für problematische Anfragen aussieht, finden Sie in der Dokumentation. Bei dieser Beispielanwendung ist die Datenbankabfragelast gering, sodass es keine großen Spitzen in der Grafik gibt.

Welche Anfragen verursachen die höchste Last?

Unter dem Diagramm befindet sich die Tabelle „ABFRAGEN“ mit den normalisierten Abfragen für den ausgewählten Zeitraum. Die Abfragen in der Tabelle sind nach der Gesamtausführungszeit sortiert.

Tabelle mit Top-Abfragen

Sie können auf eine einzelne Abfrage klicken, um detaillierte Informationen dazu aufzurufen, z. B. die Datenbanklast für diese bestimmte Abfrage, die Abfragelatenz, Beispielabfragepläne und die wichtigsten Nutzer. Wenn eine Anwendung mit einem ORM erstellt wird, wie es bei der Beispielanwendung der Fall ist, wissen Sie möglicherweise nicht, welcher Teil der Anwendung für welche Abfrage verantwortlich ist. Im Bereich „Top-Tags“ kannst du das herausfinden.

Woher stammt die Abfragelast in der Anwendung?

Wechseln Sie von der Tabelle „QUERIES“ zur Tabelle „TAGS“, um eine Liste der nach Geschäftslogik getaggten Abfragen aufzurufen. So erhalten Sie eine anwendungszentrierte Ansicht.

Tabelle „Häufigste Tags“

In der Tabelle „TAGS“ sehen Sie die Datenbanklast aufgeschlüsselt nach der Route, die die Last generiert hat. Im Screenshot oben sehen Sie, dass die '/getAllVotes'-Route eine längere durchschnittliche Ausführungszeit und eine höhere durchschnittliche Anzahl zurückgegebener Zeilen hat. Die Ausführungszeit in der Tabelle ist in diesem Fall nicht problematisch. Klicken Sie trotzdem auf die Zeile für '/getAllVotes', um sich die Daten genauer anzusehen.

Warum werden Abfragen langsam ausgeführt?

Klicken Sie im Diagramm Beispielabfragepläne auf den Punkt, um einen Abfrageplan aufzurufen.

Beispiele für Abfragepläne

Die Abfragepläne zeigen, wie PostgreSQL eine Abfrage im Hintergrund ausführt. So lässt sich leichter feststellen, ob es Vorgänge gibt, die zu einer Verlangsamung führen.

Welcher Anwendungscode trägt zur Verlangsamung bei?

Query Insights bietet auch eine kontextbezogene Visualisierung des End-to-End-Tracing, die hilfreich sein kann, um genauer zu untersuchen, welche Teile einer Anwendung langsame Abfragen generieren.

Klicken Sie auf den Tab ENDE zu ENDE, um einen Kontexttrace aufzurufen.

End-to-End-Trace

10. Speicherplatz freigeben und mehr erfahren

Sie haben gelernt, wie Sie Query Insights verwenden, um die Abfrageleistung mit einer Node.js-App und einer Cloud SQL PostgreSQL-Datenbank zu überwachen und zu untersuchen.

Bereinigen

Wenn Sie Ihre Cloud SQL-Instanz nicht weiter ausführen möchten, können Sie sie jetzt löschen.

gcloud sql instances delete my-instance

Weitere Informationen