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

Panduan untuk Pgpool untuk PostgreSQL:Bagian Satu

Pgpool kurang aktual hari ini, dibandingkan 10 tahun yang lalu, ketika itu adalah bagian default dari pengaturan produksi PostgreSQL. Seringkali ketika seseorang berbicara tentang cluster PostgreSQL, mereka mengacu pada postgreSQL di belakang pgpool dan bukan pada instance PostgreSQL itu sendiri (yang merupakan istilah yang tepat). Pgpool diakui di antara pemain Postgres yang paling berpengaruh:komunitas postgresql, commandprompt, 2ndquadrant, EDB, citusdata, postgrespro (diurutkan berdasarkan usia, bukan pengaruh). Saya menyadari tingkat pengenalan di tautan saya sangat berbeda - saya hanya ingin menekankan dampak keseluruhan pgpool di dunia postgres. Beberapa "vendor" postgres saat ini yang paling dikenal ditemukan setelah pgpool sudah terkenal. Jadi apa yang membuatnya begitu terkenal?

Hanya daftar fitur yang ditawarkan paling laris yang membuatnya tampak hebat:

  • replikasi asli
  • pengumpulan koneksi
  • load balancing untuk skalabilitas baca
  • ketersediaan tinggi (pengawas dengan IP virtual, pemulihan online &failover)

Baiklah, mari kita membuat kotak pasir dan bermain. Pengaturan sampel saya adalah mode master slave. Saya akan menganggap ini adalah yang paling populer saat ini, karena Anda biasanya menggunakan replikasi streaming bersama dengan penyeimbangan beban. Mode replikasi hampir tidak digunakan akhir-akhir ini. Sebagian besar DBA melewatkannya untuk mendukung replikasi streaming dan pglogical, dan sebelumnya ke slony.

Mode replikasi memiliki banyak pengaturan menarik dan fungsionalitas yang pasti menarik. Tetapi sebagian besar DBA memiliki pengaturan master/multi slave pada saat mereka masuk ke pgpool. Jadi mereka mencari failover otomatis dan penyeimbang beban, dan pgpool menawarkannya di luar kotak untuk lingkungan master/multi slave yang ada. Belum lagi sejak Postgres 9.4, streaming replikasi bekerja tanpa bug utama dan dari 10 indeks hash replikasi didukung, jadi hampir tidak ada yang menghentikan Anda untuk menggunakannya. Replikasi streaming juga tidak sinkron secara default (dapat dikonfigurasi untuk penyiapan rumit sinkronisasi sinkron dan bahkan tidak "linier", sementara replikasi pgpool asli sinkron (yang berarti perubahan data lebih lambat) tanpa opsi pilihan. Juga batasan tambahan berlaku. Manual Pgpool sendiri menyarankan untuk memilih bila memungkinkan streaming replikasi melalui pgpool asli). Dan inilah pilihan saya di sini.

Ah, tapi pertama-tama kita harus menginstalnya - kan?

Instalasi (versi yang lebih tinggi di ubuntu).

Pertama-tama periksa versi ubuntu dengan lsb_release -a. Bagi saya repo adalah:

[email protected]:~# sudo add-apt-repository 'deb http://apt.postgresql.org/pub/repos/apt/ xenial-pgdg main'
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | \
>   sudo apt-key add -
OK
[email protected]:~# sudo apt-get update

Terakhir instalasi itu sendiri:

sudo apt-get install pgpool2=3.7.2-1.pgdg16.04+1

Konfigurasi:

Saya menggunakan konfigurasi default dari mode yang disarankan:

zcat /usr/share/doc/pgpool2/examples/pgpool.conf.sample-stream.gz > /etc/pgpool2/pgpool.conf

Mulai:

Jika Anda melewatkan konfigurasi, Anda akan melihat:

2018-03-22 13:52:53.284 GMT [13866] FATAL:  role "nobody" does not exist

Ah benar - saya buruk, tetapi mudah diperbaiki (dapat dilakukan secara membabi buta dengan satu liner jika Anda menginginkan pengguna yang sama untuk semua pemeriksaan kesehatan dan pemulihan):

[email protected]:~# sed -i s/'nobody'/'pgpool'/g /etc/pgpool2/pgpool.conf

Dan sebelum kita melangkah lebih jauh, mari kita buat database pgpool dan user pgpool di semua cluster (Di sandbox saya mereka adalah master, failover dan slave, jadi saya hanya perlu menjalankannya di master saja):

t=# create database pgpool;
CREATE DATABASE
t=# create user pgpool;
CREATE ROLE

Akhirnya - mulai:

[email protected]:~$ /usr/sbin/service pgpool2 start
[email protected]:~$ /usr/sbin/service pgpool2 status
pgpool2.service - pgpool-II
   Loaded: loaded (/lib/systemd/system/pgpool2.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2018-04-09 10:25:16 IST; 4h 14min ago
     Docs: man:pgpool(8)
  Process: 19231 ExecReload=/bin/kill -HUP $MAINPID (code=exited, status=0/SUCCESS)
 Main PID: 8770 (pgpool)
    Tasks: 10
   Memory: 5.5M
      CPU: 18.250s
   CGroup: /system.slice/pgpool2.service
           ├─ 7658 pgpool: wait for connection reques
           ├─ 7659 pgpool: wait for connection reques
           ├─ 7660 pgpool: wait for connection reques
           ├─ 8770 /usr/sbin/pgpool -n
           ├─ 8887 pgpool: PCP: wait for connection reques
           ├─ 8889 pgpool: health check process(0
           ├─ 8890 pgpool: health check process(1
           ├─ 8891 pgpool: health check process(2
           ├─19915 pgpool: postgres t ::1(58766) idl
           └─23730 pgpool: worker proces

Hebat - jadi kita bisa melanjutkan ke fitur pertama - mari kita periksa load balancing. Ini memiliki beberapa persyaratan untuk digunakan, mendukung petunjuk (misalnya untuk menyeimbangkan dalam sesi yang sama), memiliki fungsi daftar hitam-putih, memiliki daftar preferensi pengalihan berbasis ekspresi reguler. Ini canggih. Sayangnya, semua fungsi itu akan berada di luar cakupan blog ini, jadi kami akan memeriksa demo paling sederhana:

Pertama, sesuatu yang sangat sederhana akan menunjukkan node mana yang digunakan untuk memilih (dalam pengaturan saya, master berputar pada 5400, slave pada 5402 dan failover pada 5401, sementara pgpool sendiri pada 5433, karena saya memiliki cluster lain yang berjalan dan tidak ingin mengganggu dengan itu):

[email protected]:~$ psql -h localhost -p 5433 t -c "select current_setting('port') from ts limit 1"
 current_setting
-----------------
 5400
(1 row)

Kemudian dalam lingkaran:

[email protected]:~$ (for i in $(seq 1 99); do psql -h localhost -p 5433 t -c "select current_setting('port') from ts limit 1" -XAt; done) | sort| uniq -c
      9 5400
     30 5401
     60 5402

Besar. Itu pasti menyeimbangkan beban antar node, tetapi tampaknya tidak seimbang - mungkin sangat pintar sehingga mengetahui bobot setiap pernyataan? Mari kita periksa distribusinya dengan hasil yang diharapkan:

t=# show pool_nodes;
 node_id | hostname  | port | status | lb_weight |  role   | select_cnt | load_balance_node | replication_delay
---------+-----------+------+--------+-----------+---------+------------+-------------------+-------------------
 0       | localhost | 5400 | up     | 0.125000  | primary | 122        | false             | 0
 1       | localhost | 5401 | up     | 0.312500  | standby | 169        | false             | 0
 2       | localhost | 5402 | up     | 0.562500  | standby | 299        | true              | 0
(3 rows)

Tidak - pgpool tidak menganalisis bobot pernyataan - itu adalah DBA dengan pengaturannya lagi! Pengaturan (lihat atribut lb_weight) dicocokkan dengan target tujuan kueri yang sebenarnya. Anda dapat dengan mudah mengubahnya (seperti yang kami lakukan di sini) dengan mengubah pengaturan yang sesuai, misalnya:

[email protected]:~$ grep weight /etc/pgpool2/pgpool.conf
backend_weight0 =0.2
backend_weight1 = 0.5
backend_weight2 = 0.9
[email protected]:~# sed -i s/'backend_weight2 = 0.9'/'backend_weight2 = 0.2'/ /etc/pgpool2/pgpool.conf
[email protected]:~# grep backend_weight2 /etc/pgpool2/pgpool.conf
backend_weight2 = 0.2
[email protected]:~# pgpool reload
[email protected]:~$ (for i in $(seq 1 9); do psql -h localhost -p 5433 t -c "select current_setting('port') from ts limit 1" -XAt; done) | sort| uniq -c
      6 5401
      3 5402
Unduh Whitepaper Hari Ini Pengelolaan &Otomatisasi PostgreSQL dengan ClusterControlPelajari tentang apa yang perlu Anda ketahui untuk menerapkan, memantau, mengelola, dan menskalakan PostgreSQLUnduh Whitepaper

Besar! Fitur hebat berikutnya yang ditawarkan adalah connection pooling. Dengan 3.5 "masalah kawanan guntur" diselesaikan dengan membuat serial panggilan accept(), sangat mempercepat waktu "koneksi klien". Namun fitur ini cukup mudah. Itu tidak menawarkan beberapa level pooling atau beberapa pool yang dikonfigurasi untuk database yang sama (pgpool memungkinkan Anda untuk memilih tempat menjalankan pilihan dengan database_redirect_preference_list dari load balancing), atau fitur fleksibel lainnya yang ditawarkan oleh pgBouncer.

Demo yang sangat singkat:

t=# select pid,usename,backend_type, state, left(query,33) from pg_stat_activity where usename='vao' and pid <> pg_backend_pid();
 pid  | usename |  backend_type  | state |     left
------+---------+----------------+-------+--------------
 8911 | vao     | client backend | idle  |  DISCARD ALL
 8901 | vao     | client backend | idle  |  DISCARD ALL
 7828 | vao     | client backend | idle  |  DISCARD ALL
 8966 | vao     | client backend | idle  |  DISCARD ALL
(4 rows)
Hm - did I set up this little number of children?
t=# pgpool show num_init_children;
 num_init_children
-------------------
 4
(1 row)

Ah, benar, saya mengubahnya lebih rendah dari default 32, jadi hasilnya tidak akan memakan waktu beberapa halaman. Baiklah, mari kita coba melebihi jumlah sesi (di bawah ini saya membuka sesi postgres async in loop, sehingga 6 sesi akan diminta pada waktu yang kurang lebih bersamaan):

[email protected]:~$ for i in $(seq 1 6); do (psql -h localhost -p 5433 t -U vao -c "select pg_backend_pid(), pg_sleep(1), current_setting('port'), clock_timestamp()" &);  done
[email protected]:~$  pg_backend_pid | pg_sleep | current_setting |        clock_timestamp
----------------+----------+-----------------+-------------------------------
           8904 |          | 5402            | 2018-04-10 12:46:55.626206+01
(1 row)

 pg_backend_pid | pg_sleep | current_setting |        clock_timestamp
----------------+----------+-----------------+-------------------------------
           9391 |          | 5401            | 2018-04-10 12:46:55.630175+01
(1 row)

 pg_backend_pid | pg_sleep | current_setting |       clock_timestamp
----------------+----------+-----------------+------------------------------
           8911 |          | 5400            | 2018-04-10 12:46:55.64933+01
(1 row)

 pg_backend_pid | pg_sleep | current_setting |        clock_timestamp
----------------+----------+-----------------+-------------------------------
           8904 |          | 5402            | 2018-04-10 12:46:56.629555+01
(1 row)

 pg_backend_pid | pg_sleep | current_setting |        clock_timestamp
----------------+----------+-----------------+-------------------------------
           9392 |          | 5402            | 2018-04-10 12:46:56.633092+01
(1 row)

 pg_backend_pid | pg_sleep | current_setting |       clock_timestamp
----------------+----------+-----------------+------------------------------
           8910 |          | 5402            | 2018-04-10 12:46:56.65543+01
(1 row)

Ini memungkinkan sesi datang dengan tiga - diharapkan, karena satu diambil oleh sesi di atas (memilih dari pg_stat_activity) jadi 4-1=3. Segera setelah pg_sleep selesai tidur siang satu detik dan sesi ditutup oleh postgres, sesi berikutnya dibiarkan masuk. Jadi setelah tiga yang pertama berakhir, tiga langkah berikutnya masuk. Apa yang terjadi dengan sisanya? Mereka diantrekan sampai slot koneksi berikutnya kosong. Kemudian proses yang dijelaskan di sebelah serialize_accept terjadi dan klien terhubung.

Hah? Hanya pengumpulan sesi dalam mode sesi? Apakah itu semua?.. Tidak, ini langkah-langkah caching! Lihat.:

postgres=# /*NO LOAD BALANCE*/ select 1;
 ?column?
----------
        1
(1 row)

Memeriksa pg_stat_activity:

postgres=# select pid, datname, state, left(query,33),state_change::time(0), now()::time(0) from pg_stat_activity where usename='vao' and query not like '%DISCARD%';
  pid  | datname  | state |               left                | state_change |   now
-------+----------+-------+-----------------------------------+--------------+----------
 15506 | postgres | idle  | /*NO LOAD BALANCE*/ select 1, now | 13:35:44     | 13:37:19
(1 row)

Kemudian jalankan pernyataan pertama lagi dan amati state_change tidak berubah, yang berarti Anda bahkan tidak masuk ke database untuk mendapatkan hasil yang diketahui! Tentu saja jika Anda meletakkan beberapa fungsi yang bisa berubah, hasilnya tidak akan di-cache. Bereksperimenlah dengan:

postgres=# /*NO LOAD BALANCE*/ select 1, now();
 ?column? |             now
----------+------------------------------
        1 | 2018-04-10 13:35:44.41823+01
(1 row)

Anda akan menemukan bahwa state_change berubah seperti halnya hasilnya.

Poin terakhir di sini - mengapa /*NO LOAD BALANCE*/ ?.. untuk memastikan kami memeriksa pg_stat_activity pada master dan menjalankan kueri pada master juga. Anda juga dapat menggunakan petunjuk /*NO QUERY CACHE*/ untuk menghindari hasil yang di-cache.

Sudah banyak untuk review singkat? Tapi kami bahkan tidak menyentuh bagian HA! Dan banyak pengguna melihat ke pgpool khusus untuk fitur ini. Nah, ini bukan akhir dari cerita, ini adalah akhir dari bagian pertama. Bagian kedua akan datang, di mana kita akan membahas secara singkat HA dan beberapa tips lain dalam menggunakan pgpool...


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kapan memilih untuk memperbarui mengunci dan membuka kunci?

  2. Kesalahan Menginstal Psycopg2 di MacOS 10.9.5

  3. Cara mendapatkan PostgreSQL di VPS / Dedicated Server

  4. PostgreSQL EXPLAIN – Berapa Biaya Kueri?

  5. Memvalidasi Cadangan PostgreSQL Anda di Docker