Auf dieser Seite wird beschrieben, wie Sie Hotspots in Ihrer Datenbank erkennen und Fehler beheben. Sie können sowohl mit GoogleSQL als auch mit PostgreSQL auf Statistiken zu Hotspots in Splits zugreifen.
In Spanner werden Ihre Daten als zusammenhängender Schlüsselbereich gespeichert, der nach den Primärschlüsseln Ihrer Tabellen und Indexe sortiert ist. Ein Split ist ein Bereich von Zeilen aus einer Gruppe von Tabellen oder einem Index. Der Beginn des Splits wird als Split-Start bezeichnet. Mit dem Split-Limit wird das Ende des Splits festgelegt. Der Split umfasst den Split-Start, aber nicht das Split-Limit.
In Spanner sind Hotspots Situationen, in denen zu viele Anfragen an denselben Server gesendet werden, wodurch die Ressourcen des Servers ausgelastet werden und möglicherweise hohe Latenzen entstehen. Die von Hotspots betroffenen Splits werden als stark genutzt oder mäßig genutzt bezeichnet.
Die Hotspot-Statistik eines Splits (im System als CPU_USAGE_SCORE
gekennzeichnet) ist ein Maß für die Last auf einem Split, die durch die auf dem Server verfügbaren Ressourcen eingeschränkt ist. Dieser Wert wird als Prozentsatz angegeben. Wenn mehr als 50% der Last auf einem Split durch die verfügbaren Ressourcen eingeschränkt werden, gilt der Split als warm. Wenn 100% der Last auf einen Split beschränkt sind, gilt der Split als hot.
Spanner verwendet lastbasierte Aufteilung, um die Datenlast gleichmäßig auf die Server der Instanz zu verteilen. Die warmen und heißen Splits können zur Lastverteilung auf verschiedene Server verschoben oder in kleinere Splits aufgeteilt werden. Aufgrund von Antipatterns in der Anwendung kann Spanner die Last jedoch möglicherweise auch nach mehreren Versuchen, die Daten aufzuteilen, nicht ausgleichen. Daher müssen persistente Hotspots, die mindestens 10 Minuten lang anhalten, möglicherweise weiter untersucht und es müssen eventuell Änderungen an der Anwendung vorgenommen werden.
Mithilfe der Spanner-Statistiken zum Heißlaufen von Splits können Sie die Splits ermitteln, in denen Hotspots auftreten. Sie können dann bei Bedarf Änderungen an Ihrer Anwendung oder Ihrem Schema vornehmen. Sie können diese Statistiken mithilfe von SQL-Anweisungen aus den SPANNER_SYS.SPLIT_STATS_TOP_MINUTE
-Systemtabellen abrufen.
Statistiken zu Hot Splits aufrufen
Spanner stellt die Statistiken für Hot Splits im Schema SPANNER_SYS
bereit. SPANNER_SYS
-Daten sind nur über GoogleSQL- und PostgreSQL-Schnittstellen verfügbar. Sie haben folgende Möglichkeiten, auf diese Daten zuzugreifen:
- Die Spanner Studio-Seite einer Datenbank in der Google Cloud Console.
- Befehl
gcloud spanner databases execute-sql
- Die Methode
executeSql
oderexecuteStreamingSql
.
Die folgenden von Spanner bereitgestellten Einzellesemethoden unterstützen SPANNER_SYS
nicht:
- Starken Lesevorgang aus einer einzelnen Zeile oder mehreren Zeilen in einer Tabelle durchführen
- Veralteten Lesevorgang aus einer einzelnen Zeile oder mehreren Zeilen in einer Tabelle durchführen
- Aus einer einzelnen Zeile oder mehreren Zeilen in einem sekundären Index lesen
Statistiken zu beliebten Splits
In der folgenden Tabelle können Sie die häufig genutzten Splits im Blick behalten:
SPANNER_SYS.SPLIT_STATS_TOP_MINUTE
: Hier werden Splits angezeigt, die in 1-Minuten-Intervallen besonders beliebt sind.
Diese Tabellen haben folgende Attribute:
- Jede Tabelle enthält Daten für nicht überlappende Zeitintervalle in der Länge, die der Tabellenname festlegt.
Die Intervalle basieren auf der Uhrzeit:
- 1-Minuten-Intervalle enden nach einer vollen Minute.
Nach jedem Intervall erfasst Spanner Daten von allen Servern und stellt die Daten danach in den
SPANNER_SYS
-Tabellen bereit.Beispielsweise sind die neuesten, für SQL-Abfragen verfügbaren Intervalle um 11:59:30 Uhr:
- 1 Minute: 11:58:00–11:58:59 Uhr
Spanner gruppiert die Statistiken nach Splits.
Jede Zeile enthält einen Prozentsatz, der angibt, wie stark oder schwach ein Split genutzt wird. Dies gilt für jeden Split, für den Cloud Spanner während des angegebenen Intervalls Statistiken erfasst.
Wenn weniger als 50% der Last auf einem Split durch die verfügbaren Ressourcen eingeschränkt werden, wird die Statistik in Spanner nicht erfasst. Wenn Spanner nicht alle Hot Splits während des Intervalls speichern kann, priorisiert das System die Splits mit dem höchsten
CPU_USAGE_SCORE
-Prozentsatz im angegebenen Intervall. Wenn keine Splits zurückgegeben werden, gibt es keine Hotspots.
Tabellenschema
Die folgende Tabelle enthält das Tabellenschema für die folgenden Statistiken:
SPANNER_SYS.SPLIT_STATS_TOP_MINUTE
Spaltenname | Typ | Beschreibung |
---|---|---|
INTERVAL_END |
TIMESTAMP |
Ende des Zeitintervalls, in dem der Split stark genutzt wurde |
SPLIT_START |
STRING |
Der Startschlüssel des Zeilenbereichs im Split. Der Split-Start kann auch <begin> sein, was den Beginn des Schlüsselbereichs angibt. |
SPLIT_LIMIT
|
STRING
|
Der Limitschlüssel für den Zeilenbereich im Split. Der Limitschlüssel kann auch <end> sein, was das Ende des Schlüsselbereichs angibt. |
CPU_USAGE_SCORE
|
INT64
|
Der CPU_USAGE_SCORE -Prozentsatz der Splits. Ein CPU_USAGE_SCORE -Prozentsatz von 50% weist auf das Vorhandensein von warmen oder heißen Splits hin. |
AFFECTED_TABLES |
STRING ARRAY |
Die Tabellen, deren Zeilen möglicherweise im Split enthalten sind. |
Split-Start- und Split-Limitschlüssel
Ein Split ist ein zusammenhängender Zeilenbereich einer Datenbank, der durch seine Start- und Limit-Schlüssel definiert wird. Ein Split kann eine einzelne Zeile, ein schmaler oder ein breiter Zeilenbereich sein und mehrere Tabellen oder Indexe umfassen.
In den Spalten SPLIT_START
und SPLIT_LIMIT
werden die Primärschlüssel einer Warm- oder Hot-Aufteilung angegeben.
Beispielschema
Das folgende Schema ist eine Beispielstabelle für die Themen auf dieser Seite.
GoogleSQL
CREATE TABLE Users (
UserId INT64 NOT NULL,
FirstName STRING(MAX),
LastName STRING(MAX),
) PRIMARY KEY(UserId);
CREATE INDEX UsersByFirstName ON Users(FirstName DESC);
CREATE TABLE Threads (
UserId INT64 NOT NULL,
ThreadId INT64 NOT NULL,
Starred BOOL,
) PRIMARY KEY(UserId, ThreadId),
INTERLEAVE IN PARENT Users ON DELETE CASCADE;
CREATE TABLE Messages (
UserId INT64 NOT NULL,
ThreadId INT64 NOT NULL,
MessageId INT64 NOT NULL,
Subject STRING(MAX),
Body STRING(MAX),
) PRIMARY KEY(UserId, ThreadId, MessageId),
INTERLEAVE IN PARENT Threads ON DELETE CASCADE;
CREATE INDEX MessagesIdx ON Messages(UserId, ThreadId, Subject),
INTERLEAVE IN Threads;
PostgreSQL
CREATE TABLE users
(
userid BIGINT NOT NULL PRIMARY KEY,-- INT64 to BIGINT
firstname VARCHAR(max),-- STRING(MAX) to VARCHAR(MAX)
lastname VARCHAR(max)
);
CREATE INDEX usersbyfirstname
ON users(firstname DESC);
CREATE TABLE threads
(
userid BIGINT NOT NULL,
threadid BIGINT NOT NULL,
starred BOOLEAN, -- BOOL to BOOLEAN
PRIMARY KEY (userid, threadid),
CONSTRAINT fk_threads_user FOREIGN KEY (userid) REFERENCES users(userid) ON
DELETE CASCADE -- Interleave to Foreign Key constraint
);
CREATE TABLE messages
(
userid BIGINT NOT NULL,
threadid BIGINT NOT NULL,
messageid BIGINT NOT NULL PRIMARY KEY,
subject VARCHAR(max),
body VARCHAR(max),
CONSTRAINT fk_messages_thread FOREIGN KEY (userid, threadid) REFERENCES
threads(userid, threadid) ON DELETE CASCADE
-- Interleave to Foreign Key constraint
);
CREATE INDEX messagesidx ON messages(userid, threadid, subject), REFERENCES
threads(userid, threadid);
Angenommen, Ihr Schlüsselbereich sieht so aus:
PRIMÄRSCHLÜSSEL |
---|
<begin> |
Users() |
Threads() |
Users(2) |
Users(3) |
Threads(3) |
Threads(3,"a") |
Messages(3,"a",1) |
Messages(3,"a",2) |
Threads(3, "aa") |
Users(9) |
Users(10) |
Threads(10) |
UsersByFirstName("abc") |
UsersByFirstName("abcd") |
<end> |
Beispiel für Splits
Im Folgenden finden Sie einige Beispiele für Splits, damit Sie sehen, wie sie aussehen.
SPLIT_START
und SPLIT_LIMIT
können die Zeile einer Tabelle oder eines Index angeben oder <begin>
und <end>
sein, die die Grenzen des Schlüsselbereichs der Datenbank darstellen. SPLIT_START
und SPLIT_LIMIT
können auch gekürzte Schlüssel enthalten, die allen vollständigen Schlüsseln in der Tabelle vorangestellt sind. Threads(10)
ist beispielsweise ein Präfix für jede Threads
-Zeile, die in Users(10)
verschachtelt ist.
SPLIT_START | SPLIT_LIMIT | AFFECTED_TABLES | ERKLÄRUNG |
---|---|---|---|
Users(3) |
Users(10) |
UsersByFirstName : Users , Threads , Messages , MessagesIdx |
Die Aufteilung beginnt in der Zeile mit UserId=3 und endet in der Zeile vor der Zeile mit UserId = 10 . Der Split enthält die Zeilen der Tabelle Users und alle Zeilen der überlappenden Tabellen für UserId=3 bis 10. |
Messages(3,"a",1) |
Threads(3,"aa") |
Threads , Messages , MessagesIdx |
Die Aufteilung beginnt bei der Zeile mit UserId=3 , ThreadId="a" und MessageId=1 und endet bei der Zeile vor der Zeile mit dem Schlüssel UserId=3 und ThreadsId = "aa" . Die Aufteilung enthält alle Tabellen zwischen Messages(3,"a",1) und Threads(3,"aa") . Da split_start und split_limit in derselben Zeile der übergeordneten Tabelle verschränkt sind, enthält der Split die Zeilen der verschränkten Tabellen zwischen dem Start und dem Grenzwert. Unter schemas-overview erfahren Sie, wie überlappende Tabellen zusammengefasst werden. |
Messages(3,"a",1) |
<end> |
UsersByFirstName : Users , Threads , Messages , MessagesIdx |
Der Split beginnt in der Tabelle „messages“ in der Zeile mit dem Schlüssel UserId=3 , ThreadId="a" und MessageId=1 . Der Split enthält alle Zeilen von split_start bis <end> , dem Ende des Schlüsselbereichs der Datenbank. Alle Zeilen der Tabellen nach dem split_start , z. B. Users(4) , sind im Split enthalten. |
<begin> |
Users(9) |
UsersByFirstName : Users , Threads , Messages , MessagesIdx |
Der Split beginnt bei <begin> , dem Beginn des Schlüsselbereichs der Datenbank, und endet in der Zeile vor der Users -Zeile mit UserId=9 . Der Split enthält also alle Tabellenzeilen vor Users , alle Zeilen der Tabelle Users vor UserId=9 und die Zeilen der verschachtelten Tabellen. |
Messages(3,"a",1) |
Threads(10) |
UsersByFirstName : Users , Threads , Messages , MessagesIdx |
Der Split beginnt bei Messages(3,"a", 1) , das in Users(3) verschachtelt ist, und endet in der Zeile vor Threads(10) . Threads(10) ist ein gekürzter Split-Schlüssel, der ein Präfix eines beliebigen Schlüssels der Threads-Tabelle ist, der in Users(10) verschachtelt ist. |
Users() |
<end> |
UsersByFirstName : Users , Threads , Messages , MessagesIdx |
Der Split beginnt mit dem gekürzten Split-Schlüssel von Users() , der jedem vollständigen Schlüssel der Tabelle Users vorangestellt ist. Der Split erstreckt sich bis zum Ende des möglichen Schlüsselbereichs in der Datenbank. Die affected_tables umfassen daher die Tabelle Users , ihre verschachtelten Tabellen und Indexe sowie alle Tabellen, die nach „users“ angezeigt werden. |
Threads(10) |
UsersByFirstName("abc") |
UsersByFirstName : Users , Threads , Messages , MessagesIdx |
Die Aufteilung beginnt in Zeile Threads mit UserId = 10 und endet am Index UsersByFirstName mit dem Schlüssel vor "abc" . |
Beispielabfragen zum Ermitteln von Hot Splits
Das folgende Beispiel zeigt eine SQL-Anweisung, mit der Sie die Statistiken für Hot Splits abrufen können. Sie können diese SQL-Anweisungen mit den Clientbibliotheken, gcloud oder der Google Cloud Console ausführen.
GoogleSQL
SELECT t.split_start,
t.split_limit,
t.cpu_usage_score,
t.affected_tables,
FROM SPANNER_SYS.SPLIT_STATS_TOP_MINUTE t
WHERE t.interval_end =
(SELECT MAX(interval_end)
FROM SPANNER_SYS.SPLIT_STATS_TOP_MINUTE)
ORDER BY t.cpu_usage_score DESC;
PostgreSQL
SELECT t.split_start,
t.split_limit,
t.cpu_usage_score,
t.affected_tables
FROM SPANNER_SYS.SPLIT_STATS_TOP_MINUTE t
WHERE t.interval_end = (
SELECT MAX(interval_end)
FROM SPANNER_SYS.SPLIT_STATS_TOP_MINUTE
)
ORDER BY t.cpu_usage_score DESC;
Die Ausgabe der Abfrage sieht so aus:
SPLIT_START |
SPLIT_LIMIT |
CPU_USAGE_SCORE |
AFFECTED_TABLES |
---|---|---|---|
Users(13) |
Users(76) |
82 |
Messages,Users,Threads |
Users(101) |
Users(102) |
90 |
Messages,Users,Threads |
Threads(10, "a") |
Threads(10, "aa") |
100 |
Messages,Threads |
Messages(631, "abc", 1) |
Messages(631, "abc", 3) |
100 |
Messages |
Threads(12, "zebra") |
Users(14) |
76 |
Messages,Users,Threads |
Users(620) |
<end> |
100 |
Messages,Users,Threads |
Datenaufbewahrung für die Statistiken der Hot-Aufteilung
Spanner speichert die Daten für jede Tabelle mindestens für die folgenden Zeiträume:
SPANNER_SYS.SPLIT_STATS_TOP_MINUTE
: Intervalle der letzten 6 Stunden.
Fehlerbehebung bei Hotspots mithilfe von Statistiken zu stark genutzten Splits
In diesem Abschnitt wird beschrieben, wie Sie Hotspots erkennen und Fehler beheben.
Zeitraum für die Untersuchung auswählen
Sehen Sie sich die Latenzmesswerte für Ihre Spanner-Datenbank an, um den Zeitraum zu ermitteln, in dem Ihre Anwendung eine hohe Latenz und CPU-Auslastung aufwies. Beispiel: Ein Problem trat am 18. Mai 2024 um 22:50 Uhr auf.
Dauerhafte Hotspots finden
Da Spanner Ihre Last mit lastbasierter Aufteilung ausgleicht, empfehlen wir, dass Sie prüfen, ob Hotspots länger als 10 Minuten bestehen. Dazu können Sie die Tabelle SPANNER_SYS.SPLIT_STATS_TOP_MINUTE
abfragen, wie im folgenden Beispiel gezeigt:
GoogleSQL
SELECT Count(DISTINCT t.interval_end)
FROM SPANNER_SYS.SPLIT_STATS_TOP_MINUTE t
WHERE t.cpu_usage_score >= 50
AND t.interval_end >= "interval_end_date_time"
AND t.interval_end <= "interval_end_date_time";
Ersetzen Sie interval_end_date_time durch das Datum und die Uhrzeit für das Intervall im Format 2024-05-18T17:40:00Z
.
PostgreSQL
SELECT COUNT(DISTINCT t.interval_end)
FROM SPLIT_STATS_TOP_MINUTE t
WHERE t.cpu_usage_score >= 50
AND t.interval_end >= 'interval_end_date_time'::timestamptz
AND t.interval_end <= 'interval_end_date_time'::timestamptz;
Ersetzen Sie interval_end_date_time durch das Datum und die Uhrzeit für das Intervall im Format 2024-05-18T17:40:00Z
.
Wenn das Ergebnis der vorherigen Abfrage gleich 10 ist, bedeutet das, dass in Ihrer Datenbank Hotspots auftreten, die möglicherweise weiter untersucht werden müssen.
Segmente mit dem höchsten CPU_USAGE_SCORE
-Wert finden
In diesem Beispiel führen wir den folgenden SQL-Code aus, um die Zeilenbereiche mit dem höchsten CPU_USAGE_SCORE
-Wert zu ermitteln:
GoogleSQL
SELECT t.split_start,
t.split_limit,
t.affected_tables,
t.cpu_usage_score
FROM SPANNER_SYS.SPLIT_STATS_TOP_MINUTE t
WHERE t.cpu_usage_score >= 50
AND t.interval_end = "interval_end_date_time";
Ersetzen Sie interval_end_date_time durch das Datum und die Uhrzeit für das Intervall im Format 2024-05-18T17:40:00Z
.
PostgreSQL
SELECT t.split_start,
t.split_limit,
t.affected_tables,
t.cpu_usage_score
FROM SPLIT_STATS_TOP_MINUTE t
WHERE t.cpu_usage_score = 100
AND t.interval_end = 'interval_end_date_time'::timestamptz;
Ersetzen Sie interval_end_date_time durch das Datum und die Uhrzeit für das Intervall im Format 2024-05-18T17:40:00Z
.
Die vorherige SQL-Anweisung gibt Folgendes aus:
SPLIT_START |
SPLIT_LIMIT |
CPU_USAGE_SCORE |
AFFECTED_TABLES |
---|---|---|---|
Users(180) |
<end> |
85 |
Messages,Users,Threads |
Users(24) |
Users(76) |
76 |
Messages,Users,Threads |
In dieser Ergebnistabelle sehen Sie, dass Hotspots bei zwei Splits aufgetreten sind. Die lastbasierte Aufteilung von Spanner kann versuchen, Hotspots in diesen Aufteilungen zu beheben. Das ist jedoch möglicherweise nicht möglich, wenn es problematische Muster im Schema oder in der Arbeitslast gibt. Damit Sie erkennen können, ob es Splits gibt, bei denen Sie eingreifen müssen, empfehlen wir, die Splits mindestens 10 Minuten lang zu beobachten. Mit dem folgenden SQL-Code wird beispielsweise der erste Split in den letzten zehn Minuten erfasst.
GoogleSQL
SELECT t.interval_end,
t.split_start,
t.split_limit,
t.cpu_usage_score
FROM SPANNER_SYS.SPLIT_STATS_TOP_MINUTE t
WHERE t.split_start = "users(180)"
AND t.split_limit = "<end>"
AND t.interval_end >= "interval_end_date_time"
AND t.interval_end <= "interval_end_date_time";
Ersetzen Sie interval_end_date_time durch das Datum und die Uhrzeit für das Intervall im Format 2024-05-18T17:40:00Z
.
PostgreSQL
SELECT t.interval_end,
t.split_start,
t.split_limit,
t.cpu_usage_score
FROM SPANNER_SYS.SPLIT_STATS_TOP_MINUTE t
WHERE t.split_start = 'users(180)'
AND t.split_limit = ''
AND t.interval_end >= 'interval_end_date_time'::timestamptz
AND t.interval_end <= 'interval_end_date_time'::timestamptz;
Ersetzen Sie interval_end_date_time durch das Datum und die Uhrzeit für das Intervall im Format 2024-05-18T17:40:00Z
.
Die vorherige SQL-Anweisung gibt Folgendes aus:
INTERVAL_END |
SPLIT_START |
SPLIT_LIMIT |
CPU_USAGE_SCORE |
---|---|---|---|
2024-05-18T17:46:00Z |
Users(180) |
<end> |
85 |
2024-05-18T17:47:00Z |
Users(180) |
<end> |
85 |
2024-05-18T17:48:00Z |
Users(180) |
<end> |
85 |
2024-05-18T17:49:00Z |
Users(180) |
<end> |
85 |
2024-05-18T17:50:00Z |
Users(180) |
<end> |
85 |
Der Split scheint in den letzten Minuten sehr beliebt gewesen zu sein. Möglicherweise müssen Sie die Aufteilung länger beobachten, um festzustellen, dass die lastbasierte Aufteilung von Spanner den Hotspot reduziert. Es kann vorkommen, dass Spanner nicht weiter ausbalancieren kann.
Fragen Sie beispielsweise die Tabelle SPANNER_SYS.SPLIT_STATS_TOP_MINUTE
ab. Sehen Sie sich die folgenden Beispielszenarien an.
GoogleSQL
SELECT t.interval_end,
t.split_start,
t.split_limit,
t.cpu_usage_score
FROM SPANNER_SYS.SPLIT_STATS_TOP_MINUTE t
WHERE t.interval_end >= "interval_end_date_time"
AND t.interval_end <= "interval_end_date_time";
Ersetzen Sie interval_end_date_time durch das Datum und die Uhrzeit für das Intervall im Format 2024-05-18T17:40:00Z
.
PostgreSQL
SELECT t.interval_end,
t.split_start,
t.split_limit,
t._cpu_usage
FROM SPANNER_SYS.SPLIT_STATS_TOP_MINUTE t
WHERE t.interval_end >= 'interval_end_date_time'::timestamptz
AND t.interval_end <= 'interval_end_date_time'::timestamptz;
Ersetzen Sie interval_end_date_time durch das Datum und die Uhrzeit für das Intervall im Format 2024-05-18T17:40:00Z
.
Einzelne „heiße“ Zeile
Im folgenden Beispiel sieht es so aus, als ob Threads(10,"spanner")
in einer einzelnen Zeilenaufteilung enthalten ist, die über 10 Minuten lang aktiv war. Das kann passieren, wenn eine beliebte Zeile dauerhaft stark belastet wird.
INTERVAL_END |
SPLIT_START |
SPLIT_LIMIT |
CPU_USAGE_SCORE |
---|---|---|---|
2024-05-16T20:40:00Z |
Threads(10,"spanner") |
Threads(10,"spanner1") |
62 |
2024-05-16T20:41:00Z |
Threads(10,"spanner") |
Threads(10,"spanner1") |
62 |
2024-05-16T20:42:00Z |
Threads(10,"spanner") |
Threads(10,"spanner1") |
62 |
2024-05-16T20:43:00Z |
Threads(10,"spanner") |
Threads(10,"spanner1") |
62 |
2024-05-16T20:44:00Z |
Threads(10,"spanner") |
Threads(10,"spanner1") |
62 |
2024-05-16T20:45:00Z |
Threads(10,"spanner") |
Threads(10,"spanner1") |
62 |
2024-05-16T20:46:00Z |
Threads(10,"spanner") |
Threads(10,"spanner1") |
80 |
2024-05-16T20:47:00Z |
Threads(10,"spanner") |
Threads(10,"spanner1") |
80 |
2024-05-16T20:48:00Z |
Threads(10,"spanner") |
Threads(10,"spanner1") |
80 |
2024-05-16T20:49:00Z |
Threads(10,"spanner") |
Threads(10,"spanner1") |
100 |
2024-05-16T20:50:00Z |
Threads(10,"spanner") |
Threads(10,"spanner1") |
100 |
Spanner kann die Last für diesen einzelnen Schlüssel nicht ausgleichen, da er nicht weiter aufgeteilt werden kann.
Hotspot verschieben
Im folgenden Beispiel wird die Last im Zeitverlauf durch zusammenhängende Splits verschoben.
INTERVAL_END |
SPLIT_START |
SPLIT_LIMIT |
CPU_USAGE_SCORE |
---|---|---|---|
2024-05-16T20:40:00Z |
Threads(1,"a") |
Threads(1,"aa") |
100 |
2024-05-16T20:41:00Z |
Threads(1,"aa") |
Threads(1,"ab") |
100 |
2024-05-16T20:42:00Z |
Threads(1,"ab") |
Threads(1,"c") |
100 |
2024-05-16T20:43:00Z |
Threads(1,"c") |
Threads(1,"ca") |
100 |
Dies kann beispielsweise bei einer Arbeitslast auftreten, bei der Schlüssel in monoton steigender Reihenfolge gelesen oder geschrieben werden. Spanner kann die Last nicht ausgleichen, um die Auswirkungen dieses Anwendungsverhaltens zu mildern.
Normales Load-Balancing
Spanner versucht, die Last auszugleichen, indem mehr Aufteilungen hinzugefügt oder Aufteilungen verschoben werden. Das folgende Beispiel zeigt, wie das aussehen könnte.
INTERVAL_END |
SPLIT_START |
SPLIT_LIMIT |
CPU_USAGE_SCORE |
---|---|---|---|
2024-05-16T20:40:00Z |
Threads(1000,"zebra") |
<end> |
82 |
2024-05-16T20:41:00Z |
Threads(1000,"zebra") |
<end> |
90 |
2024-05-16T20:42:00Z |
Threads(1000,"zebra") |
<end> |
100 |
2024-05-16T20:43:00Z |
Threads(1000,"zebra") |
Threads(2000,"spanner") |
100 |
2024-05-16T20:44:00Z |
Threads(1200,"c") |
Threads(2000) |
92 |
2024-05-16T20:45:00Z |
Threads(1500,"c") |
Threads(1700,"zach") |
76 |
2024-05-16T20:46:00Z |
Threads(1700) |
Threads(1700,"c") |
76 |
2024-05-16T20:47:00Z |
Threads(1700) |
Threads(1700,"c") |
50 |
2024-05-16T20:48:00Z |
Threads(1700) |
Threads(1700,"c") |
39 |
Die größere Aufteilung am 16.05.2024 um 17:40:00 Uhr wurde weiter in eine kleinere Aufteilung unterteilt. Dadurch ist die Statistik CPU_USAGE_SCORE
gesunken.
Spanner erstellt möglicherweise keine Splits in einzelne Zeilen. Die Aufteilungen spiegeln die Arbeitslast wider, die die hohe CPU_USAGE_SCORE
-Statistik verursacht.
Wenn Sie über 10 Minuten lang einen anhaltenden Hot Split beobachtet haben, lesen Sie den Abschnitt Best Practices zur Minimierung von Hotspots.
Best Practices zur Minimierung von Hotspots
Wenn die Latenz durch den Lastenausgleich nicht verringert wird, müssen Sie als Nächstes die Ursache der Hotspots ermitteln. Danach haben Sie die Möglichkeit, die Hotspotting-Arbeitslast zu reduzieren oder das Anwendungsschema und die Anwendungslogik zu optimieren, um Hotspots zu vermeiden.
Ursache ermitteln
Mit Lock & Transaction Insights (Statistiken zu Sperren und Transaktionen) können Sie nach Transaktionen mit einer hohen Wartezeit für Sperren suchen, bei denen der Startschlüssel des Zeilenbereichs innerhalb des Hot-Splits liegt.
Verwenden Sie Abfragestatistiken, um nach Abfragen zu suchen, die Daten aus der Tabelle mit dem Hot Split lesen und bei denen die Latenz in letzter Zeit zugenommen hat oder das Verhältnis von Latenz zu CPU höher ist.
Suchen Sie mit älteste aktive Abfragen nach Abfragen, die Daten aus der Tabelle mit dem Hot Split lesen und eine höhere als die erwartete Latenz aufweisen.
Einige Sonderfälle, auf die Sie achten sollten:
- Prüfen Sie, ob die Gültigkeitsdauer (TTL) vor Kurzem aktiviert wurde. Wenn es viele Splits aus alten Daten gibt, kann TTL bei Massenlöschungen die
CPU_USAGE_SCORE
-Werte erhöhen. In diesem Fall sollte sich das Problem beheben, sobald die ursprünglichen Löschvorgänge abgeschlossen sind.
Arbeitslast optimieren
- Best Practices für SQL Berücksichtigen Sie veraltete Lesevorgänge, Schreibvorgänge, bei denen nicht zuerst gelesen wird, oder das Hinzufügen von Indexen.
- Orientieren Sie sich an den Best Practices für Schemas. Achten Sie darauf, dass Ihr Schema für das Load-Balancing ausgelegt ist und Hotspots vermieden werden.
Nächste Schritte
- Best Practices für das Schemadesign
- Weitere Informationen zu Key Visualizer
- Beispiele für Schemadesigns ansehen
- Informationen zum Verwenden des Dashboards mit aufgeteilten Statistiken