En este documento, se describen estrategias para migrar claves primarias de las tablas de tu base de datos a Cloud Spanner a fin de evitar problemas de generación de hotspots. Un hotspot es una concentración de operaciones en un solo nodo, lo que reduce la capacidad de procesamiento de escritura a la capacidad del nodo, en lugar de beneficiarse del balanceo de cargas de todas las escrituras entre los nodos de Spanner. El uso de columnas que aumentan o disminuyen monótonamente como la primera parte de la clave primaria (por ejemplo, secuencias regulares o marcas de tiempo) es la causa más común de los puntos problemáticos.
Estrategias generales
En Spanner, cada tabla que debe almacenar más de una fila debe tener una clave primaria compuesta por una o más columnas. La clave primaria de la tabla identifica de manera única cada fila de una tabla, y Spanner usa la clave primaria para ordenar las filas de la tabla. Debido a que Spanner está altamente distribuido, puedes usar las siguientes técnicas para generar valores de clave primaria únicos y reducir el riesgo de tener puntos problemáticos:
- Usa una función de clave generada automáticamente y a prueba de hotspots compatible con Spanner (más detalles se describen en la sección Migra claves generadas de forma automática):
- Usa la función
GENERATE_UUID()
(GoogleSQL, PostgreSQL) para generar valores de identificador único universal (UUID versión 4) con el tipo de datosSTRING(36)
. RFC 4122 define el formato de la versión 4 del UUID. - Usar una secuencia positiva invertida de bits (GoogleSQL, PostgreSQL) Esta secuencia genera valores positivos con bits de orden superior ya invertidos, de modo que se distribuyen de manera uniforme en el espacio positivo de los números de 64 bits.
- Usa la función
- Cambia el orden de las claves para que la columna que contiene el valor monótonamente creciente o decreciente no sea la primera parte de la clave.
- Genera un hash de la clave única y distribuye las escrituras entre fragmentos lógicos; para ello, crea una columna que contenga el hash de la clave única y, luego, usa la columna de hash (o la columna de hash más la columna de la clave única) como clave primaria. Este enfoque ayuda a evitar los puntos problemáticos porque las filas nuevas se distribuyen de manera más uniforme en el espacio de claves.
Una vez que designes tu clave primaria para la tabla, no podrás cambiarla sin borrar y volver a crear la tabla. Para obtener más información sobre cómo designar la clave primaria, consulta Esquema y modelo de datos: Claves primarias.
A continuación, se incluye un ejemplo de instrucción DDL que crea una tabla para una base de datos de pistas de música:
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) );
Migra claves generadas automáticamente
En esta sección, se describen las estrategias y los ejemplos para las siguientes situaciones en las que la tabla de origen ya usa una función de clave generada de forma automática:
- Migra desde una tabla de origen que usa una clave primaria de UUID.
- Migra desde una tabla de origen que usa una clave de número entero secuencial generada de forma automática. Los ejemplos incluyen, entre otros, secuencias (compatibles con varias bases de datos), columnas
IDENTITY
(que admiten varias bases de datos), tipos de datosSERIAL
de PostgreSQL y el atributo de columnaAUTO_INCREMENT
de MySQL. - Migra desde una tabla de origen que usa una clave invertida de bits. Quizás la base de datos de origen sea Cloud Spanner, en la que creas valores clave mediante la guía revertir los bits de los valores secuenciales.
Es importante tener en cuenta que, en todas las estrategias, Spanner no modifica los datos que migra desde una base de datos de origen. Solo estás cambiando el método para generar datos nuevos.
Migra las columnas de claves de UUID
Si tu tabla de origen usa una columna de UUID, puedes convertir la columna al tipo STRING, escribir los valores en minúsculas según la especificación RFC 4122 y usar la función GENERATE_UUID() (GoogleSQL, PostgreSQL) como el valor predeterminado de la columna. Por ejemplo:
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) );
Migra las columnas de claves secuenciales
Si el sistema de base de datos de origen genera valores secuenciales para una columna de clave, puedes usar una secuencia positiva invertida de bits (GoogleSQL, PostgreSQL) en tu esquema de Cloud Spanner a fin de generar valores que se distribuyan de manera uniforme en el espacio de números enteros positivos de 64 bits. Para evitar que la secuencia de Cloud Spanner genere un valor que se superponga con un valor migrado, puedes definir un rango omitido para ella. Por ejemplo, puedes omitir el rango de 1 a 4,294,967,296 (2^32 TODO: format) para las siguientes dos secuencias, si sabes que la base de datos de origen solo genera números enteros de 32 bits:
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;
Migra las columnas de claves con inversión de bits
Si ya invertiste bits de tus valores clave para evitar problemas de hotspots en tu base de datos de origen, también puedes usar una secuencia positiva invertida de bits de Cloud Spanner (GoogleSQL, PostgreSQL) para seguir generando esos valores. A fin de evitar generar valores duplicados, puedes configurar la secuencia para iniciar su contador desde un número personalizado.
Por ejemplo, si invertiste los números del 1 al 1,000 para generar valores de clave primaria, la secuencia de Cloud Spanner puede iniciar su contador desde cualquier número superior a 10,000. De manera opcional, puedes elegir un número alto para dejar un búfer para las nuevas operaciones de escritura que se produzcan en la base de datos de origen después de la migración de datos. En el siguiente ejemplo, los contadores comienzan en 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;