Saat bisnis berkembang, kinerja dan kapasitas tabel tunggal dapat menjadi hambatan. Solusi tradisional adalah skalabilitas vertikal (Scale Up), yang melibatkan peningkatan perangkat keras server tunggal. Namun, pendekatan ini cepat mencapai batasnya dalam hal efektivitas biaya dan kapasitas fisik. Skalabilitas horizontal (Scale Out) menawarkan solusi yang lebih dapat diskalakan dengan mendistribusikan data ke beberapa server. Kluster PolarDB for PostgreSQL (Distributed) menggunakan skalabilitas horizontal dan memperkenalkan dua jenis tabel khusus untuk mengelola distribusi data: tabel terdistribusi untuk set data besar dan tabel replikasi untuk set data kecil yang sering di-JOIN. Topik ini memandu Anda dalam membuat dan mengelola kedua jenis tabel tersebut.
Membuat tabel terdistribusi
Membuat tabel terdistribusi merupakan langkah inti dalam pemisahan data secara horizontal. Tabel ini cocok untuk tabel bisnis yang menyimpan sejumlah besar data, seperti tabel pengguna dan tabel detail pesanan. Proses ini terdiri dari dua langkah: pertama, buat tabel standar; kemudian, konversikan menjadi tabel terdistribusi menggunakan fungsi create_distributed_table.
1. Pilih kolom distribusi
Kolom distribusi adalah kunci untuk menentukan bagaimana data didistribusikan ke berbagai node data (DN). Sistem menggunakan nilai hash dari kolom yang ditentukan untuk mengarahkan baris data.
Prinsip pemilihan: Pilih kunci utama tabel atau pengidentifikasi unik sebagai kolom distribusi agar data terdistribusi secara merata.
Batasan penting: Jika tabel memiliki kunci utama atau kendala UNIK, kolom distribusi harus merupakan salah satu kolom yang membentuk kendala tersebut.
Contoh: Konversi tabel standar t menjadi tabel terdistribusi dengan menggunakan kolom id sebagai kolom distribusi.
Buat tabel standar bernama
t.CREATE TABLE t (id int primary key, data text);Konversi menjadi tabel terdistribusi dan gunakan kolom
idsebagai kolom distribusi.SELECT create_distributed_table('t', 'id');Hasil berikut dikembalikan:
create_distributed_table -------------------------- (1 row)
2. (Opsional) Tentukan jumlah shard
Shard adalah unit penyimpanan fisik dari tabel terdistribusi. Secara default, setiap tabel terdistribusi dibuat dengan 32 shard. Anda dapat secara eksplisit menentukan jumlah shard saat membuat tabel atau mengaturnya secara global menggunakan parameter polar_cluster.shard_count.
Contoh: Buat tabel terdistribusi dengan empat shard.
Buat tabel standar bernama
t1.CREATE TABLE t1 (id int primary key, data text);Tentukan secara eksplisit jumlah shard.
Menggunakan parameter
shard_countTentukan jumlah shard selama konversi menggunakan parameter
shard_count.SELECT create_distributed_table('t1', 'id', shard_count := 4);Hasil berikut dikembalikan:
create_distributed_table -------------------------- (1 row)Kueri jumlah shard.
SELECT * FROM pg_dist_shard WHERE logicalrelid = 't1'::regclass;Hasil berikut dikembalikan:
logicalrelid | shardid | shardstorage | shardminvalue | shardmaxvalue --------------+---------+--------------+---------------+--------------- t1 | 102072 | t | -2147483648 | -1073741825 t1 | 102073 | t | -1073741824 | -1 t1 | 102074 | t | 0 | 1073741823 t1 | 102075 | t | 1073741824 | 2147483647 (4 rows)
Menggunakan parameter
polar_cluster.shard_countAtur jumlah shard secara global menggunakan parameter
polar_cluster.shard_count.SET polar_cluster.shard_count TO 4;Konversi tabel menjadi tabel terdistribusi.
SELECT create_distributed_table('t1', 'id');Hasil berikut dikembalikan:
create_distributed_table -------------------------- (1 row)Kueri jumlah shard.
SELECT * FROM pg_dist_shard WHERE logicalrelid = 't1'::regclass;Hasil berikut dikembalikan:
logicalrelid | shardid | shardstorage | shardminvalue | shardmaxvalue --------------+---------+--------------+---------------+--------------- t1 | 102072 | t | -2147483648 | -1073741825 t1 | 102073 | t | -1073741824 | -1 t1 | 102074 | t | 0 | 1073741823 t1 | 102075 | t | 1073741824 | 2147483647 (4 rows)
3. (Opsional) Gunakan grup colocation untuk mengoptimalkan kinerja JOIN
Dalam banyak aplikasi bisnis, informasi tentang satu entitas sering kali disimpan di beberapa tabel. Diperlukan kueri JOIN untuk mengambil semua informasi terkait. Misalnya, tabel user_info menyimpan semua data pengguna, dan tabel user_order menyimpan semua pesanan pengguna. Kedua tabel ini perlu di-JOIN berdasarkan user_id.
Dalam database terdistribusi, jika data dalam tabel-tabel ini didistribusikan ke node yang berbeda, kueri join akan memicu transfer data lintas node, sehingga menimbulkan overhead tinggi. Untuk mengatasi masalah ini, PolarDB for PostgreSQL (Distributed) memperkenalkan konsep grup colocation.
Fungsi: Memastikan bahwa baris-baris dengan nilai kunci distribusi yang sama dari beberapa tabel disimpan secara fisik pada node data yang sama. Misalnya, semua catatan terkait dengan
user_idbernilai 1001 disimpan bersama. Hal ini memungkinkan operasiJOINpada kunci distribusi dilakukan secara efisien pada satu node, memberikan kinerja yang setara dengan kueri lokal.Cara penggunaan: PolarDB for PostgreSQL (Distributed) menyediakan dua cara untuk mengelola grup colocation: implisit (perilaku default) dan eksplisit (metode yang direkomendasikan).
Colocation default (perilaku implisit): Saat Anda membuat tabel terdistribusi tanpa menentukan parameter
colocate_with, sistem secara otomatis menempatkannya ke dalam grup colocation default. Pengelompokan ini didasarkan pada dua properti:tipe kolom distribusidanjumlah shard. Artinya, tabel-tabel dengan tipe kolom distribusi dan jumlah shard yang sama dianggap collocated secara default.CatatanColocation default (perilaku implisit): Bahkan jika dua tabel terdistribusi memiliki tipe data kolom distribusi dan jumlah shard yang sama, datanya belum tentu saling terkait.
Kontrol eksplisit (metode yang direkomendasikan): Perilaku default dapat menyebabkan tabel bisnis yang tidak terkait dikelompokkan secara salah. Untuk mengontrol colocation tabel secara tepat, Anda dapat mendeklarasikan hubungan tersebut secara eksplisit:
Saat membuat tabel pertama dalam grup colocation, atur
colocate_with := 'none'dalam fungsicreate_distributed_table. Hal ini membuat grup colocation baru dan independen untuk tabel tersebut.Saat membuat tabel berikutnya yang perlu dicolocation, atur
colocate_with := 'first_table_name'untuk menambahkannya ke grup colocation yang sudah ada.
Contoh: Tempatkan tabel pengguna dan pesanan dalam satu grup colocation, dan tabel terkait hewan dalam grup lainnya.
Buat tabel terkait pengguna dan pesanan serta tempatkan dalam grup colocation yang sama.
-- Buat grup colocation baru CREATE TABLE user_info (user_id int, user_data text); SELECT create_distributed_table('user_info', 'user_id', colocate_with := 'none'); -- Tambahkan ke grup colocation yang sudah ada CREATE TABLE user_order (user_id int, order_id int, order_data text); SELECT create_distributed_table('user_order', 'user_id', colocate_with := 'user_info');Buat tabel terkait hewan dan tempatkan dalam grup colocation lainnya.
-- Buat grup colocation baru CREATE TABLE animal (animal_id int, animal_data text); SELECT create_distributed_table('animal', 'animal_id', colocate_with := 'none'); -- Tambahkan ke grup colocation yang sudah ada CREATE TABLE animal_class (animal_id int, class_id int, class_data text); SELECT create_distributed_table('animal_class', 'animal_id', colocate_with := 'animal');Verifikasi bahwa kedua kelompok tabel terdistribusi memiliki ID colocation yang berbeda. Hal ini mengonfirmasi bahwa mereka telah ditambahkan ke grup colocation yang terpisah.
SELECT table_name, colocation_id, polar_cluster_table_type, distribution_column, shard_count FROM polar_cluster_tables WHERE table_name IN ( 'user_info'::regclass, 'user_order'::regclass, 'animal'::regclass, 'animal_class'::regclass) ORDER BY colocation_id;Hasil berikut dikembalikan:
table_name | colocation_id | polar_cluster_table_type | distribution_column | shard_count --------------+---------------+--------------------------+---------------------+------------- user_info | 3 | distributed | user_id | 4 user_order | 3 | distributed | user_id | 4 animal | 4 | distributed | animal_id | 4 animal_class | 4 | distributed | animal_id | 4 (4 rows)
Membuat tabel replikasi
Tabel replikasi, juga dikenal sebagai tabel referensi, menyimpan salinan lengkap datanya di setiap node data. Tabel ini cocok untuk menyimpan sejumlah kecil data publik atau tabel dimensi yang sering di-JOIN dengan tabel terdistribusi, seperti kode negara dan kategori produk.
Keuntungan: Menghindari kueri lintas node dan mempercepat operasi join.
Biaya: Operasi tulis disinkronkan ke semua node, sehingga menimbulkan overhead tinggi. Oleh karena itu, tabel replikasi tidak cocok untuk data yang sering berubah.
Contoh: Buat tabel replikasi.
Buat tabel standar bernama
t_reference.CREATE TABLE t_reference (id int primary key, data text);Konversi menjadi tabel replikasi. Anda hanya perlu menentukan nama tabel untuk operasi ini.
SELECT create_reference_table('t_reference');Hasil berikut dikembalikan:
create_reference_table ------------------------ (1 row)Kueri informasi tabel replikasi. Keluaran menunjukkan bahwa tabel replikasi memiliki shard dengan nama yang sama di setiap node:
SELECT table_name, polar_cluster_table_type, distribution_column, shard_count FROM polar_cluster_tables WHERE table_name = 't_reference'::regclass;Hasil berikut dikembalikan:
table_name | polar_cluster_table_type | distribution_column | shard_count -------------+--------------------------+---------------------+------------- t_reference | reference | <none> | 1 (1 row)SELECT table_name, shardid, nodename, nodeport FROM polar_cluster_shards WHERE table_name = 't_reference'::regclass;Hasil berikut dikembalikan:
table_name | shardid | nodename | nodeport -------------+---------+----------------+---------- t_reference | 102096 | 10.xxx.xxx.xxx | 3007 t_reference | 102096 | 10.xxx.xxx.xxx | 3020 t_reference | 102096 | 10.xxx.xxx.xxx | 3006 t_reference | 102096 | 10.xxx.xxx.xxx | 3003 (4 rows)
Mengelola tabel terdistribusi
Konversi tabel terdistribusi kembali menjadi tabel standar
Jika Anda tidak lagi memerlukan fitur terdistribusi, Anda dapat menggunakan fungsi undistribute_table untuk mengonversi tabel terdistribusi atau replikasi kembali menjadi tabel standar. Data secara otomatis dikumpulkan dari semua shard dan dipindahkan ke node koordinator utama (CN).
Contoh: Konversi tabel terdistribusi t kembali menjadi tabel standar.
SELECT undistribute_table('t');Hasil berikut dikembalikan:
NOTICE: creating a new table for public.t
NOTICE: moving the data of public.t
NOTICE: dropping the old public.t
NOTICE: renaming the new table to public.t
undistribute_table
--------------------
(1 row)Operasi DDL lainnya
Untuk tabel terdistribusi yang sudah ada, Anda dapat melakukan operasi Data Definition Language (DDL) lainnya seperti pada tabel PostgreSQL standar. Operasi-operasi ini secara otomatis disebarkan ke semua shard fisik untuk menjaga konsistensi struktur tabel logis dan fisik.
Hapus tabel:
DROP TABLE table_name;Buat indeks:
CREATE INDEX index_name ON table_name (column_name);