Fórum Root.cz
Hlavní témata => Server => Téma založeno: Trupik 02. 05. 2018, 19:18:23
-
Ahoj lidi,
řeším (zatím jenom teoreticky, do budoucna nejspíš i prakticky :( ) následující věc:
mám nějaké zařízení, které ukládá data o své produkci do databáze. Nic světoborného, nějaké ty int, float, varchar... celkem pár kB dat na dotaz. Jenže zařízení požaduje potvrzení že se uložila správně a požaduje po databázi ID řádku kam se data uložila a potvrzení požaduje do velmi krátké doby od odeslání dotazu - třeba do 100ms. Pokud odpověď nedostane, zastaví se s chybou. Až sem OK.
Jenže těchto údajů jsou milióny a databáze pěkně narůstá. No a někdo si bude chtít udělat statistiku výroby a nechá si udělat dump celé databáze, což server při takto velké databázi zaručeně zaměstná na déle než oněch 100ms => výrobní zařízení nahlásí chybu a zastaví se.
Můj dotaz:
je nějaká možnost jak prioritizovat dotazy? Moje hodně naivní a zjednodušená myšlenka je taková, že by dotazy od uživatele X (výrobní zařízení) měli TOP prioritu a vykonávaly se přednostně, kdežto dotazy od uživatele Y by měly nízkou prioritu a v případě že by uživateli Y běžel náročný dotaz (třeba ten dump celé db) a zároveň by přišel dotaz od uživatele X, tak by se dotaz uživatele Y zpomalil/pozastavil aby se stihl provést přednostní dotaz?
-
Nepíšete, o jakou databázi se jedná.
Nicméně, toto zajistit nejde, kvůli lockům nedostanete přístup pro zápis, tudíž ani nezískáte ID řádku.
Chyba je v ovládacím SW toho stroje, který spoléhá na něco, co nejde zaručit.
Máte dvě možnosti:
a) ochránite databázi maximálně od operací, které ji mohou zamykat (a práci s daty budete provádět třeba jen na replice, kterou získáte bez přerušení provozu),
b) (vhodněji) upravíte SW stroje, aby nespoléhal na takovou pošetilost (většinou se dává tolerance prodlevy pár sekund, tj. X zpráv, které budou ACK až po určité době); vhodné je implementovat i zprávu NACK, aby stroj věděl s co nejmenší prodlevou, kdy nastane opravdu situace rychle zastavit.
-
Řešili jsme to replikací.
Byla master databáze. Zápis do ní byl prioritní.
Následně byly slave databáze, do kterých se nezapisovalo, ale četlo, s tím, že data mohou mět určité spoždění oproti autoritativnímu masteru.
-
Podle toho, co píšete, nechcete prioritizovat dotaz, ale zápis. Nepíšete nic o konkrétní databázi. Nejrychlejší je ty zápisy směrovat do nějaké vstupní fronty, žurnálu, kam se budou jen maximální možnou rychlostí sypat nové záznamy (a přidělovat jim ID), a odsud se budou asynchronně zapisovat do hlavní databáze. Existují speciální typy NoSQL databází určené právě pro fronty. Předpokládá to ale, že to zařízení, které data zapisuje, neočekává, že hned po potvrzení zápisu bud mít data v hlavní databázi. Pokud by musela být splněna i taková podmínka, pak nezbývá, než data pro ty náročné dotazy (statistiky) odlévat do repliky a statistiky dělat nad replikou.
-
Zamyslet se nad tím, proč mít stejnou databázi pro zápis a pro dotazy? Skutečně musejí všechny dotazy obsahovat i ty nejnovější události?
Co třeba eventsourcing?
Nebo psát do nějaké spolehlivé fronty (Kafka?) a z ní teprve dumpovat do databáze? Nebo i jinam - nějaké dotazy mohou běžet nad SQL, jiné nad HDFS ve Sparku, jiné streamovaně ve Sparku. Záleží na okolnostech, aby člověk netahal kanón na vrabce, ale ani flusbrok na hrocha.
-
Díky za odpovědi.
Zatím je to tak, že tuto problematiku řeším opravdu na teoretické úrovni, ale jsem si jistý že během pár týdnů/měsíců dostanu bojový úkol a z teorie se bude muset stát praxe, tak chci mít promyšlené co největší množství možných řešení ať se mi potom lépe volí to "nejlepší".
Nebráním se žádným nápadům; snad až na úpravu SW - soudruzi z NDR jsou na ten šmejd strašně pyšní (i když osobně nechápu proč ???) ale i to by mohla být cesta když to nepůjde jinak...
Nad replikací jsem už také uvažoval - to že v dumpu pro kedlubny nebude posledních pár desítek záznamů není podstatné a asi by to bylo i jedno z těch jednodušších řešení.
Ta vstupní fronta je také pěkný nápad - to mě zatím vůbec nenapadlo :)
Schválně píšu v obecné rovině, neudávám žádné technologie - ty se budu snažit volit na poslední chvíli tak, aby co nejvíce vyhovovaly reálným podmínkám které ani já zatím neznám všechny protože se to pořád mění a upravuje.
Ještě jednou díky
-
Ta vstupní fronta by se dala realizovat například v databázi Redis, která má velmi rychlou odezvu a navíc má na frontu přímo vhodný datový typ.
-
Ta vstupní fronta by se dala realizovat například v databázi Redis, která má velmi rychlou odezvu a navíc má na frontu přímo vhodný datový typ.
Pokud na tech datech nezalezi, tak to neni spatna varianta. Samozrejme performance je o neco horsi, nez je tlacit do /dev/null ;-)
-
Ta vstupní fronta by se dala realizovat například v databázi Redis, která má velmi rychlou odezvu a navíc má na frontu přímo vhodný datový typ.
Pokud na tech datech nezalezi, tak to neni spatna varianta. Samozrejme performance je o neco horsi, nez je tlacit do /dev/null ;-)
Redis není Memcache, dá se na něj spolehnout.
-
Neumí ta DB to ID vrátit přímo v tom DML příkazu ? Něco takovéhoto:
INSERT INTO t1 VALUES (t1_seq.nextval, 'FOUR') RETURNING id INTO l_id;
-
Ta vstupní fronta by se dala realizovat například v databázi Redis, která má velmi rychlou odezvu a navíc má na frontu přímo vhodný datový typ.
Pokud na tech datech nezalezi, tak to neni spatna varianta. Samozrejme performance je o neco horsi, nez je tlacit do /dev/null ;-)
Redis není Memcache, dá se na něj spolehnout.
Vážně má at least once nebo exactly once sémantiku? (Netvrdím, že je vždy potřeba. Jen že člověk nesmí mít k těm datům moc osobní vztah.)
Update:
"RDB is NOT good if you need to minimize the chance of data loss in case Redis stops working (for example after a power outage)."
https://redis.io/topics/persistence
-
Neumí ta DB to ID vrátit přímo v tom DML příkazu ? Něco takovéhoto:
INSERT INTO t1 VALUES (t1_seq.nextval, 'FOUR') RETURNING id INTO l_id;
A to řeší co přesně, když databáze nestíhá?
-
Redis není Memcache, dá se na něj spolehnout.
S tím nezbývá než souhlasit. Mé platonické pokusy o nějaké využití toho křápu (jednalo se o data z ntopng) skončily pravidelně a zcela spolehlivě tím, že databázi bylo nutné zlikvidovat a vytvořit znova, a to nejpozději po pár týdnech. Prostě se to samo od sebe neopravitelně zhroutilo.
-
Neumí ta DB to ID vrátit přímo v tom DML příkazu ? Něco takovéhoto:
INSERT INTO t1 VALUES (t1_seq.nextval, 'FOUR') RETURNING id INTO l_id;
A to řeší co přesně, když databáze nestíhá?
Ono ale vůbec není jasné, co vlastně ta databáze nestíhá a jak ta databáze vypadá. Existují různé architektury databází a v některých z nich opravdu není důvod, aby byl zápis kvůli konkurenci blokován čtením. Já jsem si zpočátku při čtení dotazu také myslel, že je problém v konkurenci SQL dotazu, který vyzvedává přidělené ID, s jinými dotazy. Protože otázka je, jak prioritizovat dotazy – a je jenom náš dohad, že Trupik nechce prioritizovat dotazy, ale zápis. Takže pokud je použita databáze s architekturou, kde čtení neblokuje zápis, a problém aplikace je v tom, že po zapsání záznamu jej znova čte, aby získala ID, bylo by to výše uvedené velice dobré řešení. Akorát to z pozdější Trupikovy odpovědi vypadá, že míří jiným směrem a že označení zápisu jako „dotaz“ bylo jen nešikovné vyjádření (někdy se „dotaz“ opravdu používá i pro modifikující operace).
-
Redis není Memcache, dá se na něj spolehnout.
"RDB is NOT good if you need to minimize the chance of data loss in case Redis stops working (for example after a power outage)."
Neznám nikoho, kdo by produkční databázový server provozoval bez UPS.
-
100ms je celkom dlha doba aj na vacsie tabulky (10m+ riadkov)
Nenapisal si nic na zaklade coho sa da rozhodnut:
- o aku db sa jedna?
- na com to bezi, system, zelezo, disky, siet rychlost, siet odozva, mas tam HA?
- vie ten producent dat pouzivat ine rozhranie ako sql?
- mozes stratit vyprodukovane data?
- kolko je producentov ?
- ako casto sa robi ten listing?
Otazky na ktore si musis sam odpovedat:
- kolko si ochotny investovat peniazi? novy hw, licencie, dodavatel
- kolko si ochotny investovat casu? implementacia, udrzba
- co sa stane ak sa to pokazi?
Mozne riesenia:
- generovat id na tom producentovi dat
- vypnut indexy
- zapnut mvcc
- replikacia
- pouzivat mq - na taketo veci to bolo vymyslene - da sa to aj cez sql implementovat, nebude to najkrajsie ale funguje to ak nemas ine ako sql rozhranie. spominany redis ma podporu pub/sub, ale existuju aj lepsie riesenia
- pouzit asynchronne query - nie najlepsi napad bo mozes prijst o data
-
100ms je na zapis strasne vela, skontroloval by som indexy a constrainty tabulky.
Mozne rienie je sypat to do tabulky, ktora indexy nema a nasledne to prelievat do tej spravnej (alebo pouzit materializovany pohlad).
Ina moznost ak je to mozne nepouzivat int ID ale GUID-y a generovat ich v aplikacii a udaje posielat do fronty.
Ak to musia byt ID-cka, tak pouzit sekvenciu na ich generovanie, ci rovno HiLo pattern.
-
"RDB is NOT good if you need to minimize the chance of data loss in case Redis stops working (for example after a power outage)."
Neznám nikoho, kdo by produkční databázový server provozoval bez UPS.
Moze sa pokazit nieco za UPS(zdroj, MB,...), moze sa pokazit samotna UPS,....
-
Dobré ráno/dopoledne.
Tak jak jsem psal - už za mnou oficiálně přišel šéf že by bylo potřeba... ;D
Nakonec to dopadlo tak, že půjdu cestou nejmenšího odporu - replikaci na druhý server. Vzhledem k tomu že těm nad sebou se stejně nezavděčím a soudruzi v NDR do toho prý chtějí intenzivně kafrat, tak tento úkol s radostí předávám svému kolegovi který umí německy - ať si to vyžere on. 8)
Ale i tak díky za nápady, zase jsem si trošku rozšířil obzory.
-
100ms je celkom dlha doba aj na vacsie tabulky (10m+ riadkov)
Nenapisal si nic na zaklade coho sa da rozhodnut:
- o aku db sa jedna?
- na com to bezi, system, zelezo, disky, siet rychlost, siet odozva, mas tam HA?
- vie ten producent dat pouzivat ine rozhranie ako sql?
- mozes stratit vyprodukovane data?
- kolko je producentov ?
- ako casto sa robi ten listing?
Otazky na ktore si musis sam odpovedat:
- kolko si ochotny investovat peniazi? novy hw, licencie, dodavatel
- kolko si ochotny investovat casu? implementacia, udrzba
- co sa stane ak sa to pokazi?
Mozne riesenia:
- generovat id na tom producentovi dat
- vypnut indexy
- zapnut mvcc
- replikacia
- pouzivat mq - na taketo veci to bolo vymyslene - da sa to aj cez sql implementovat, nebude to najkrajsie ale funguje to ak nemas ine ako sql rozhranie. spominany redis ma podporu pub/sub, ale existuju aj lepsie riesenia
- pouzit asynchronne query - nie najlepsi napad bo mozes prijst o data
Řešení je jednoduché id jako MD5 celé datové věty a nemusíte na nic čekat, jde-li jen o to ID.