PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Panduan Menggunakan pgBouncer untuk PostgreSQL

Saat membaca PostgreSQL untuk memulai, Anda melihat baris:“Server PostgreSQL dapat menangani beberapa koneksi bersamaan dari klien. Untuk mencapai ini, ia memulai ("garpu") proses baru untuk setiap koneksi. Sejak saat itu, klien dan proses server baru berkomunikasi tanpa intervensi oleh proses postgres asli. Dengan demikian, proses server master selalu berjalan, menunggu koneksi klien, sedangkan klien dan proses server terkait datang dan pergi.

Ide brilian. Namun itu berarti bahwa setiap koneksi baru memutar proses baru, menyimpan RAM dan mungkin menjadi terlalu berat dengan beberapa sesi. Untuk menghindari masalah, postgres memiliki pengaturan max_connections dengan 100 koneksi default. Tentu saja Anda dapat meningkatkannya, tetapi tindakan seperti itu perlu dimulai ulang (pg_settings.context adalah 'postmaster'):

t=# select name,setting,short_desc,context from pg_settings where name = 'max_connections';
-[ RECORD 1 ]--------------------------------------------------
name       | max_connections
setting    | 100
short_desc | Sets the maximum number of concurrent connections.
context    | postmaster
Beberapa bacaan menarik Penggunaan PgBouncer Apa gunanya memantul? PgBouncer Changelog Postingan yang berisi 'pgbouncer' di Stack Overflow Postingan dengan tag 'pgbouncer' di Kuadran Kedua

Dan bahkan setelah meningkat - pada titik tertentu Anda mungkin memerlukan lebih banyak koneksi (tentu saja segera seperti biasa saat menjalankan prod). Mengapa meningkatkannya sangat tidak nyaman? Karena jika nyaman, Anda mungkin akan berakhir dengan peningkatan spontan yang tidak terkendali hingga cluster mulai tertinggal. Artinya koneksi lama lebih lambat - sehingga membutuhkan lebih banyak waktu, jadi Anda membutuhkan lebih banyak dan lebih banyak lagi yang baru. Untuk menghindari kemungkinan longsor dan menambahkan beberapa fleksibilitas, kami memiliki superuser_reserved_connections - untuk dapat menghubungkan dan memperbaiki masalah dengan SU ketika max_connections habis. Dan kami jelas melihat perlunya beberapa koneksi pooler. Karena kami ingin kandidat koneksi baru menunggu dalam antrian alih-alih gagal dengan pengecualian FATAL:maaf, sudah terlalu banyak klien dan tidak membahayakan postmaster.

Penyatuan koneksi ditawarkan pada tingkat tertentu oleh banyak "klien" populer. Anda bisa menggunakannya dengan jdbc cukup lama. Baru-baru ini node-postgres menawarkan node-pg-pool miliknya sendiri. Kurang lebih implementasinya sederhana (seperti idenya):pooler memulai koneksi ke database dan menyimpannya. Klien yang terhubung ke db hanya mendapatkan koneksi "bersama" yang ada dan setelah menutupnya, koneksi kembali ke kumpulan. Kami juga memiliki perangkat lunak yang jauh lebih canggih, seperti pgPool. Namun pgbouncer adalah pilihan yang sangat populer untuk tugas tersebut. Mengapa? Karena itu hanya melakukan bagian penyatuan, tetapi melakukannya dengan benar. Gratis. Ini cukup sederhana untuk diatur. Dan Anda menemukannya di sebagian besar penyedia layanan terbesar seperti yang direkomendasikan atau digunakan, misalnya citusdata, aws, heroku, dan sumber daya lainnya yang sangat dihormati.

Jadi mari kita lihat lebih dekat apa yang bisa dan bagaimana Anda menggunakannya. Dalam pengaturan saya, saya menggunakan pool_mode =transaksi default (bagian [pgbouncer]) yang merupakan pilihan yang sangat populer. Dengan cara ini kami tidak hanya mengantrekan koneksi yang melebihi max_connections, tetapi menggunakan kembali sesi tanpa menunggu koneksi sebelumnya ditutup:

[databases]
mon = host=1.1.1.1 port=5432 dbname=mon
mons = host=1.1.1.1 port=5432 dbname=mon pool_mode = session pool_size=2 max_db_connections=2
monst = host=1.1.1.1 port=5432 dbname=mon pool_mode = statement
[pgbouncer]
listen_addr = 1.1.1.1
listen_port = 6432
unix_socket_dir = /tmp
auth_file = /pg/pgbouncer/bnc_users.txt
auth_type = hba
auth_hba_file = /pg/pgbouncer/bnc_hba.conf
admin_users = root vao
pool_mode = transaction
server_reset_query = RESET ALL; --DEALLOCATE ALL; /* custom */
ignore_startup_parameters = extra_float_digits
application_name_add_host = 1
max_client_conn = 10000
autodb_idle_timeout = 3600
default_pool_size = 100
max_db_connections = 100
max_user_connections = 100
#server_reset_query_always = 1 #uncomment if you want older global behaviour

Ikhtisar singkat tentang pengaturan dan tip dan trik paling populer:

  • server_reset_query sangat berguna dan penting. Dalam mode pengumpulan sesi, itu "menghapus" "artefak" sesi sebelumnya. Jika tidak, Anda akan memiliki masalah dengan nama yang sama untuk pernyataan yang disiapkan, pengaturan sesi yang memengaruhi sesi berikutnya, dan seterusnya. Defaultnya adalah DISCARD ALL, yang "mengatur ulang" semua status sesi. Namun Anda dapat memilih nilai yang lebih canggih, misalnya, RESET ALL; DEALOKASI SEMUA; untuk melupakan hanya SESI SESI dan pernyataan yang disiapkan, menjaga tabel dan rencana TEMP "dibagi". Atau sebaliknya - Anda mungkin ingin membuat pernyataan siap pakai "global" dari sesi mana pun. Konfigurasi seperti itu bisa dilakukan, meskipun berisiko. Anda harus membuat pgbouncer menggunakan kembali sesi untuk semua (sehingga membuat ukuran kumpulan yang sangat kecil atau menghapus sesi), yang tidak sepenuhnya dapat diandalkan. Pokoknya - itu adalah kemampuan yang berguna. Terutama dalam pengaturan di mana Anda ingin sesi klien pada akhirnya (tidak segera) berubah ke pengaturan sesi gabungan yang dikonfigurasi. Poin yang sangat penting di sini adalah mode kumpulan sesi. Sebelum 1.6, pengaturan ini memengaruhi mode kumpulan lainnya juga, jadi jika Anda mengandalkannya, Anda perlu menggunakan pengaturan baru server_reset_query_always =1. Mungkin pada titik tertentu orang akan menginginkan server_reset_query menjadi lebih fleksibel dan dapat dikonfigurasi per pasangan db/pengguna ( dan client_reset_query sebagai gantinya). Tetapi pada tulisan saat ini, Maret 2018, itu bukan pilihan. Gagasan di balik membuat pengaturan ini valid secara default untuk mode sesi saja adalah - jika Anda berbagi koneksi pada tingkat transaksi atau pernyataan - Anda tidak dapat mengandalkan pengaturan sesi sama sekali.

  • Jenis_auth =hba. Sebelum 1.7, masalah besar dengan pgbouncer adalah tidak adanya otentikasi berbasis host - "firewall postgres". Tentu saja Anda masih memilikinya untuk koneksi cluster postgres, tetapi pgbouncer "terbuka" untuk sumber apa pun. Sekarang kita dapat menggunakan hba.conf yang sama untuk membatasi koneksi host/db/user berdasarkan jaringan koneksi.

  • connect_query tidak dilakukan pada setiap "koneksi" klien ke pgbouncer, melainkan ketika pgbouncer terhubung ke instance Postgres. Dengan demikian Anda tidak dapat menggunakannya untuk mengatur atau mengesampingkan pengaturan "default". Dalam mode sesi, sesi lain tidak saling memengaruhi dan saat terputus, kueri reset membuang semua - jadi Anda tidak perlu mengacaukannya. Dalam mode pengumpulan transaksi, Anda berharap dapat menggunakannya untuk pengaturan yang salah diatur oleh sesi lain, tetapi sayangnya tidak akan berhasil. Misalnya. Anda ingin membagikan pernyataan yang disiapkan antara "sesi" dalam mode transaksi, jadi Anda mengatur sesuatu seperti

    trns = dbname=mon pool_mode = transaction connect_query = 'do $$ begin raise warning $w$%$w$, $b$new connection$b$; end; $$; prepare s(int) as select $1;'

    dan memang - setiap klien baru melihat pernyataan yang disiapkan (kecuali Anda membiarkan server_reset_query_always aktif, jadi pgbouncer membuangnya saat dikomit). Tetapi jika beberapa klien menjalankan DISCARD s; dalam sesinya, ini memengaruhi semua klien pada koneksi ini dan klien baru yang terhubung dengannya tidak akan melihat pernyataan yang disiapkan lagi. Tetapi jika Anda ingin memiliki beberapa pengaturan awal untuk koneksi postgres yang berasal dari pgbouncer, maka inilah tempatnya.

  • application_name_add_host telah ditambahkan di 1.6, ia memiliki batasan yang sama. Ini "menempatkan" IP klien ke application_name, sehingga Anda dapat dengan mudah mendapatkan sumber kueri buruk Anda, tetapi mudah diganti dengan set sederhana application_name TO 'bukan saya'; Anda masih dapat "menyembuhkan" ini menggunakan tampilan - ikuti posting ini untuk mendapatkan ide atau bahkan menggunakan instruksi singkat ini. Pada dasarnya ide itu adalah menunjukkan klien; akan menampilkan IP klien, sehingga Anda dapat menanyakannya langsung dari basis data pgbouncer pada setiap pilihan dari pg_stat_activity untuk memeriksa apakah itu disetel ulang. Namun tentunya menggunakan setting yang sederhana jauh lebih simpel dan nyaman. Meski tidak menjamin hasil...

  • pool_mode dapat ditentukan baik sebagai default, per database dan per pengguna - membuatnya sangat fleksibel. Mode pencampuran membuat pgbouncer sangat efektif untuk pengumpulan. Ini adalah fitur yang kuat, tetapi kita harus berhati-hati saat menggunakannya. Seringkali pengguna menggunakannya tanpa memahami hasil untuk campuran atom dari per transaksi/per sesi/per pengguna/per database/pengaturan global bekerja secara berbeda untuk pengguna atau database yang sama, karena mode penyatuan yang berbeda dengan pgbouncer. Ini adalah kotak korek api yang tidak boleh Anda berikan kepada anak-anak tanpa pengawasan. Juga banyak opsi lain yang dapat dikonfigurasi untuk default dan per db dan per pengguna.

  • Tolong jangan mengartikannya secara harfiah, tetapi Anda dapat “membandingkan” bagian yang berbeda dari ini dengan SET dan ALTER:SET LOCAL mempengaruhi transaksi dan baik digunakan ketika poll_mode=transaction , SET SESSION mempengaruhi sesi dan aman untuk digunakan ketika poll_mode=session , ALTER USER SET mempengaruhi peran dan akan mengganggu pgbouncer.ini bagian dari bagian [pengguna], ALTER DATABASE SET mempengaruhi database dan akan mengganggu pgbouncer.ini bagian dari bagian [databases], ALTER SYSTEM SET atau mengedit postgres.conf secara global mempengaruhi default dan sebanding dengan efeknya dengan bagian default pgbouncer.ini.

  • Sekali lagi - gunakan mode pool secara bertanggung jawab. Pernyataan yang disiapkan atau pengaturan lebar sesi akan berantakan dalam mode pengumpulan transaksi. Sama seperti transaksi SQL tidak masuk akal dalam mode penyatuan pernyataan. Pilih mode penyatuan yang sesuai untuk koneksi yang sesuai. Praktik yang baik adalah menciptakan peran dengan gagasan bahwa:

    • beberapa hanya akan menjalankan pilihan cepat, sehingga dapat berbagi satu sesi tanpa transaksi untuk ratusan pilihan kecil yang tidak penting secara bersamaan.
    • Beberapa anggota peran aman untuk konkurensi tingkat sesi, dan SELALU menggunakan transaksi. Dengan demikian, mereka dapat dengan aman berbagi beberapa sesi untuk ratusan transaksi bersamaan.
    • Beberapa peran terlalu rumit dan rumit untuk dibagikan kepada orang lain. Jadi, Anda menggunakan mode pengumpulan sesi untuk menghindari kesalahan koneksi saat semua "slot" sudah diambil.
  • Jangan menggunakannya sebagai ganti HAProxy atau penyeimbang beban lainnya. Terlepas dari kenyataan bahwa pgbouncer memiliki beberapa fitur yang dapat dikonfigurasi yang menangani alamat penyeimbang beban, seperti dns_max_ttl dan Anda dapat mengatur konfigurasi DNS untuknya, sebagian besar lingkungan prod menggunakan HAProxy atau penyeimbang beban lainnya untuk HA. Ini karena HAProxy sangat bagus dalam penyeimbangan beban di seluruh server langsung dengan cara round robin, lebih baik daripada pgbouncer. Meskipun pgbouncer lebih baik untuk penggabungan koneksi postgres, mungkin lebih baik menggunakan satu daemon kecil yang melakukan satu tugas dengan sempurna, daripada yang lebih besar yang melakukan dua tugas, tetapi lebih buruk.

  • Perubahan konfigurasi bisa jadi rumit. Beberapa perubahan pgbouncer.ini memerlukan restart (listen_port dan semacamnya), sementara yang lain seperti admin_users memerlukan reload atau SIGHUP. Perubahan di dalam auth_hba_file memerlukan pemuatan ulang, sedangkan perubahan pada auth_file tidak.

Ikhtisar yang sangat singkat dari pengaturan di atas dibatasi oleh format. Saya mengundang Anda untuk melihat daftar lengkapnya. Pgbouncer adalah jenis perangkat lunak dengan jumlah "pengaturan membosankan" yang sangat kecil - semuanya memiliki potensi besar dan sangat menarik.

Unduh Whitepaper Hari Ini Pengelolaan &Otomatisasi PostgreSQL dengan ClusterControlPelajari tentang apa yang perlu Anda ketahui untuk menerapkan, memantau, mengelola, dan menskalakan PostgreSQLUnduh Whitepaper

Dan terakhir, beralih dari ulasan singkat yang antusias ke sesuatu yang mungkin membuat Anda kurang senang - pemasangannya. Prosesnya dijelaskan dengan jelas di bagian dokumentasi ini. Satu-satunya opsi yang dijelaskan adalah membangun dari sumber git. Tapi semua orang tahu ada paket! Mencoba keduanya yang paling populer:

sudo yum install pgbouncer
sudo apt-get install pgbouncer

bisa bekerja. Namun terkadang Anda harus melakukan langkah ekstra. Misalnya, ketika tidak ada paket pgbouncer yang tersedia, coba ini.

Atau bahkan:

sudo yum install pgbouncer
Loaded plugins: priorities, update-motd, upgrade-helper
amzn-main                                                                                                                    | 2.1 kB  00:00:00
amzn-updates                                                                                                                 | 2.5 kB  00:00:00
docker-ce-edge                                                                                                               | 2.9 kB  00:00:00
docker-ce-stable                                                                                                             | 2.9 kB  00:00:00
docker-ce-test                                                                                                               | 2.9 kB  00:00:00
pgdg10                                                                                                                       | 4.1 kB  00:00:00
pgdg95                                                                                                                       | 4.1 kB  00:00:00
pgdg96                                                                                                                       | 4.1 kB  00:00:00
pglogical                                                                                                                    | 3.0 kB  00:00:00
sensu                                                                                                                        | 2.5 kB  00:00:00
(1/3): pgdg96/x86_64/primary_db                                                                                              | 183 kB  00:00:00
(2/3): pgdg10/primary_db                                                                                                     | 151 kB  00:00:00
(3/3): pgdg95/x86_64/primary_db                                                                                              | 204 kB  00:00:00
50 packages excluded due to repository priority protections
Resolving Dependencies
--> Running transaction check
---> Package pgbouncer.x86_64 0:1.8.1-1.rhel6 will be installed
--> Processing Dependency: libevent2 >= 2.0 for package: pgbouncer-1.8.1-1.rhel6.x86_64
--> Processing Dependency: c-ares for package: pgbouncer-1.8.1-1.rhel6.x86_64
--> Processing Dependency: libcares.so.2()(64bit) for package: pgbouncer-1.8.1-1.rhel6.x86_64
--> Running transaction check
---> Package c-ares.x86_64 0:1.13.0-1.5.amzn1 will be installed
---> Package pgbouncer.x86_64 0:1.8.1-1.rhel6 will be installed
--> Processing Dependency: libevent2 >= 2.0 for package: pgbouncer-1.8.1-1.rhel6.x86_64
--> Finished Dependency Resolution
Error: Package: pgbouncer-1.8.1-1.rhel6.x86_64 (pgdg10)
           Requires: libevent2 >= 2.0
 You could try using --skip-broken to work around the problem
 You could try running: rpm -Va --nofiles --nodigest

Tentu saja menambahkan pgdg ke /etc/yum.repos.d/ tidak akan membantu lagi. Baik --skip-broken atau rpm -Va --nofiles --nodigest. Sederhana

sudo yum install libevent2
Loaded plugins: priorities, update-motd, upgrade-helper
50 packages excluded due to repository priority protections
No package libevent2 available.
Error: Nothing to do

akan terlalu mudah. Jadi Anda harus membangun libevent2 sendiri, membawa Anda kembali ke posisi ketika Anda harus mengkompilasi semuanya sendiri. Entah itu pgbouncer atau salah satu dependensinya.

Sekali lagi - menggali terlalu dalam dengan kekhasan instalasi berada di luar jangkauan. Anda harus tahu bahwa Anda memiliki peluang besar untuk menginstalnya sebagai paket.

Terakhir - pertanyaan seperti "mengapa postgres tidak menawarkan pooler sesi asli" muncul berulang kali. Bahkan ada saran dan pemikiran yang sangat segar tentangnya. Namun sejauh ini pendekatan yang paling populer di sini adalah menggunakan pgbouncer.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. pgadmin4 :server aplikasi postgresql tidak dapat dihubungi.

  2. Ganti nama tabel dengan aman menggunakan kolom kunci utama serial

  3. Dalam fungsi pemicu, cara mendapatkan bidang mana yang diperbarui

  4. Dapatkan nilai paling umum untuk setiap nilai kolom lain di SQL

  5. Nilai Kesalahan saat mengimpor data ke tabel postgres menggunakan psycopg2