PostgreSQL Ketersediaan Tinggi / Skalabilitas menggunakan HAProxy dan PGBouncer

17

Saya memiliki beberapa server PostgreSQL untuk aplikasi web. Biasanya satu master dan beberapa budak dalam mode siaga panas (replikasi streaming asinkron).

Saya menggunakan PGBouncer untuk koneksi pooling: satu instance diinstal pada setiap server PG (port 6432) yang terhubung ke database di localhost. Saya menggunakan mode kumpulan transaksi.

Untuk memuat-menyeimbangkan koneksi read-only saya pada slave, saya menggunakan HAProxy (v1.5) dengan conf kurang lebih seperti ini:

listen pgsql_pool 0.0.0.0:10001
        mode tcp
        option pgsql-check user ha
        balance roundrobin
        server master 10.0.0.1:6432 check backup
        server slave1 10.0.0.2:6432 check
        server slave2 10.0.0.3:6432 check
        server slave3 10.0.0.4:6432 check

Jadi, aplikasi web saya terhubung ke haproxy (port 10001), koneksi load-balance pada beberapa pgbouncer yang dikonfigurasi pada setiap slave PG.

Berikut ini adalah grafik representasi arsitektur saya saat ini:

haproxy> pgbouncer> postgresql

Ini berfungsi sangat baik seperti ini, tetapi saya menyadari bahwa beberapa mengimplementasikan ini sangat berbeda: aplikasi web terhubung ke instance PGBouncer tunggal yang terhubung ke HAproxy yang memuat-menyeimbangkan lebih dari beberapa server PG:

pgbouncer> haproxy> postgresql

Apa pendekatan terbaik? Yang pertama (yang saya sekarang) atau yang kedua? Adakah keunggulan dari satu solusi di atas yang lain?

Terima kasih

Nicolas Payart
sumber

Jawaban:

10

Konfigurasi HAProxy -> PGBouncer -> PGServer Anda yang sudah ada lebih baik. Dan itu hanya berhasil. Inilah alasannya: HAProxy mengalihkan koneksi ke server yang berbeda. ini menghasilkan perubahan alamat MAC dalam koneksi database. Jadi, jika PGBouncer di atas HAProxy, setiap kali koneksi di pool menjadi tidak valid karena perubahan alamat MAC.

Jobin Augustine
sumber
7

pgbouncer memelihara koneksi di kolam dengan server postgres. Waktu pembentukan koneksi TCP signifikan dalam lingkungan volume tinggi.

Klien yang membuat sejumlah besar permintaan DB harus menyiapkan koneksi dengan PGBouncer jarak jauh untuk setiap permintaan. Ini lebih mahal, daripada menjalankan PgBouncer secara lokal (sehingga aplikasi terhubung ke pgbouncer secara lokal) dan pgBuncer mempertahankan kumpulan koneksi dengan server PG jarak jauh.

Jadi, IMO, PGBouncer -> HAProxy -> PGServer tampaknya lebih baik daripada, HAProxy -> PGBouncer -> PGServer, terutama ketika PGBouncer bersifat lokal untuk aplikasi klien.

donatello
sumber
1

Saya harus tidak setuju dengan jawaban yang diberikan oleh donatello.

Anda lihat, jika aplikasi Anda tidak mengelola koneksi DB menggunakan kumpulan lokal, itu akan membuat koneksi baru setiap kali perlu meminta DB; itu terjadi persis sama ketika menggunakan PgBouncer, jadi Anda akan memiliki peningkatan yang sangat baik dengan menggunakannya.

Saat PgBouncer mengelola koneksi PostgreSQL dengan menyatukannya, waktu yang dihabiskan aplikasi Anda untuk membuka koneksi menurun secara signifikan, dibandingkan dengan saat koneksi dibuka langsung ke DB. Itu karena PG cukup lambat untuk memeriksa dan memverifikasi kredensial dan semuanya setiap kali koneksi diminta.

Jadi, aplikasi pendekatan -> HAProxy -> [PgBouncer -> PostgreSQL] adalah yang lebih baik, karena PgBouncer menghemat waktu koneksi ke PG. Mode penyatuan juga penting untuk diperhitungkan. Anda harus menyadari bagaimana perilaku aplikasi Anda. Apakah sebagian besar transaksional? Atau, apakah lebih dari mengeksekusi sekelompok kalimat SQL kecil dengan konkurensi tinggi? Semua parameter tersebut berpengaruh pada kinerja.

Alvaro
sumber