Migra estrategias de clave primaria

En este documento, se describen estrategias para migrar claves primarias de tus tablas de bases de datos a 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 tu clave primaria (por ejemplo, secuencias regulares o marcas de tiempo) es la causa más común de los hotspots.

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 de la tabla. La clave primaria de la tabla identifica de manera única cada una de sus filas, 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 hotspots:

  • Usa una función de clave generada de forma automática a prueba de hotspot y compatible con Spanner (se describen más detalles en la sección Cómo migrar claves generadas automáticamente):
    • Usa la función GENERATE_UUID() (GoogleSQL, PostgreSQL) para generar valores de identificadores únicos universales (versión 4 de UUID) con el tipo de datos STRING(36). RFC 4122 define el formato de la versión 4 de UUID.
    • Usa una secuencia positiva inversa de bits (GoogleSQL, PostgreSQL). Esa secuencia genera valores positivos con bits de orden superior ya invertidos, de modo que se distribuyan de manera uniforme en el espacio numérico positivo de 64 bits.
  • 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.

Después de designar 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.

La siguiente es una instrucción de DDL de ejemplo 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)
);

Cómo migrar 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.
  • Migrar 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 (que admiten varias bases de datos), columnas IDENTITY (compatibles con varias bases de datos), tipos de datos SERIAL de PostgreSQL y el atributo de columna AUTO_INCREMENT de MySQL.
  • Migración desde una tabla de origen que usa una clave de inversión de bits. Tal vez la base de datos de origen sea Spanner, donde creas valores clave con la guía de valores secuenciales de reversión de bits.

Es importante tener en cuenta que, en todas las estrategias, Spanner no cambia los datos, sino que migra desde una base de datos de origen. Solo cambiarás el método para generar datos nuevos.

Migra las columnas de claves de UUID

Si la tabla de origen usa una columna UUID, puedes convertir la columna al tipo STRING, poner 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 columnas de claves secuenciales

Si el sistema de la base de datos de origen genera valores secuenciales para una columna de clave, puedes usar una secuencia positiva inversa de bits (GoogleSQL, PostgreSQL) en tu esquema de Spanner para generar valores que se distribuyan de manera uniforme en el espacio numérico positivo de 64 bits. Para evitar que la secuencia de 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) 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 columnas de claves con inversión de bits

Si ya revirtió los bits de los valores clave para evitar problemas de hotspot en tu base de datos de origen, también puedes usar una secuencia positiva inversa de bits de Spanner (GoogleSQL, PostgreSQL) para seguir generando esos valores. Si quieres evitar generar valores duplicados, puedes configurar la secuencia para que inicie su contador desde un número personalizado.

Por ejemplo, si revirtiste números del 1 al 1,000 para generar valores de clave primaria, la secuencia de Spanner puede iniciar su contador desde cualquier número superior a 10,000. De manera opcional, puedes elegir un número alto a fin de dejar un búfer para las nuevas escrituras que se producen 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;