sql >> Databáze >  >> RDS >> PostgreSQL

Průvodce Pgpool pro PostgreSQL:Část první

Pgpool je dnes méně aktuální než před 10 lety, kdy byl výchozí součástí produkčního nastavení PostgreSQL. Často, když někdo mluvil o PostgreSQL clusteru, měl na mysli postgreSQL za pgpool a ne samotnou instanci PostgreSQL (což je správný termín). Pgpool je uznáván mezi nejvlivnějšími hráči Postgres:komunita postgresql, commandprompt, 2ndquadrant, EDB, citusdata, postgrespro (řazeno podle věku, ne vlivu). Uvědomuji si, že úroveň uznání v mých odkazech je velmi odlišná – chci jen zdůraznit celkový dopad pgpoolu ve světě postgresu. Někteří z nejznámějších současných „prodejců“ postgres byli nalezeni poté, co byl pgpool již slavný. Čím je tedy tak slavný?

Už jen díky seznamu nejžádanějších nabízených funkcí vypadá skvěle:

  • nativní replikace
  • sdružování připojení
  • vyrovnávání zátěže pro škálovatelnost čtení
  • vysoká dostupnost (hlídací pes s virtuální IP adresou, online obnova a převzetí služeb při selhání)

No, uděláme si pískoviště a hrajeme si. Moje ukázkové nastavení je režim master slave. Předpokládal bych, že je dnes nejoblíbenější, protože obvykle používáte streamingovou replikaci spolu s vyrovnáváním zátěže. Režim replikace se v dnešní době téměř nepoužívá. Většina správců databází to přeskakuje a dává přednost streamovací replikaci a pglogic a dříve k slony.

Režim replikace má mnoho zajímavých nastavení a jistě zajímavou funkcionalitu. Ale většina DBA má nastavení master/multi slave v době, kdy se dostanou do pgpool. Hledají tedy automatické převzetí služeb při selhání a nástroj pro vyrovnávání zátěže a pgpool je ihned nabízí pro stávající prostředí master/multi slave. Nemluvě o tom, že od Postgresu 9.4 funguje streamingová replikace bez větších chyb a je podporována replikace 10 hash indexů, takže vám v jejím používání prakticky nic nebrání. Také streamingová replikace je ve výchozím nastavení asynchronní (lze konfigurovat na synchronní a dokonce ne „lineární“ synchronizace komplikovaná nastavení, zatímco replikace nativního fondu pgpool je synchronní (což znamená pomalejší změny dat) bez možnosti výběru. Platí také další omezení. Manuál Pgpool sám o sobě doporučuje preferovat pokud je to možné, streaming replikace přes pgpool nativní). A toto je moje volba zde.

Ach, ale nejdřív to musíme nainstalovat - ne?

Instalace (vyšší verze na ubuntu).

Nejprve zkontrolujte verzi ubuntu pomocí lsb_release -a. Pro mě je repo:

[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

Nakonec samotná instalace:

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

Konfigurace:

Používám výchozí konfiguraci z doporučeného režimu:

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

Začátek:

Pokud jste zmeškali konfiguraci, uvidíte:

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

Ach pravda – moje špatné, ale snadno opravitelné (lze provést naslepo s jednou vložkou, pokud chcete stejného uživatele pro všechny zdravotní kontroly a zotavení):

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

A než půjdeme dále, vytvoříme databáze pgpool a uživatelský pgpool ve všech clusterech (v mém sandboxu jsou master, failover a slave, takže to potřebuji spustit pouze na master):

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

Konečně – začíná:

[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

Skvělé – takže můžeme přejít k první funkci – zkontrolujeme vyrovnávání zátěže. Má určité požadavky na použití, podporuje rady (např. pro vyvážení ve stejné relaci), má funkce na černobílém seznamu, má seznam předvoleb přesměrování založený na regulárních výrazech. Je to sofistikované. Bohužel všechny tyto funkce by byly mimo rozsah tohoto blogu, proto zkontrolujeme nejjednodušší ukázky:

Nejprve něco velmi jednoduchého ukáže, který uzel se používá pro výběr (v mém nastavení se master točí na 5400, slave na 5402 a failover na 5401, zatímco samotný pgpool je na 5433, protože mám spuštěný jiný cluster a nechtěl jsem zasahovat s tím):

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

Pak ve smyčce:

[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

Skvělý. Rozhodně vyrovnává zatížení mezi uzly, ale zdá se, že nevyvažuje rovnoměrně – možná je tak chytrý, že zná váhu každého prohlášení? Pojďme zkontrolovat distribuci s očekávanými výsledky:

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)

Ne - pgpool neanalyzuje váhu prohlášení - byl to opět DBA s jejím nastavením! Nastavení (viz atribut lb_weight) je v souladu se skutečnými cíli cíle dotazu. Můžete jej snadno změnit (jako jsme to udělali zde) změnou odpovídajícího nastavení, např.:

[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
Stáhněte si Whitepaper Today Správa a automatizace PostgreSQL s ClusterControlZjistěte, co potřebujete vědět k nasazení, monitorování, správě a škálování PostgreSQLStáhněte si Whitepaper

Skvělý! Další skvělou nabízenou funkcí je sdružování připojení. Ve verzi 3.5 je „problém s hromovým stádem“ vyřešen serializací volání accept(), což výrazně zrychluje dobu „připojení klienta“. A přesto je tato funkce docela přímočará. Nenabízí několik úrovní sdružování nebo několik fondů konfigurovaných pro stejnou databázi (pgpool vám umožňuje vybrat, kde chcete spouštět výběry pomocí database_redirect_preference_list of load balancing), ani jiné flexibilní funkce nabízené pgBouncer.

Takže krátké demo:

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)

Ach, pravda, změnil jsem je na nižší než výchozích 32, takže výstup nezabere několik stránek. Zkusme tedy překročit počet relací (níže otevírám postgresové relace asynchronně ve smyčce, takže 6 relací bude požadováno víceméně ve stejnou dobu):

[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)

Umožňuje, aby relace přišly o tři - očekávané, protože jedna je přijímána výše uvedenou relací (výběr z pg_stat_activity), takže 4-1=3. Jakmile pg_sleep dokončí své druhé zdřímnutí a relace je ukončena postgresem, další je vpuštěna dovnitř. Takže po skončení prvních tří nastoupí další tři. Co se stane se zbytkem? Jsou zařazeny do fronty, dokud se neuvolní další připojovací slot. Poté proběhne proces popsaný u serialize_accept a klient se připojí.

co? Pouze sdružování relací v režimu relací? Je to všechno?... Ne, zde zasahuje ukládání do mezipaměti! Podívejte.:

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

Kontrola 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)

Poté znovu spusťte první příkaz a pozorujte, že se state_change nemění, což znamená, že se ani nedostanete do databáze, abyste získali známý výsledek! Samozřejmě, pokud vložíte nějakou měnitelnou funkci, výsledky se nebudou ukládat do mezipaměti. Experimentujte s:

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

Zjistíte, že state_change se mění stejně jako výsledek.

Poslední bod zde - proč /*NO LOAD BALANCE*/ ?.. pro jistotu zkontrolujeme pg_stat_activity na masteru a spustíme dotaz i na masteru. Stejně tak můžete použít nápovědu /*NO QUERY CACHE*/, abyste se vyhnuli získání výsledku uloženého v mezipaměti.

Už hodně na krátkou recenzi? Ale ani jsme se nedotkli části HA! A mnoho uživatelů hledá pgpool speciálně pro tuto funkci. No, toto není konec příběhu, toto je konec první části. Blíží se druhá část, kde se krátce zaměříme na HA a některé další tipy na používání pgpool...


  1. Jak velký dopad může mít výběr datového typu?

  2. Obchodní logika:Databázová nebo aplikační vrstva

  3. Jak mohu opravit tuto chybu:není podporován SQL92?

  4. Vytvořte Multi-Statement Table-Valued Function (MSTVF) v SQL Server