Lapisan proxy bisa sangat berguna dalam meningkatkan ketersediaan tingkat basis data Anda. Ini dapat mengurangi jumlah kode di sisi aplikasi untuk menangani kegagalan database dan perubahan topologi replikasi. Dalam posting blog ini kita akan membahas cara mengatur HAProxy agar berfungsi di atas PostgreSQL.
Hal pertama yang pertama - HAProxy bekerja dengan database sebagai proxy lapisan jaringan. Tidak ada pemahaman tentang topologi yang mendasarinya, terkadang rumit. Yang dilakukan HAProxy hanyalah mengirim paket secara round-robin ke backend yang ditentukan. Itu tidak memeriksa paket atau memahami protokol di mana aplikasi berbicara dengan PostgreSQL. Akibatnya, HAProxy tidak dapat menerapkan pemisahan baca/tulis pada satu port - ini akan memerlukan penguraian kueri. Selama aplikasi Anda dapat memisahkan pembacaan dari penulisan dan mengirimkannya ke IP atau port yang berbeda, Anda dapat menerapkan pemisahan R/W menggunakan dua backend. Mari kita lihat bagaimana hal itu dapat dilakukan.
Konfigurasi HAProxy
Di bawah ini Anda dapat menemukan contoh dua backend PostgreSQL yang dikonfigurasi di HAProxy.
listen haproxy_10.0.0.101_3307_rw
bind *:3307
mode tcp
timeout client 10800s
timeout server 10800s
tcp-check expect string master\ is\ running
balance leastconn
option tcp-check
option allbackups
default-server port 9201 inter 2s downinter 5s rise 3 fall 2 slowstart 60s maxconn 64 maxqueue 128 weight 100
server 10.0.0.101 10.0.0.101:5432 check
server 10.0.0.102 10.0.0.102:5432 check
server 10.0.0.103 10.0.0.103:5432 check
listen haproxy_10.0.0.101_3308_ro
bind *:3308
mode tcp
timeout client 10800s
timeout server 10800s
tcp-check expect string is\ running.
balance leastconn
option tcp-check
option allbackups
default-server port 9201 inter 2s downinter 5s rise 3 fall 2 slowstart 60s maxconn 64 maxqueue 128 weight 100
server 10.0.0.101 10.0.0.101:5432 check
server 10.0.0.102 10.0.0.102:5432 check
server 10.0.0.103 10.0.0.103:5432 check
Seperti yang bisa kita lihat, mereka menggunakan port 3307 untuk menulis dan 3308 untuk membaca. Dalam pengaturan ini ada tiga server - satu replika aktif dan dua replika siaga. Yang penting, tcp-check digunakan untuk melacak kesehatan node. HAProxy akan terhubung ke port 9201 dan mengharapkan untuk melihat string dikembalikan. Anggota backend yang sehat akan mengembalikan konten yang diharapkan, mereka yang tidak mengembalikan string akan ditandai sebagai tidak tersedia.
Pengaturan Xinetd
Saat HAProxy memeriksa port 9201, sesuatu harus mendengarkannya. Kita dapat menggunakan xinetd untuk mendengarkan di sana dan menjalankan beberapa skrip untuk kita. Contoh konfigurasi layanan tersebut mungkin terlihat seperti:
# default: on
# description: postgreschk
service postgreschk
{
flags = REUSE
socket_type = stream
port = 9201
wait = no
user = root
server = /usr/local/sbin/postgreschk
log_on_failure += USERID
disable = no
#only_from = 0.0.0.0/0
only_from = 0.0.0.0/0
per_source = UNLIMITED
}
Anda perlu memastikan bahwa Anda menambahkan baris:
postgreschk 9201/tcp
ke /etc/services.
Xinetd memulai skrip postgreschk, yang memiliki konten seperti di bawah ini:
#!/bin/bash
#
# This script checks if a PostgreSQL server is healthy running on localhost. It will
# return:
# "HTTP/1.x 200 OK\r" (if postgres is running smoothly)
# - OR -
# "HTTP/1.x 500 Internal Server Error\r" (else)
#
# The purpose of this script is make haproxy capable of monitoring PostgreSQL properly
#
export PGHOST='10.0.0.101'
export PGUSER='someuser'
export PGPASSWORD='somepassword'
export PGPORT='5432'
export PGDATABASE='postgres'
export PGCONNECT_TIMEOUT=10
FORCE_FAIL="/dev/shm/proxyoff"
SLAVE_CHECK="SELECT pg_is_in_recovery()"
WRITABLE_CHECK="SHOW transaction_read_only"
return_ok()
{
echo -e "HTTP/1.1 200 OK\r\n"
echo -e "Content-Type: text/html\r\n"
if [ "$1x" == "masterx" ]; then
echo -e "Content-Length: 56\r\n"
echo -e "\r\n"
echo -e "<html><body>PostgreSQL master is running.</body></html>\r\n"
elif [ "$1x" == "slavex" ]; then
echo -e "Content-Length: 55\r\n"
echo -e "\r\n"
echo -e "<html><body>PostgreSQL slave is running.</body></html>\r\n"
else
echo -e "Content-Length: 49\r\n"
echo -e "\r\n"
echo -e "<html><body>PostgreSQL is running.</body></html>\r\n"
fi
echo -e "\r\n"
unset PGUSER
unset PGPASSWORD
exit 0
}
return_fail()
{
echo -e "HTTP/1.1 503 Service Unavailable\r\n"
echo -e "Content-Type: text/html\r\n"
echo -e "Content-Length: 48\r\n"
echo -e "\r\n"
echo -e "<html><body>PostgreSQL is *down*.</body></html>\r\n"
echo -e "\r\n"
unset PGUSER
unset PGPASSWORD
exit 1
}
if [ -f "$FORCE_FAIL" ]; then
return_fail;
fi
# check if in recovery mode (that means it is a 'slave')
SLAVE=$(psql -qt -c "$SLAVE_CHECK" 2>/dev/null)
if [ $? -ne 0 ]; then
return_fail;
elif echo $SLAVE | egrep -i "(t|true|on|1)" 2>/dev/null >/dev/null; then
return_ok "slave"
fi
# check if writable (then we consider it as a 'master')
READONLY=$(psql -qt -c "$WRITABLE_CHECK" 2>/dev/null)
if [ $? -ne 0 ]; then
return_fail;
elif echo $READONLY | egrep -i "(f|false|off|0)" 2>/dev/null >/dev/null; then
return_ok "master"
fi
return_ok "none";
Logika skrip berjalan sebagai berikut. Ada dua query yang digunakan untuk mendeteksi status node.
SLAVE_CHECK="SELECT pg_is_in_recovery()"
WRITABLE_CHECK="SHOW transaction_read_only"
Pemeriksaan pertama apakah PostgreSQL dalam pemulihan - itu akan menjadi 'salah' untuk server aktif dan 'benar' untuk server siaga. Pemeriksaan kedua apakah PostgreSQL dalam mode read-only. Server aktif akan kembali 'mati' sementara server siaga akan kembali 'aktif'. Berdasarkan hasil, skrip memanggil fungsi return_ok() dengan parameter yang tepat ('master' atau 'slave', tergantung pada apa yang terdeteksi). Jika kueri gagal, fungsi 'return_fail' akan dijalankan.
Fungsi Return_ok mengembalikan string berdasarkan argumen yang diteruskan ke sana. Jika host adalah server aktif, skrip akan mengembalikan "Master PostgreSQL sedang berjalan". Jika dalam keadaan siaga, string yang dikembalikan akan menjadi:"Budak PostgreSQL sedang berjalan". Jika status tidak jelas, itu akan kembali:"PostgreSQL sedang berjalan". Di sinilah loop berakhir. HAProxy memeriksa status dengan menghubungkan ke xinetd. Yang terakhir memulai skrip, yang kemudian mengembalikan string yang diurai HAProxy.
Seperti yang mungkin Anda ingat, HAProxy mengharapkan string berikut:
tcp-check expect string master\ is\ running
untuk backend tulis dan
tcp-check expect string is\ running.
untuk backend hanya-baca. Hal ini membuat server aktif menjadi satu-satunya host yang tersedia di backend tulis sedangkan di backend baca, server aktif dan siaga dapat digunakan.
PostgreSQL dan HAProxy di ClusterControl
Pengaturan di atas tidak rumit, tetapi perlu waktu untuk mengaturnya. ClusterControl dapat digunakan untuk mengatur semua ini untuk Anda.
Di menu tarik-turun tugas cluster, Anda memiliki opsi untuk menambahkan penyeimbang beban. Kemudian opsi untuk menyebarkan HAProxy muncul. Anda perlu mengisi tempat Anda ingin menginstalnya, dan membuat beberapa keputusan:dari repositori yang telah Anda konfigurasikan di host atau versi terbaru, yang dikompilasi dari kode sumber. Anda juga harus mengonfigurasi node mana dalam cluster yang ingin Anda tambahkan ke HAProxy.
Setelah instance HAProxy diterapkan, Anda dapat mengakses beberapa statistik di tab “Node”:
Seperti yang dapat kita lihat, untuk backend R/W, hanya satu host (server aktif) yang ditandai sebagai up. Untuk backend hanya-baca, semua node aktif.
Unduh Whitepaper Hari Ini Pengelolaan &Otomatisasi PostgreSQL dengan ClusterControlPelajari tentang apa yang perlu Anda ketahui untuk menerapkan, memantau, mengelola, dan menskalakan PostgreSQLUnduh WhitepaperTeruskan
HAProxy akan berada di antara aplikasi Anda dan instans database, sehingga akan memainkan peran sentral. Sayangnya ini juga bisa menjadi satu titik kegagalan, jika gagal, tidak akan ada rute ke database. Untuk menghindari situasi seperti itu, Anda dapat menerapkan beberapa instans HAProxy. Tapi kemudian pertanyaannya adalah - bagaimana memutuskan ke host proxy mana yang akan disambungkan. Jika Anda menerapkan HAProxy dari ClusterControl, semudah menjalankan tugas “Tambahkan Load Balancer” lainnya, kali ini menerapkan Keepalive.
Seperti yang dapat kita lihat pada tangkapan layar di atas, Anda dapat mengambil hingga tiga host HAProxy dan Keepalive akan ditempatkan di atasnya, memantau statusnya. Virtual IP (VIP) akan diberikan ke salah satunya. Aplikasi Anda harus menggunakan VIP ini untuk terhubung ke database. Jika HAProxy "aktif" tidak tersedia, VIP akan dipindahkan ke host lain.
Seperti yang telah kita lihat, cukup mudah untuk menerapkan tumpukan ketersediaan tinggi penuh untuk PostgreSQL. Cobalah dan beri tahu kami jika Anda memiliki masukan.