Primärschlüsselstrategien migrieren

In diesem Dokument werden Strategien zum Migrieren von Primärschlüsseln aus Ihren Datenbanktabellen zu Spanner beschrieben, um Heißlaufensprobleme zu vermeiden. Ein Hotspot ist eine Konzentration von Vorgängen auf einem einzelnen Knoten, wodurch der Schreibdurchsatz auf die Kapazität des Knotens reduziert wird. Der Vorteil ist, dass alle Schreibvorgänge auf den Spanner-Knoten verteilt werden. Die Verwendung von kontinuierlich ansteigenden oder abnehmenden Spalten als erster Teil Ihres Primärschlüssels (z. B. reguläre Sequenzen oder Zeitstempel) ist die häufigste Ursache für Hotspots.

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 zum Sortieren der Tabellenzeilen. Da Spanner stark verteilt ist, können Sie die folgenden Techniken verwenden, um eindeutige Primärschlüsselwerte zu generieren und das Risiko von Hotspots zu reduzieren:

  • Verwenden Sie eine automatisch generierte Schlüsselfunktion, die Hotspots sicher macht, die von Spanner unterstützt wird. Weitere Informationen finden Sie unter Automatisch generierte Schlüssel migrieren:
    • Verwenden Sie die Funktion GENERATE_UUID() (GoogleSQL, PostgreSQL), um universell eindeutige Kennzeichnungswerte (UUID-Version 4) mit dem Datentyp STRING(36) zu generieren. RFC 4122 definiert das UUID-Format Version 4.
    • Verwenden Sie eine bitumgekehrte positive Sequenz (GoogleSQL, PostgreSQL). Eine solche Sequenz erzeugt positive Werte mit Bits höherer Ordnung, die bereits umgekehrt wurden, sodass sie gleichmäßig über den positiven 64-Bit-Zahlenbereich 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. Erstellen Sie dazu eine Spalte, die den Hash des eindeutigen Schlüssels enthält, und verwenden Sie 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 der 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.

Das folgende Beispiel zeigt 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 die Strategien und Beispiele für die folgenden Szenarien beschrieben, in denen die Quelltabelle bereits ein automatisch generiertes Schlüsselfeature verwendet:

  • Migration von einer Quelltabelle, die einen UUID-Primärschlüssel verwendet
  • Migration von einer Quelltabelle, die einen sequenziellen, automatisch generierten Ganzzahlschlüssel verwendet Beispiele hierfür sind unter anderem Sequenzen (die von verschiedenen Datenbanken unterstützt werden), IDENTITY-Spalten (die von verschiedenen Datenbanken unterstützt werden), PostgreSQL-SERIAL-Datentypen 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 anhand der Anleitung zu Bitumkehrungen für sequentielle Werte erstellen.

Beachten Sie, dass Spanner bei allen Strategien keine Daten ändert, die aus einer Quelldatenbank migriert werden. Sie ändern lediglich die Methode zum Generieren neuer Daten.

Spalten mit UUID-Schlüssel 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 kleinschreiben und die GENERATE_UUID()-Funktion (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 Ihr Quelldatenbanksystem sequenzielle Werte für eine Schlüsselspalte generiert, können Sie in Ihrem Spanner-Schema eine bitumkehrende positive Sequenz (GoogleSQL, PostgreSQL) verwenden, um Werte zu generieren, die gleichmäßig über den positiven 64-Bit-Ganzzahlbereich verteilt werden. Sie können einen übersprungenen Bereich dafür definieren, um zu verhindern, dass die Spanner-Sequenz einen Wert generiert, der sich mit einem migrierten Wert überschneidet. Beispielsweise können Sie 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;

Bitumkehrte Schlüsselspalten migrieren

Wenn Sie für Ihre Schlüssel/Wert-Paare bereits eine Bitumkehrung vorgenommen haben, um Hotspot-Probleme in der Quelldatenbank zu vermeiden, können Sie auch eine Bit-umkehrende positive Spanner-Sequenz (GoogleSQL, PostgreSQL) verwenden, um diese Werte weiter zu generieren. Damit keine doppelten Werte generiert werden, können Sie die Sequenz so konfigurieren, dass der Zähler mit einer benutzerdefinierten Zahl beginnt.

Wenn Sie beispielsweise Zahlen von 1 in 1.000 umgekehrt haben, um Primärschlüsselwerte zu generieren, kann der Zähler der Spanner-Sequenz bei einer beliebigen Zahl größer als 10.000 beginnen. Optional können Sie eine hohe Anzahl auswählen, um einen Puffer für neue Schreibvorgänge zu lassen, die nach der Datenmigration in der Quelldatenbank erfolgen. 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;