All Products
Search
Document Center

ApsaraDB RDS:Pemisahan horizontal (PL/Proxy)

Last Updated:Mar 29, 2026

PL/Proxy adalah ekstensi PostgreSQL yang mengarahkan panggilan SQL dari node proxy ke database remote. Di ApsaraDB RDS for PostgreSQL, ekstensi ini dapat digunakan dalam mode CLUSTER untuk mendistribusikan operasi tulis ke beberapa shard atau mereplikasi data di berbagai node, serta dalam mode CONNECT untuk mengarahkan kueri ke database tertentu.

Prasyarat

Sebelum memulai, pastikan Anda telah memiliki:

Cara kerja

PL/Proxy berjalan pada node proxy khusus. Ketika klien memanggil fungsi PL/Proxy, PL/Proxy mencegat panggilan tersebut dan meneruskannya ke satu atau beberapa node data berdasarkan aturan routing yang tertanam dalam isi fungsi.

Mode CLUSTER mengelompokkan node data ke dalam kluster bernama menggunakan pernyataan SQL/MED CREATE SERVER. Setiap fungsi proxy menentukan klausa RUN ON yang mengatur cara panggilan diarahkan:

KlausaPerilaku routing
RUN ON ANYMengirim panggilan ke node data yang dipilih secara acak
RUN ON ALLMenyiarkan panggilan ke semua node data (gunakan untuk replikasi SQL atau pembacaan lintas shard)

Mode CONNECT melewati konfigurasi kluster. Setiap fungsi menyematkan string koneksi secara langsung dan mengarahkan kueri ke database target tetap.

Catatan penggunaan

  • Instans RDS dalam virtual private cloud (VPC) yang sama dapat saling mengakses secara langsung.

  • Untuk mengarahkan kueri antar instans RDS di VPC berbeda, tempatkan instans Elastic Compute Service (ECS) di VPC yang sama sebagai proxy perantara.

  • Jumlah node data dalam CLUSTER harus merupakan pangkat dari 2 (2, 4, 8, dan seterusnya).

Instal ekstensi

Hubungkan ke database node proxy dan jalankan:

CREATE EXTENSION plproxy;

Siapkan CLUSTER (hanya untuk mode CLUSTER)

Lewati bagian ini jika Anda menggunakan mode CONNECT.

Kluster didefinisikan dengan CREATE SERVER. Setiap node data didaftarkan sebagai opsi (p0, p1, dan seterusnya). Jumlah opsi harus merupakan pangkat dari 2.

  1. Buat server kluster dan daftarkan node data Anda:

    CREATE SERVER cluster_srv1 FOREIGN DATA WRAPPER plproxy
    OPTIONS (
        connection_lifetime '1800',
        disable_binary '1',
        p0 'dbname=pl_db0 host=100.xxx.xxx.72 port=5678',
        p1 'dbname=pl_db1 host=11.xxx.xxx.9 port=5678'
    );
  2. Berikan akses ke kluster:

    GRANT USAGE ON FOREIGN SERVER cluster_srv1 TO postgres;
  3. Buat pemetaan pengguna agar PL/Proxy dapat melakukan autentikasi ke node data:

    CREATE USER MAPPING FOR postgres SERVER cluster_srv1 OPTIONS (user 'postgres');

Uji coba pengaturan

Bagian berikut menggunakan tiga instans RDS untuk mendemonstrasikan kedua mode.

IPPeranDatabaseUsername
100.xx.xx.136Node proxypostgrespostgres
100.xx.xx.72Node datapl_db0postgres
11.xx.xx.9Node datapl_db1postgres

Buat tabel users di setiap node data:

CREATE TABLE users (userid int, name text);

Uji coba mode CLUSTER

Sharding horizontal

RUN ON ANY mengarahkan setiap perintah INSERT secara acak ke salah satu node data, sehingga mendistribusikan operasi tulis di seluruh kluster.

  1. Buat fungsi insert_user di setiap node data:

    CREATE OR REPLACE FUNCTION insert_user(i_id int, i_name text)
    RETURNS integer AS $$
        INSERT INTO users (userid, name) VALUES ($1, $2);
        SELECT 1;
    $$ LANGUAGE SQL;
  2. Buat fungsi proxy di node proxy. PL/Proxy mencocokkan panggilan berdasarkan nama fungsi, sehingga fungsi proxy dan fungsi di node data harus memiliki nama yang sama.

    CREATE OR REPLACE FUNCTION insert_user(i_id int, i_name text)
    RETURNS integer AS $$
        CLUSTER 'cluster_srv1';
        RUN ON ANY;
    $$ LANGUAGE plproxy;
  3. Buat fungsi baca di node proxy. RUN ON ALL mengkueri setiap node data dan menggabungkan hasilnya.

    CREATE OR REPLACE FUNCTION get_user_name()
    RETURNS TABLE(userid int, name text) AS $$
        CLUSTER 'cluster_srv1';
        RUN ON ALL;
        SELECT userid, name FROM users;
    $$ LANGUAGE plproxy;
  4. Masukkan 10 catatan dari node proxy:

    SELECT insert_user(1001, 'Sven');
    SELECT insert_user(1002, 'Marko');
    SELECT insert_user(1003, 'Steve');
    SELECT insert_user(1004, 'lottu');
    SELECT insert_user(1005, 'rax');
    SELECT insert_user(1006, 'ak');
    SELECT insert_user(1007, 'jack');
    SELECT insert_user(1008, 'molica');
    SELECT insert_user(1009, 'pg');
    SELECT insert_user(1010, 'oracle');
  5. Kueri setiap node data untuk melihat bagaimana data didistribusikan:

    RUN ON ANY mengarahkan operasi tulis secara acak, sehingga distribusinya tidak merata.
    -- Di pl_db0
    SELECT * FROM users;
     userid |  name
    --------+--------
       1001 | Sven
       1003 | Steve
       1004 | lottu
       1005 | rax
       1006 | ak
       1007 | jack
       1008 | molica
       1009 | pg
    (8 baris)
    
    -- Di pl_db1
    SELECT * FROM users;
     userid |  name
    --------+--------
       1002 | Marko
       1010 | oracle
    (2 baris)
  6. Baca kembali semua baris melalui node proxy:

    SELECT userid, name FROM get_user_name();
     userid |  name
    --------+--------
       1001 | Sven
       1003 | Steve
       1004 | lottu
       1005 | rax
       1006 | ak
       1007 | jack
       1008 | molica
       1009 | pg
       1002 | Marko
       1010 | oracle
    (10 baris)

Replikasi SQL

RUN ON ALL menyiarkan setiap operasi tulis ke semua node data, sehingga menjaga semua node tetap sinkron.

  1. Buat fungsi trunc_user di setiap node data dan di node proxy:

    -- Di pl_db0 dan pl_db1
    CREATE OR REPLACE FUNCTION trunc_user()
    RETURNS integer AS $$
        TRUNCATE TABLE users;
        SELECT 1;
    $$ LANGUAGE SQL;
    
    -- Di node proxy
    CREATE OR REPLACE FUNCTION trunc_user()
    RETURNS SETOF integer AS $$
        CLUSTER 'cluster_srv1';
        RUN ON ALL;
    $$ LANGUAGE plproxy;
  2. Truncate tabel di semua node:

    SELECT trunc_user();
     trunc_user
    ------------
              1
              1
    (2 baris)
  3. Buat fungsi insert replikasi di node proxy. TARGET insert_user memberi tahu PL/Proxy untuk memanggil fungsi insert_user (yang sudah didefinisikan di node data) di setiap node:

    CREATE OR REPLACE FUNCTION insert_user_2(i_id int, i_name text)
    RETURNS SETOF integer AS $$
        CLUSTER 'cluster_srv1';
        RUN ON ALL;
        TARGET insert_user;
    $$ LANGUAGE plproxy;
  4. Masukkan 4 catatan:

    SELECT insert_user_2(1004, 'lottu');
    SELECT insert_user_2(1005, 'rax');
    SELECT insert_user_2(1006, 'ak');
    SELECT insert_user_2(1007, 'jack');
  5. Verifikasi bahwa kedua node data berisi data yang identik:

    -- Di pl_db0
    SELECT * FROM users;
     userid | name
    --------+-------
       1004 | lottu
       1005 | rax
       1006 | ak
       1007 | jack
    (4 baris)
    
    -- Di pl_db1
    SELECT * FROM users;
     userid | name
    --------+-------
       1004 | lottu
       1005 | rax
       1006 | ak
       1007 | jack
    (4 baris)
  6. Baca melalui node proxy menggunakan RUN ON ANY — karena semua node menyimpan data yang identik, node mana pun akan mengembalikan hasil lengkap:

    CREATE OR REPLACE FUNCTION get_user_name_2()
    RETURNS TABLE(userid int, name text) AS $$
        CLUSTER 'cluster_srv1';
        RUN ON ANY;
        SELECT userid, name FROM users;
    $$ LANGUAGE plproxy;
    
    SELECT userid, name FROM get_user_name_2();
     userid | name
    --------+-------
       1004 | lottu
       1005 | rax
       1006 | ak
       1007 | jack
    (4 baris)

Uji coba mode CONNECT

Mode CONNECT mengarahkan kueri ke satu database tertentu tanpa memerlukan pengaturan kluster. Sematkan string koneksi langsung di dalam fungsi.

CREATE OR REPLACE FUNCTION get_user_name_3()
RETURNS TABLE(userid int, name text) AS $$
    CONNECT 'dbname=pl_db0 host=100.81.137.72 port=56789';
    SELECT userid, name FROM users;
$$ LANGUAGE plproxy;

SELECT userid, name FROM get_user_name_3();
 userid | name
--------+-------
   1004 | lottu
   1005 | rax
   1006 | ak
   1007 | jack
(4 baris)

Pilih mode

Mode CLUSTERMode CONNECT
Gunakan saatAnda membutuhkan sharding horizontal atau ingin mereplikasi operasi tulis di berbagai nodeAnda perlu mengkueri database remote tertentu berdasarkan string koneksi
Diperlukan pengaturan klusterYa (CREATE SERVER, pemetaan pengguna)Tidak
Batasan jumlah node dataHarus merupakan pangkat dari 2Tidak ada
RoutingRUN ON ANY (acak) atau RUN ON ALL (siaran)String koneksi tetap per fungsi
Kasus penggunaan umumDistribusi dataset besar di beberapa instans RDSKueri lintas instans atau federasi ad-hoc

Langkah selanjutnya