Fulltext se slovníky ve sdílené paměti

Pokud používáte fulltext zabudovaný do PostgreSQL a vzhledem k povaze jazyka vám nestačí řešení založené na snowballu (což funguje dobře pro angličtinu, ale například pro češtinu nic takového s rozumnou přesností neexistuje a asi ani existovat nebude), jste víceméně nuceni používat ispell slovníky. V tom případě jste si určitě všimli dvou nepříjemných vlastností.

Slovníky se načítají do paměti jednotlivých spojení (backendů), tj. každé spojení při prvním dotazu stráví netriviální čas parsováním souborů se slovníkem, a každé spojení si drží vlastní kopii. Pokud naparsovaný slovník zabere např. 25MB (a to není nic výjimečného) a máte třeba 20 spojení která se alespoň jednou dotkla fulltextu, rázem vám zmizí 500 MB paměti (což např. na VPS není málo).

Existují řešení jak toto řešit - např. použitím connection poolu s již inicializovaným fulltextem (tj. šetříte CPU ale plýtváte pamětí), vyhrazením několika persistentních spojení pro fulltext (ale s tím se zase hůř pracuje). Existují asi i další možnosti které mne teď nenapadají, ale nic z toho není ideální ...

Nedávné problémy právě s fulltextem mne vyprovokovaly k napsání extension která umožňuje sdílení slovníků ve sdílené paměti. Ani toto řešení není dokonalé (více na konci článku), ale rozhodně je to krok správným směrem. Takže jak to funguje a co to vlastně umí?

Connection limits - proof of concept

Čas od času se někdo v mailing listu zeptá jestli existuje způsob jak omezit počet spojení podle IP adresy, databáze nebo uživatele. Ne, nic takového v core implementováno není, ačkoliv by to byla velmi užitečná vlastnost zejména clustery sdílené více uživateli (aplikacemi, zákazníky, ...). Podobné quoty lze někdy dostatečně implementovat pomocí connection pooleru jako je pgbouncer nebo věcí jako je netfilter connlimit, ale obě řešení mají určité nevýhody.

Ale! Máme přeci věcičky kterým říkáme "extensions", "hooky" a "sdílené knihovny." Minulý týden jsem napsal jednoduchý "proof of concept" extension která používá "client auth hook" a umožňuje vám nastavit omezení počtu spojení podle různých kritérií. Není to dokonalé (viz. dále), ale funguje to celkem pěkně. Zatím je dostupná na githubu a až opravím zbývající drobnosti tak ji publikuji na pgxn.

PS: Díky Magnusovi za upozornění že existuje "client auth hook" který by se možná dal použít, a  TL za upozornění jak neuvěřitelně ošklivý hack byla původní verze extension.

Výpočet kvantilů a ořezávajících agregačních funkcí

Pokud jste někdy někdy potřebovali počítat medián nebo jiné kvantily, pravděpodobně už jste zjistili že přímo v PostreSQL odpovídající agregační funkce zabudována není. Jsou dostupná různá externí řešení s různou flexibilitou a výkonem - dovolte mi jmenovat alespoň řešení Joea Conwaye založené na PL/R a depeszovo PL/pgSQL řešení. Osobně jsem s žádným z těchto řešení nebyl příliš spokojen ale protože jsem poněkud línější tak jsem nenapsal nic vlastního ... až do minulého týdne. Extension (již dostupná na pgxn) je založena na poněkud nechutné fintě (podrobněji dále), ale zdá se že to funguje, zejména pokud se jedná o výkon.

Když jsem dokončil zmíněnou extension, uvědomil jsem si že bych stejný trik mohl použít k implementaci ořezaných agregačních funkcí - nevím jestli je to správný termín, nicméně znamená to něco jako "odstraň 3% nejnižších hodnot, 2% nejvyšších hodnot a ze zbytku spočítej AVG/VARIANCE." V podstatě se jedná o elegantní způsob jak se zbavit "outliers" tj. hodnot které leží velmi daleko od ostatních. I tato extension je již dostupná na pgxn.

Sběr histogramu dotazů

Pokud používáte PostgreSQL a potřebujete sledovat výkonnostní anomálie, znáte asi konfigurační volbu log_min_duration a možná i auto_explain modul, které vám umožňují nějakým způsobem reagovat na výskyt dotazů pomalejších než stanovený limit. To je samozřejmě výborná věc, ale má to jeden drobný háček - jak stanovit vhodnou hranici, zejména pokud je doba běhu jednotlivých dotazů velmi různorodá?

Pokud hranici stanovíte příliš nízko, získáte obří logy s velkým množstvím dotazů. Naopak pokud ji stanovíte příliš vysoko, nebudete mít možnost zaznamenat změny u rychlejších dotazů. Co když máte hranici nastavenu na 200ms ale změna se uděje pod touto hranicí, tj. co když dotazy které původně trvaly 50ms náhle trvají 150ms? Doba zpracování se efektivně ztrojnásobila ale nic se nezaloguje ...

Výsledky benchmarku na SSD - TPC-H

Podíváme-li se na srovnání SSD s tradičním pevným diskem v TPC-H části benchmarku, zjistíme že zvýšení výkonnosti je ještě menší než u read-write pgbench zátěže. Například při srovnání m-time (tj. času spotřebovaného pro vyhodnocení stejně naplánovaných dotazů, podrobněji je definováno v článku o výsledcích TPC-H benchmarku na standardním disku) vypadá na SSD s XFS situace takto

výkon XFS (m-time) se SSD diskem

zatímco na standardním rotačním pevném disku takto

výkon XFS (m-time) s tradičním diskem

tj. SSD disk je jen zhruba 1,5x rychlejší než tradiční rotační disk (což je výrazně horší výsledek než u read-only/read-write pgbenche kde byl nárůst 25x/13x). I pro SSD disk nicméně platí pravidlo že nejlepšího výkonu je dosahováno pro velké databázové bloky a velikost bloků souborového systému nehraje příliš zásadní roli.

Výsledky benchmarku na SSD - read-write pgbench

Takže se podívejme na další SSD výsledky - read-write pgbench. Stejně jako v případě read-only benchmarku platí že výsledky jednotlivých souborových systémů jsou téměř totožné, ale od

BTW v předchozím postu jsem zapomněl zmínit jednu důležitou věc - pokud máte zájem o data sesbíraná během benchmarku, rád vám je poskytnu. Má to jednu technickou chybičku - výsledky pro HDD mají 3.4GB (komprimované 1GB), výsledky pro SSD dokonce 38GB (10GB komprimované), což je příliš mnoho než abych to umístil na tenhle blog. Ale pokud pojedete na pgconf.eu do Amsterdamu, stačí si o data říct ...

Výsledky benchmarku na SSD - read-only pgbench

V předchozích několika postech jsem se zabýval výsledky benchmarku na tradičním SATA pevném disku, v několika následujících se budu věnovat výsledkům stejných testů na SSD disku. Konkrétně v tomto postu se jedná o read-only pgbench benchmarku. Výkon na SSD ve všech testech dle očekávání výrazně narostl, je ale zajímavé sledovat jak se nárůst výkonu mění v závislosti na typu benchmarku a jak se téměř dokonale stírají rozdíly mezi různými souborovými systémy.

Průměrný výsledek přes všechny souborové systémy vypadá takto:

průměrný read-only výkon na SSD

 Výsledky pro SSD jsou již dostupné zde, konkrétně srovnání read-only výkonu je zde.

Výsledky benchmarku / HDD + TPC-H

Minulý týden jsem stručně analyzoval read-only a read-write OLTP část benchmarku, nyní tedy tak přichází na řadu část benchmarku věnovaná DWH/DSS zátěži, založená na TPC-H benchmarku. Nebudu vás napínat, výsledky pro jednotlivé velikosti bloků jsou takovéto

m-score přes všechny souborové systémy

Podrobný popis definice a výpočtu m-score najdete v textu, pro tuto chvíli stačí vědět že vyšší hodnoty znamenají vyšší výkon. Z obrázku je jasně patrné že čím větší bloky (souborového systému i databáze), tím vyšší výkon při vyhodnocování dotazů.

Platí to ale i pro další činnosti obvyklé v DWH aplikacích, tj. load dat, vytváření indexů a cizích klíčů, sběr statistik apod.? A platí to pro všechny souborové systémy nebo existují výjimky?

Výsledky benchmarku / HDD + read-write pgbench

Minule jsem se zabýval výsledky read-only pgbench běhů, tentokrát je tak na řadě read-write zátěž. Průměrná hodnota tps přes všechny souborové systémy vypadá se zapnutými write bariérami takto

průměrný výkon s read-write zátěží a zapnutými write bariérami

Z obrázku je vidět že stejně jako v případě read-only zátěže platí že vyššího výkonu je dosahováno spíše s menšími databázovými bloky, a i tentokrát mezi 1kB a 32kB bloky cca 30%.

Výsledky benchmarku / HDD + read-only pgbench

V předcházejícím postu jsem se stručně zabýval výsledky benchmarku, zejména tomu jak interpretovat generované obrázky. Nyní se konečně dostávám k interpretaci první části výsledků, konkrétně read-only části OLTP zátěže (tj. výsledků read-only běhů pgbenche).

Srovnání TPS přes všechny testované souborové systémy (podrobné srovnání najdete zde), při vynechání XFS (jediný systém s blokem 512B, jen zbytečně komplikuje obrázek) vypadá situace takto

průměrná read-only tps přes všechny souborové systémy

Z obrázku je patrné že nejvyššího výkonu je dosahováno pro malé databázové bloky a velké bloky souborového systému. Závislost na velikosti bloku souborového systému ale není u všech souborových systémů stejně silná - u některých téměř neexistuje, u některých je relativně silná.

1 2 3