Postgres – vsetko, co si chtel vediet, ale bal sa spytat svojho seniora, aby si nevypadal ako jelito 10. Pgbouncer.
Pgbouncer je koneksn pooler, pretoze postgres nativne nema tuto vlastnost a mnoho koneksii do DB moze viest k vycerpaniu pamati, ale dosiahnutiu max_connections v Postgres konfe a odmietnutiu sluzby. Skvele zdovodnenie pouzitia pgbounceru so zaujimavou diskusiou je tu. Vseobecne sa da povedat, ze mnozstvo klientov snaziacich sa pripojit, sa stava nepodstatnym, pretoze pgbouncer ich supne do poolu u seba a postupne pusta k databaze. Mnozstvo konnesn do DB je naopak nutne obozretne konfigurovat.
obecne
PGSQL postmaster obhospodaruje vsetky pokusy o pripojenie a pokial je uspesne, tak sa forkne na novy subproces, ktory sefuje spojeniu – az do doby, kedy ukonci spojenie aplikacia, alebo sam postmaster.
Pgbouncer ma vlastny pool na spojenia a sam si na zaklade nastavenia robi jeho management – spojenie vrati do svojho poolu a poskytuje ho dalej. Pri rotovani spojeni pouziva 3 typy poolovania:
- session pooling (default) – udrzuje spojenie po celu session.
- transaction pooling – po ukonceni transakcie ukonci spojenie a vrati ho do poolu
- statement pooling – po ukonceni query ukonci spojenie a vrati ho do poolu
Inak je to standardna servisa, s hlavnym konfigurakom v /etc/pgbouncer.ini. Podporuje SSL/TLS.
jak to funguje
Z hladiska klienta naprosto transparentne – zada sa koneksn string na pgbouncer presne ako na postgres a pgbouncer to len “premosti” ma odpovedajuci postgres v konfigu. Priklad: psql -h PGBOUNCER_HOST -d DATABAZA -U user (normalny DB user, pgboncer to potom prekonekti, vysvetlenie nizsie)
useri, hesla a auth_user
Pri standardnom pripojovani sa clovek/aplikacia hlasi k Postgresu DB uctom/heslom. Tu je vsak vsunuta “vrstva pgbounceru”, ktory musi urobit autentikaciu sam. Je riesenie jednoduche a nepruzne (useri a ich hesla v userlist.txt) a zlozitejsie a pruzne: mapovanie pomocou auth_user.
Jednoduche riesenie je napisat user= a password= do pgbouncer.ini napriamo, alebo do userlist.txt. Nevyhodou samozrejme je, ze kazdy uzivatel tu musi mat svoj riadok a pri zmene hesla v DB sa to musi osefovat aj v konfigurakoch. Inak tuto pracu za vas urobi skript mkauth.py, ktory naimportuje do suboru hashe hesiel z DB:
#postgres /etc/pgbouncer/mkauth.py /etc/pgbouncer/userlist.txt “host=DBHOST dbname=DBNAME”
Zlozitejsie riesenie vyuziva funkcionalitu auth_user a auth_query. V tomto pripade sa user neporovnava s konfigurakom, ale pomocou auth_usera (preduzivatel) sa spusti auth_query, ktora sa dopta na uzivatela a jeho heslo priamo v postgrese. Pokial sa zhoduju, tak spojenie je nadviazane a uzivatel je pusteny z pgbounceru do DB.
Zapis v pgbouncer.ini potom vypada asu takto>
db_spojenie = host=10.2.215.10 port=5432 dbname=NAZOV_DB max_db_connections=10 auth_user=app_pgbouncer pool_mode=session
pgbouncer pseudodatabaza
Okrem databaze, na ktory sa pgbouncer pripojuje, ma vlastnu preudoDB, ktora bezi na hoste, kde bezi aj pgbouncer (v pripade, ze na jednom hoste bezi DB i pgbouncer, tak bacha na konflikt portov, vtedy sa pgbouncer vacsinou konfiguruje na port 6432…)
K pseudoDB sa pripaja podobne, ako ku klasickemu postgresu, t.j. napr. psql -h /tmp -U app_pgbouncer pgbouncer (pripajanie na soket)
Prikazov nie je mnouho a sluzia ku sprave pgbounceru a monitoringu poolov a pod: SHOW POOLS; SHOW DATABASES; SHOW STATS; a pod… (SHOW HELP; pre vsetky)
pgbouncer pooling
Kedze pgbouncer tam pridava medzivrstvu a musi komunikovat na jednej strane s klientmi a na druhej strane s DB serverom, situacia ka komplikuje. Klient moze byt vo faze login, alebo cakajuci na login, moze byt vo faze active, alebo idle a pod. Aj spojenie so serverom moze byt v roznych fazach (login, active, idle) a pod. Skvele to vysvetluje tento clanok, z ktoreho je aj tento obrazok (mozne stavy klienta).
Stavy klienta a naplnenost pgbouncer poolu – prikaz SHOW POOLS; Velkost poolov zo strany DB – prikaz SHOW DATABASES;
- cl_active = klienti, ktori boli uspesne nakonekteni na pgbouncer a su aktivni.
- cl_waiting = klienti, ktori cakaju na spojenie s pgbouncerom, alebo uz su spojeni cakaju na pristup k databazi
- sv_active = spojenie medzi pgbouncerom a DB, ktore ma odpovedajuce klientske spojenie (pozor, nemusi zrovna nic robit, ako zapisy a ready a tak…)
- sv_idle = spojenie medzi bouncerom a DB, ktore nema aktivny link na klientske spojenie (v pripade potreby ho nhed poskyne)
- sv_used a sv_tested = suvisi s cekovanim, ci su spojenia vyuzivane
- sv_login = pocet pokusov o login z pgbouncera na DB
dolezite parametre v pgbouncer.ini
- pool_size = obmedzenie spojenie medzi poolom a DB (sv_* koneksien)
- max_db_connections = obmedzenie spojenia medzi vsetkymi poolmi a DB (sv_* koneksien)
pgbouncer a pgpool
Druhym najznamejsim poolerom je Pgpool, ale ja s nim nemam skusenosti. Rozdiely perfektne zhrnuje tento blogpost:
- pgbouncer je lepsi v pamati, poolovacich modoch, kontrole koneksi a autentikaci
- pgpool vie na rozdiel od pgbounceru HA, loadbalancing a ma GUI