Memigrasikan strategi kunci utama

Dokumen ini menjelaskan strategi untuk memigrasikan kunci utama dari tabel database Anda ke Spanner untuk menghindari masalah hotspot. Hotspot adalah konsentrasi operasi pada satu node, yang menurunkan throughput operasi tulis ke kapasitas node, bukan mengambil keuntungan dari load balancing pada semua penulisan di antara node Spanner. Penggunaan kolom yang meningkat atau menurun secara monoton sebagai bagian pertama dari kunci utama Anda (contohnya termasuk urutan atau stempel waktu reguler) adalah penyebab paling umum hot spot.

Strategi keseluruhan

Di Spanner, setiap tabel yang harus menyimpan lebih dari satu baris harus memiliki kunci utama yang terdiri dari satu atau beberapa kolom tabel. Kunci utama tabel Anda secara unik mengidentifikasi setiap baris dalam tabel, dan Spanner menggunakan kunci utama untuk mengurutkan baris tabel. Karena Spanner sangat terdistribusi, Anda dapat menggunakan teknik berikut untuk membuat nilai kunci utama yang unik dan mengurangi risiko hot spot:

  • Gunakan fitur kunci yang dibuat secara otomatis dan tahan hotspot yang didukung Spanner (detail selengkapnya dijelaskan di bagian Memigrasikan kunci yang dibuat otomatis):
    • Gunakan fungsi GENERATE_UUID() (GoogleSQL, PostgreSQL) untuk menghasilkan nilai ID unik universal (UUID Versi 4) dengan jenis data STRING(36). RFC 4122 menentukan format UUID Versi 4.
    • Gunakan urutan positif terbalik bit (GoogleSQL, PostgreSQL). Urutan tersebut menghasilkan nilai positif dengan bit urutan tinggi yang sudah dibalik, sehingga didistribusikan secara merata di seluruh ruang angka 64-bit positif.
  • Tukar urutan kunci sehingga kolom yang berisi nilai yang meningkat atau menurun secara monoton bukan bagian kunci pertama.
  • Melakukan hashing pada kunci unik dan menyebarkan operasi tulis ke seluruh shard logis dengan membuat kolom yang berisi hash kunci unik, lalu menggunakan kolom hash tersebut (atau kolom hash dan kolom kunci unik secara bersamaan) sebagai kunci utama. Pendekatan ini membantu menghindari hot spot karena baris baru didistribusikan secara lebih merata di seluruh keyspace.

Setelah menentukan kunci utama untuk tabel, Anda tidak dapat mengubahnya nanti tanpa menghapus dan membuat ulang tabel. Untuk informasi selengkapnya tentang cara menentukan kunci utama, lihat Skema dan model data - kunci utama.

Berikut adalah contoh pernyataan DDL yang membuat tabel untuk database trek musik:

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)
);

Migrasikan kunci yang dibuat secara otomatis

Bagian ini menjelaskan strategi dan contoh untuk skenario berikut ketika tabel sumber sudah menggunakan fitur utama yang dibuat secara otomatis:

  • Bermigrasi dari tabel sumber yang menggunakan kunci utama UUID.
  • Bermigrasi dari tabel sumber yang menggunakan kunci bilangan bulat yang dibuat secara otomatis dan berurutan. Contohnya mencakup, tetapi tidak terbatas pada, urutan (yang didukung oleh berbagai database), kolom IDENTITY (yang didukung oleh berbagai database), jenis data SERIAL PostgreSQL, dan atribut kolom AUTO_INCREMENT MySQL.
  • Bermigrasi dari tabel sumber yang menggunakan kunci bit balik. Mungkin database sumbernya adalah Spanner, tempat Anda membuat nilai kunci menggunakan panduan nilai berurutan bit-reverse.

Penting untuk diperhatikan bahwa di semua strategi, Spanner tidak mengubah data yang dimigrasikan dari database sumber. Anda hanya mengubah metode untuk menghasilkan data baru.

Memigrasikan kolom kunci UUID

Jika tabel sumber menggunakan kolom UUID, Anda dapat mengonversi kolom menjadi jenis STRING, membuat nilai huruf kecil sesuai spesifikasi RFC 4122, dan menggunakan fungsi GENERATE_UUID() (GoogleSQL, PostgreSQL) sebagai nilai default kolom. Misalnya:

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)
);

Memigrasikan kolom kunci berurutan

Jika sistem database sumber menghasilkan nilai berurutan untuk kolom kunci, Anda dapat menggunakan urutan positif bit-reversed (GoogleSQL, PostgreSQL) dalam skema Spanner untuk menghasilkan nilai yang didistribusikan secara merata di seluruh ruang bilangan bulat 64-bit positif. Untuk mencegah urutan Spanner menghasilkan nilai yang tumpang-tindih dengan nilai yang dimigrasikan, Anda dapat menentukan rentang yang dilewati untuk nilai tersebut. Misalnya, Anda dapat melewati rentang dari 1 hingga 4.294.967.296 (2^32) untuk dua urutan berikut, jika Anda tahu database sumber hanya menghasilkan bilangan bulat 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;

Memigrasikan kolom kunci terbalik bit

Jika sudah membalik nilai kunci untuk menghindari masalah hot spot di database sumber, Anda juga dapat menggunakan urutan positif balik bit Spanner (GoogleSQL, PostgreSQL) untuk terus menghasilkan nilai tersebut. Untuk menghindari pembuatan nilai duplikat, Anda dapat mengonfigurasi urutan untuk memulai penghitungnya dari angka kustom.

Misalnya, jika Anda membalik angka dari 1 menjadi 1.000 untuk menghasilkan nilai kunci utama, urutan Spanner dapat memulai penghitungnya dari angka yang lebih besar dari 10.000. Jika ingin, Anda dapat memilih angka yang tinggi untuk meninggalkan buffer untuk penulisan baru yang terjadi dalam database sumber setelah migrasi data. Pada contoh berikut, penghitung dimulai dari 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;