Primärschlüsselstrategien migrieren

In diesem Dokument werden Strategien für die Migration von Primärschlüsseln aus Ihren Datenbanktabellen zu Spanner beschrieben, um Heißlaufen zu vermeiden. Ein Hotspot ist eine Zusammenfassung von Vorgängen auf einem einzelnen Knoten. Dadurch wird der Schreibdurchsatz auf die Kapazität des Knotens verringert, anstatt vom Load-Balancing aller Schreibvorgänge auf den Spanner-Knoten zu profitieren. Die häufigste Ursache für Hotspots ist die Verwendung monoton zunehmender oder abnehmender Spalten als erster Teil Ihres Primärschlüssels (z. B. regelmäßige Sequenzen oder Zeitstempel).

Gesamtstrategien

In Spanner muss jede Tabelle, die mehr als eine Zeile speichern muss, einen Primärschlüssel haben, der aus einer oder mehreren Spalten der Tabelle besteht. Der Primärschlüssel der Tabelle identifiziert jede Zeile in einer Tabelle eindeutig und Spanner verwendet den Primärschlüssel, um die Tabellenzeilen zu sortieren. Da Spanner hochgradig verteilt ist, können Sie mit den folgenden Methoden eindeutige Primärschlüsselwerte generieren und das Risiko von Hotspots reduzieren:

  • Verwenden Sie ein automatisch generiertes Schlüsselfeature, das Hotspots und von Spanner unterstützt wird. Weitere Informationen finden Sie im Abschnitt Automatisch generierte Schlüssel migrieren.
    • Verwenden Sie die Funktion GENERATE_UUID() (GoogleSQL, PostgreSQL), um Universally Unique Identifier-Werte (UUID Version 4) mit dem Datentyp STRING(36) zu generieren. RFC 4122 definiert das Format der UUID Version 4.
    • Verwenden Sie eine Bit-umgekehrte positive Sequenz (GoogleSQL, PostgreSQL). Eine solche Sequenz generiert positive Werte mit Bits höherer Ordnung, die bereits umgekehrt sind, sodass sie gleichmäßig über den positiven 64-Bit-Zahlenraum verteilt sind.
  • Tauschen Sie die Reihenfolge der Schlüssel so aus, dass die Spalte mit dem monoton zu- oder abnehmenden Wert nicht der erste Schlüsselteil ist.
  • Hashen Sie den eindeutigen Schlüssel und verteilen Sie die Schreibvorgänge auf logische Shards. Dazu erstellen Sie eine Spalte, die den Hash des eindeutigen Schlüssels enthält, und verwenden diese Hash-Spalte (oder die Hash-Spalte und die Spalten mit dem eindeutigen Schlüssel) als Primärschlüssel. Mit diesem Ansatz können Sie Hotspots vermeiden, da neue Zeilen gleichmäßiger über den Schlüsselbereich verteilt werden.

Nachdem Sie den Primärschlüssel für die Tabelle festgelegt haben, können Sie ihn nicht mehr ändern. Dazu müssten Sie die Tabelle löschen und neu erstellen. Weitere Informationen zum Zuweisen des Primärschlüssels finden Sie unter Schema und Datenmodell – Primärschlüssel.

Im Folgenden finden Sie ein Beispiel für eine DDL-Anweisung, mit der eine Tabelle für eine Datenbank mit Musiktiteln erstellt wird:

GoogleSQL

CREATE TABLE Singers (
  SingerId   INT64 NOT NULL,
  FirstName  STRING(1024),
  LastName   STRING(1024),
  SingerInfo BYTES(MAX),
  BirthDate  DATE,
) PRIMARY KEY(SingerId);

PostgreSQL

CREATE TABLE Singers (
  SingerId   bigint NOT NULL,
  FirstName  varchar(1024),
  LastName   varchar(1024),
  SingerInfo bytea,
  BirthDate  date,
  PRIMARY KEY(SingerId)
);

Automatisch generierte Schlüssel migrieren

In diesem Abschnitt werden Strategien und Beispiele für die folgenden Szenarien beschrieben, in denen die Quelltabelle bereits ein automatisch generiertes Schlüsselfeature verwendet:

  • Migration aus einer Quelltabelle, die einen UUID-Primärschlüssel verwendet.
  • Migration aus einer Quelltabelle, die einen sequenziellen, automatisch generierten Ganzzahlschlüssel verwendet. Beispiele hierfür sind Sequenzen (die verschiedene Datenbanken unterstützen), IDENTITY-Spalten (die verschiedene Datenbanken unterstützen), PostgreSQL-Datentypen SERIAL und das MySQL-Spaltenattribut AUTO_INCREMENT.
  • Migration von einer Quelltabelle, die einen Bit-Umkehrschlüssel verwendet. Vielleicht ist die Quelldatenbank Spanner, wo Sie Schlüssel/Wert-Paare mithilfe der Anleitung Bit-Umkehrungen für sequenzielle Werte erstellen.

Beachten Sie, dass Spanner bei allen Strategien keine Daten ändert, die aus einer Quelldatenbank migriert werden. Sie ändern lediglich die Methode, um neue Daten zu generieren.

UUID-Schlüsselspalten migrieren

Wenn die Quelltabelle eine UUID-Spalte verwendet, können Sie die Spalte in den Typ STRING konvertieren, die Werte gemäß der RFC 4122-Spezifikation in Kleinbuchstaben umwandeln und die Funktion GENERATE_UUID() (GoogleSQL, PostgreSQL) als Spaltenstandardwert verwenden. Beispiel:

GoogleSQL


CREATE TABLE UserAccessLog (
UserId     STRING(36) DEFAULT (GENERATE_UUID()),
...
) PRIMARY KEY (UserId);

PostgreSQL


CREATE TABLE UserAccessLog (
UserId     varchar(36) DEFAULT SPANNER.GENERATE_UUID(),
...
PRIMARY KEY (UserId)
);

Sequenzielle Schlüsselspalten migrieren

Wenn das Quelldatenbanksystem sequenzielle Werte für eine Schlüsselspalte generiert, können Sie in Ihrem Spanner-Schema eine durch Bit umgedrehte positive Sequenz (GoogleSQL, PostgreSQL) verwenden, um Werte zu generieren, die gleichmäßig über den positiven 64-Bit-Ganzzahlraum verteilt sind. Wenn Sie verhindern möchten, dass die Spanner-Sequenz einen Wert generiert, der sich mit einem migrierten Wert überschneidet, können Sie einen übersprungenen Bereich dafür definieren. Sie können beispielsweise den Bereich von 1 bis 4.294.967.296 (2^32) für die folgenden beiden Sequenzen überspringen, wenn Sie wissen, dass die Quelldatenbank nur 32-Bit-Ganzzahlen generiert:

GoogleSQL


CREATE SEQUENCE MyFirstSequence OPTIONS (
  sequence_kind = "bit_reversed_positive",
  skip_range_min = 1,
  skip_range_max = 4294967296
);

ALTER SEQUENCE MySecondSequence SET OPTIONS (
  skip_range_min = 1,
  skip_range_max = 4294967296
);

PostgreSQL


CREATE SEQUENCE MyFirstSequence BIT_REVERSED_POSITIVE
  SKIP RANGE 1 4294967296;

ALTER SEQUENCE MySecondSequence SKIP RANGE 1 4294967296;

Bit-umgekehrte Schlüsselspalten migrieren

Wenn Sie Ihre Schlüssel/Wert-Paare bereits umgekehrt haben, um Hotspot-Probleme in der Quelldatenbank zu vermeiden, können Sie auch eine Spanner-Bit-Umkehrung mit positiver Sequenz verwenden (GoogleSQL, PostgreSQL), um solche Werte weiter zu generieren. Um doppelte Werte zu vermeiden, können Sie die Sequenz so konfigurieren, dass der Zähler mit einer benutzerdefinierten Zahl beginnt.

Wenn Sie beispielsweise Zahlen von 1 auf 1.000 umgekehrt haben, um Primärschlüsselwerte zu generieren, kann der Zähler der Spanner-Sequenz mit einer beliebigen Zahl größer als 10.000 beginnen. Optional können Sie eine hohe Zahl auswählen, um einen Puffer für neue Schreibvorgänge zu lassen, die nach der Datenmigration in der Quelldatenbank auftreten. Im folgenden Beispiel beginnen die Zähler bei 11.000:

GoogleSQL


CREATE SEQUENCE MyFirstSequence OPTIONS (
  sequence_kind = "bit_reversed_positive",
  start_with_counter = 11000
);

ALTER SEQUENCE MySecondSequence SET OPTIONS (
  start_with_counter = 11000
);

PostgreSQL


CREATE SEQUENCE MyFirstSequence BIT_REVERSED_POSITIVE
  START COUNTER 11000;

ALTER SEQUENCE MySecondSequence RESTART COUNTER 11000;