PostgreSQL - zvládne 400m řádků?

PostgreSQL - zvládne 400m řádků?
« kdy: 28. 12. 2021, 12:57:31 »
Zdar,

mam jednu PostgreSQL tabulku s touhle strukturou a 400 miliony radku:

id (autoinc), 10x text (max 256zn.), 10x jsonb (max par tisic znaku)

Na par text sloupeccich je dany index.

Jaky potrebuji HW, nebo co a jak tam nastavit, aby to zvladalo kolem 1k SELECT/UPDATE/INSERT dotazu (tj. 3k dotazu) za vterinu soucasne (a tohle bude muset bezet "nonstop").

Dotazy se vazi na jeden text sloupecek jako identifikator (je unikatni ale je na nem index), zadne slozite veci u toho dotazu nejsou.
Zkousel jsem to na serveru se ssd disky a 64gb ram a... tfujky, absolutne to nedava.
S ohledem na obsah tabulky by ji asi neslo rozdelit do vice tabulek.

Co s tim? Klidne muzu vymenit za jinou db, ale radeji bych zustal u PostgreSQL.
« Poslední změna: 28. 12. 2021, 13:38:58 od Petr Krčmář »


Re:PostgreSQL - zvladne 400m radku?
« Odpověď #1 kdy: 28. 12. 2021, 13:18:06 »
400 milionů řádků PostgreSQL obecně zvládne. Nicméně nepíšete nic dalšího o těch dotazech – ten SELECT potřebuje všechna data z řádku tabulky, nebo jenom některá? Update hledá podle toho unikátního identifikátoru? Jaký je poměr insert/update/select? Jaký index na tom unikátním sloupečku máte?

Jinak pokud je to jeden dokument hledaný na základě primárního klíče, hodila by se na to víc nějaká NoSQL databáze. Ale záleží na tom, jak přesně se s těmi daty pracuje – bez toho se nedá posoudit, co případně na PostgreSQL ladit.

RDa

  • *****
  • 2 674
    • Zobrazit profil
    • E-mail
Re:PostgreSQL - zvladne 400m radku?
« Odpověď #2 kdy: 28. 12. 2021, 13:51:20 »
Me to prijde ze nevite co delate... rekneme ze 10*256 + 10*5000(cca) = 50KB na radek x 400M = 20 TB dat.
(3K dotazu nad 50K radky dela cca 150MB/s traffic, cca)

V cem by vam melo pomoct 64GB ram jako? :))

Nejspis vam ten index nefunguje tak, jak si predstavujete, a nejdrazsi operace nad 400M index stromem bude patrne insert s rebalancingem indexu.

Osobne bych to resil rozdelenim na 256 az 4K tabulek, tj. spocital 8 az 12-bit hash vaseho primarniho klice, a pak dale operoval nad danou tabulkou, ktera bude mit 1.5M az 100K radku kazda, kde ten prepocet indexu po insertu nebude tak drahej.

Nasledne si udelejte benchmark, kolik jakych operaci jste schopen provest nad tou mini-tabulkou na 1 cpu jadru a 1 disku. Vyjde vam ze treba 100 cteni, 50 updatu, nebo 20 insertu. Z toho vidite ze potrebujete pro 1K dotazu 10 R cpu, 20 U cpu, 50 I cpu, dohromady 10+20+50 = 80 jader.

Bottleneck u storage nejspis nebude, pokud tech 20T udelate nad SSD, ale to zjistite az udelate mereni vykonu s daty ktere predstavuji realny use-case.

Reseni je tedy iterativni... postavit, nasimulovat, zmerit, opravit, a znova.

Re:PostgreSQL - zvládne 400m řádků?
« Odpověď #3 kdy: 28. 12. 2021, 14:16:14 »
Jaky potrebuji HW, nebo co a jak tam nastavit, aby to zvladalo kolem 1k SELECT/UPDATE/INSERT dotazu (tj. 3k dotazu) za vterinu soucasne (a tohle bude muset bezet "nonstop").
Stejně jako všichni ostatní musím říct: toto je dotaz úplně k ničemu, protože nikdo neví co to znamená "1k SELECT/UPDATE/INSERT". Je naprosto zásadní rozdíl zda to znamená "1000x SELECT za sekundu, sem tam nějaký UPDATE" nebo "1000x za sekundu se provede transakce SELECT+UPSERT".

Nicméně tipuji že asi to druhé, protože to první by se opravdu nemělo dát zadýchat (ani s opravdu debilně zvolenými indexy). To druhé, ovšem... to je něco na co typicky není ani HW ani SW typicky připraveno (zápis je pomalý, zvlášť když se má zaručit ACID). V každém případě bych doporučil začít tím že místo SELECT/UPDATE/INSERT se použije MERGE (ale nemám takové zkušenosti s tím zda to v postgresu konkrétně pomůže). Dále pak co nejméně indexů, a pokud možno filtrovaných. A samozřejmě revidovat datový model...  10xVARCHAR(256) vyloženě bije do očí jako "EAV-lite".

Pokud ten model nejde nijak relačně reprezentovat, tak možná použití specializované databáze by nebylo od věci. Některé dokumentové db mají automaticky sharding, který při intenzivním zápisu fakt pomůže (s tím že místo jednoho 64GB serveru bude několik menších).

Na par text sloupeccich je dany index.
Jeden index na sloupeček? To pravděpodobně není úplně to pravé a asi by bylo lepší použít vícesloupcový index. Plus: pokud se opravdu často a hodně zapisuje, tak platí že čím méně indexů, tím lépe. Ale to se fakt nedá takhle na náhodném fóru radit.

Re:PostgreSQL - zvládne 400m řádků?
« Odpověď #4 kdy: 28. 12. 2021, 14:42:44 »
Zdar,

mam jednu PostgreSQL tabulku s touhle strukturou a 400 miliony radku:

id (autoinc), 10x text (max 256zn.), 10x jsonb (max par tisic znaku)

Na par text sloupeccich je dany index.

Jaky potrebuji HW, nebo co a jak tam nastavit, aby to zvladalo kolem 1k SELECT/UPDATE/INSERT dotazu (tj. 3k dotazu) za vterinu soucasne (a tohle bude muset bezet "nonstop").

Dotazy se vazi na jeden text sloupecek jako identifikator (je unikatni ale je na nem index), zadne slozite veci u toho dotazu nejsou.
Zkousel jsem to na serveru se ssd disky a 64gb ram a... tfujky, absolutne to nedava.
S ohledem na obsah tabulky by ji asi neslo rozdelit do vice tabulek.

Co s tim? Klidne muzu vymenit za jinou db, ale radeji bych zustal u PostgreSQL.

U téhle velikosti to už chce používat partitioning, a při nonstop zátěži 1K DML a 3K SELECTů za sec to už chce i vymyslet nějaké horizontální škálování. Minimálně potřebujete vacuovat tabulky, a budete potřebovat reindexaci. Update velkých tabulek je dost drahá záležitost - zvlášť pak když jsou bloatlý indexy. 1000 DML za sec nekolika kb jsonu - to musí být peklo. To vám pomalu nemůžou dát ani ta SSDčka.

Můžete zkusit MySQL - UPDATE tabulky s větším množstvím oindexovaných sloupců je na MySQL rychlejší. Nicméně je otázkou, co se vám vejde do paměti, a jak často budete muset hrabat na disk. I pro MySQL platí, že pro rychlý přístup musí být drtivá většina dat v RAMce. Pro ten požadovaný výkon musíte mít dotazy hodně pod 10 ms, spíš pod ms, takže to chce hodně RAM, hodně IOPS, a hodně CPU.
« Poslední změna: 28. 12. 2021, 14:51:40 od Pavel Stěhule »


Re:PostgreSQL - zvládne 400m řádků?
« Odpověď #5 kdy: 28. 12. 2021, 14:52:51 »
Pokud to je fat 1000 insertu a 1000 updatu/s nad tabulkou s 400M radky a "nekolika indexy nad varchary", tak si pripravte  spoustu $$$. To je 2000*"nekolik"/s zmen indexu s mohutnosti 400M nad varcharem, ktere se budou casto rebalancovat a kazdy takovy rebalanc muze zpusobit stovky IOPS. A to pocitam, ze update meni vzdy jen jeden radek.

Nekdo tady, psal, ze to bude vadnout na CPU ale to pochybuji - zvadne to na zapisovych IOPS.

Re:PostgreSQL - zvládne 400m řádků?
« Odpověď #6 kdy: 28. 12. 2021, 18:21:20 »
A co takhle to celé udržet v paměti a každý záznam mít zkomprimován.

Při stroji se 128GB RAM by zbylo na jeden záznam 343B, při 2 strojích 686B ...

varchar(256) neříká, jaká je průměrná délka a alokovat na maximální velikost je neefektivní.

Pokud tam bude standardní text, tak je možné to zkomprimovat huffmanem např. na 5bitů na znak

Není tam nějaká znovuvyužitelnost dat mezi řádky? Jako že by se dal uložit jen hash obsahu a ten obsah už by se získal odjinud na základě hashe?

Re:PostgreSQL - zvládne 400m řádků?
« Odpověď #7 kdy: 28. 12. 2021, 22:31:30 »
Pošlete vzorek dat a sql dotazy, které jste zkoušel. Jak jste testoval?