Questo documento descrive le strategie per la migrazione delle chiavi primarie dal database a Spanner per evitare problemi di hotspot. Un hotspot è un delle operazioni su un singolo nodo, con conseguente riduzione della velocità effettiva di scrittura alla capacità del nodo invece di trarre vantaggio dal bilanciamento del carico di tutte le scritture tra i nodi Spanner. L'uso dell'aumento monotonico colonne decrescenti come prima parte della chiave primaria (esempi includono: sequenze regolari o timestamp) è la causa più comune di "hot spot".
Strategie generali
In Spanner, ogni tabella che deve archiviare più di una riga deve Avere una chiave primaria composta da una o più colonne della tabella. La tabella la chiave primaria identifica in modo univoco ogni riga di una tabella e Spanner utilizza la chiave primaria per ordinare le righe della tabella. Poiché Spanner è altamente distribuita, puoi utilizzare le seguenti tecniche per generare e ridurre il rischio di hotspot:
- Usa una funzionalità chiave generata automaticamente a prova di hotspot che Spanner
(maggiori dettagli sono descritti nella sezione Eseguire la migrazione dei dati generati automaticamente
chiavi):
- Usa la funzione
GENERATE_UUID()
(GoogleSQL, PostgreSQL) per generare valori di identificatori univoci universalmente (UUID versione 4) con il tipo di datiSTRING(36)
. RFC 4122 definisce il formato UUID versione 4. - Usa una sequenza positiva invertita con il bit (GoogleSQL, PostgreSQL). Una tale sequenza genera valori positivi già con bit di ordine elevato invertiti, di modo che vengano distribuiti uniformemente tra i componenti uno spazio numerico.
- Usa la funzione
- Scambiare l'ordine delle chiavi in modo che la colonna che contiene l'aumento o la diminuzione monotonica non è la prima parte della chiave.
- Eseguire l'hashing della chiave univoca e distribuire le scritture tra gli shard logici creando una colonna che contiene l'hash della chiave univoca e utilizzando la colonna hash (o la colonna hash e le colonne chiave univoche) insieme) come chiave primaria. Questo approccio consente di evitare punti critici perché le nuove righe vengono distribuite in modo più uniforme nello spazio delle chiavi.
Dopo aver designato la chiave primaria per la tabella, non puoi modificarla in un secondo momento senza eliminare e ricreare la tabella. Per ulteriori informazioni su come designare la chiave primaria, consulta Schema e modello dei dati - chiavi primarie.
Di seguito è riportato un esempio di istruzione DDL che crea una tabella per un database di musica tracce:
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) );
Esegui la migrazione delle chiavi generate automaticamente
Questa sezione descrive le strategie e gli esempi per i seguenti scenari in cui la tabella di origine utilizza già una funzionalità chiave generata automaticamente:
- Migrazione da una tabella di origine che utilizza una chiave primaria UUID.
- Migrazione da una tabella di origine che utilizza un numero intero sequenziale generato automaticamente
chiave. Tra gli esempi ci sono, a titolo esemplificativo, le sequenze (che diverse
database supportati),
IDENTITY
colonne (supportate da vari database), Tipi di dati PostgreSQLSERIAL
e la colonna MySQLAUTO_INCREMENT
. - Migrazione da una tabella di origine che utilizza una chiave invertita di bit. Forse la fonte è Spanner, per creare le coppie chiave-valore usando la guida valori sequenziali invertiti a bit.
In tutte le strategie, è importante notare che Spanner e modificare i dati sottoposti a migrazione da un database di origine. Stai cambiando solo il metodo per generare nuovi dati.
Esegui la migrazione delle colonne delle chiavi UUID
Se la tabella di origine utilizza una colonna UUID, puoi convertirla in
STRING, imposta i valori in minuscolo per
RFC 4122 e utilizza il
GENERATE_UUID()
(GoogleSQL,
PostgreSQL) come valore predefinito della colonna. Per
esempio:
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) );
Esegui la migrazione delle colonne delle chiavi sequenziali
Se il sistema del database di origine genera valori sequenziali per una colonna chiave, puoi usare una sequenza positiva invertita di più (GoogleSQL, PostgreSQL). nello schema Spanner per generare valori che distribuiscono uniformemente tra lo spazio numerico positivo a 64 bit. Per impedire che Spanner dalla generazione di un valore che si sovrappone a un valore migrato, puoi e definire un intervallo ignorato. Ad esempio, puoi ignorare compreso tra 1 e 4.294.967.296 (2^32) per i due sequenze, se sai che il database di origine genera solo numeri interi a 32 bit:
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;
Esegui la migrazione delle colonne delle chiavi con invertito del bit
Se hai già invertito leggermente le coppie chiave per evitare problemi di hotspot nelle del database di origine, puoi anche usare un valore positivo di Spanner invertito sequenza (GoogleSQL, PostgreSQL). per continuare a generare questi valori. Per evitare di generare valori duplicati, può configurare la sequenza in modo che inizi il contatore da un numero personalizzato.
Ad esempio, se hai invertito i numeri da 1 a 1000 per generare una chiave primaria di valori, la sequenza di Spanner può iniziare il suo contatore da qualsiasi numero maggiore di 10.000. Facoltativamente, puoi scegliere un numero lascia un buffer per le nuove scritture che avvengono nel database di origine migrazione. Nell'esempio seguente, i contatori iniziano da 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;