Anda dapat menggunakan libpq atau Java Database Connectivity (JDBC) di PostgreSQL untuk mengimplementasikan failover otomatis dan pembagian baca/tulis setelah melakukan konfigurasi sederhana.
Informasi latar belakang
Pada PostgreSQL 10 dan versi lebih baru, libpq mendukung failover, sedangkan JDBC mendukung failover dan load balancing di tingkat driver.
libpq adalah API C untuk PostgreSQL. libpq merupakan kumpulan fungsi perpustakaan yang memungkinkan program klien mengirimkan query ke server backend PostgreSQL dan menerima hasil dari query tersebut.
JDBC adalah API Java untuk menentukan bagaimana program klien mengakses database. Di PostgreSQL, JDBC mendukung failover dan load balancing.
Menggunakan libpq untuk mengimplementasikan failover otomatis dan pembagian baca/tulis
Anda dapat menggunakan fungsi libpq untuk terhubung ke beberapa database. Jika satu database mengalami gangguan, layanan secara otomatis dialihkan ke database lain yang tersedia.
Perintah
postgresql://[user[:password]@][netloc][:port][,...][/dbname][?param1=value1&...]Contoh
Dalam contoh berikut, klien terhubung ke instance ApsaraDB RDS for PostgreSQL utama dan dua instance RDS baca-saja miliknya. Jika setidaknya salah satu dari instance RDS ini tersedia, permintaan baca tidak akan gagal.
postgres://pgm-bpxxx1.pg.rds.aliyuncs.com:3433,pgm-bpxxx2.pg.rds.aliyuncs.com:3433,pgm-bpxxx3.pg.rds.aliyuncs.com:3433/postgres?target_session_attrs=anytarget_session_attrs: menentukan status instance RDS yang terhubung. Nilai valid:
any: Klien secara acak terhubung ke instance RDS dalam sistem database Anda. Jika koneksi terputus karena instance RDS mengalami gangguan, klien terhubung ke instance RDS lain dalam sistem database untuk mengimplementasikan failover. Ini adalah nilai default.
read-write: Klien hanya terhubung ke instance RDS yang mendukung operasi baca dan tulis dalam sistem database Anda. Klien terhubung ke instance RDS dalam sistem database secara berurutan. Jika instance RDS tidak mendukung operasi baca dan tulis, klien memutuskan koneksi dari instance RDS tersebut dan terhubung ke instance RDS berikutnya hingga klien terhubung ke instance RDS yang mendukung operasi baca dan tulis.
Untuk informasi lebih lanjut tentang cara menggunakan libpq dan mengonfigurasi parameter lainnya, lihat Connection Strings.
Anda dapat memanggil fungsi pg_is_in_recovery() di aplikasi Anda untuk menentukan apakah instance RDS yang terhubung adalah instance RDS utama atau instance RDS baca-saja. Hal ini membantu mengimplementasikan failover otomatis dan pembagian baca/tulis. Contoh:
Python
$ cat pg_conn.py import psycopg2 conn = psycopg2.connect(database="postgres",host="pgm-bpxxx1.pg.rds.aliyuncs.com,pgm-bpxxx2.pg.rds.aliyuncs.com,pgm-bpxxx3.pg.rds.aliyuncs.com", user="testxxx", password="xxxxxx", port="3433", target_session_attrs="read-write") cur = conn.cursor() cur.execute("select pg_is_in_recovery(), pg_postmaster_start_time()") row = cur.fetchone() print "recovery =",row[0] print "time =",row[1] $ python pg_conn.py recovery = False time = 2020-07-09 15:33:57.79001+08CatatanSintaks print pada contoh di atas hanya berlaku untuk Python 2. Jika Anda menggunakan Python 3, ganti sintaks print dengan konten berikut:
print("recovery =", row[0]) print("time =", row[1])PHP
# cat pg_conn.php <?php $conn = pg_connect("host=pgm-bpxxx1.pg.rds.aliyuncs.com,pgm-bpxxx2.pg.rds.aliyuncs.com,pgm-bpxxx3.pg.rds.aliyuncs.com port=3433 dbname=postgres user=testxxx password=xxxxxx target_session_attrs=read-write") or die("Could not connect"); $status = pg_connection_status($conn); if ($status === PGSQL_CONNECTION_OK) { print "Status koneksi ok\n"; } else { print "Status koneksi buruk\n"; } $sql = pg_query($conn, "select pg_is_in_recovery()"); while ($row = pg_fetch_row($sql)) { echo "Status pemulihan: $row[0]\n"; } ?> $ php -f pg_conn.php Status koneksi ok Status pemulihan: f Server: xxx.xxx.xx.xx
Menggunakan JDBC untuk mengimplementasikan failover otomatis dan pembagian baca/tulis
Anda dapat menentukan beberapa instance RDS dan memisahkannya dengan koma (,) di URL koneksi. Driver JDBC mencoba terhubung ke instance secara berurutan hingga koneksi berhasil. Jika semua upaya koneksi gagal, pesan kesalahan akan dikembalikan.
Perintah
jdbc:postgresql://node1,node2,node3/accounting?targetServerType=preferSlave&loadBalanceHosts=true Contoh
jdbc:postgresql://pgm-bpxxx1.pg.rds.aliyuncs.com:3433,pgm-bpxxx2.pg.rds.aliyuncs.com:3433,pgm-bpxxx3.pg.rds.aliyuncs.com:3433/accounting?targetServerType=preferSlave&loadBalanceHosts=true Daftar berikut menjelaskan parameter dalam hasil yang dikembalikan:
targetServerType: menentukan instance RDS ke mana driver JDBC terhubung. Nilai valid:
any: Driver JDBC terhubung ke instance RDS apa pun.
master: Driver JDBC hanya terhubung ke instance RDS utama.
slave: Driver JDBC hanya terhubung ke instance RDS sekunder.
preferSlave: Driver JDBC secara preferensial terhubung ke instance RDS sekunder. Jika tidak ada instance RDS sekunder yang tersedia, driver JDBC terhubung ke instance RDS utama.
CatatanInstance RDS utama mendukung operasi tulis, tetapi instance RDS sekunder tidak mendukung operasi tulis.
loadBalanceHosts menentukan urutan percobaan untuk terhubung ke instance RDS. Nilai valid:
False: Instance RDS dihubungkan sesuai urutan yang ditentukan dalam perintah. Ini adalah nilai default.
True: Instance RDS dihubungkan secara acak.
Untuk mengimplementasikan pembagian baca/tulis, Anda harus mengonfigurasi instance RDS utama dan instance RDS sekunder saat mengonfigurasi driver JDBC. Atur targetServerType ke master untuk instance RDS utama dan targetServerType ke preferSlave untuk instance RDS sekunder. Kemudian, tentukan bahwa operasi tulis dilakukan pada instance RDS utama dan operasi baca dilakukan pada instance RDS sekunder. Jika Anda ingin menentukan apakah instance RDS yang terhubung adalah instance RDS utama atau sekunder atau baca-saja, Anda dapat memanggil fungsi pg_is_in_recovery(). Hal ini membantu mengimplementasikan failover otomatis dan pembagian baca/tulis.