RabbitMQ – dávkové zpracovávání

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
MirekTH
Člen | 20
+
0
-

Zdravím,

zkoukl jsem Filipův přednáško-workshop ;) o RabbitMQ a celkem mě namotivoval ho začít používat. Nainstaloval jsem tedy Rabbita, stáhl Kdyby/RabbitMq, vše nastavil a během hoďky už jsem měl první fronty plněné. Začal jsem s dvěma tasky, které mi přišly tak nějak logické – nadefinoval jsem si 2 queue pro synchronizaci ElasticSearch a zpracovávání feedů (pošlu všechny řádky feedu do fronty a workery se mi o to postarají). Jenže mě trochu zarazil výkon. Tím, že se vše posílá pouze jednou zprávou tak když jsem přidl do fronty 150000 záznamů, které se mají poslat do elasticu tak to bylo pomalejší a dražší na prostředky než klasickým procesem přes consoli, kdy se to rovnou v chunku pošle do elasticu. Prostě se nastřádá třeba 500 dokumentů a pak se to pošle do elasticu hromadně. Toto u Rabbitu neudělám a některé procesy mi to tak bude zbytečně zpomalovat. V některých případech si zase ve workeru potřebuji natahat k požadovanému záznamu další údaje z databáze. Doteď jsem to dělal jednoduše – zpracoval si třeba 1000 řádků feedu, pak si k nim hromadně stáhl dodatečné info a až poté to začal zpracovávat. Ano, náročnější na paměť ale zase mnohem ryhlejší. U rabitu mi tenhle přístup také chybí a zpracováváná je opět pomalejší. Pokud má feed 100000 záznamů a musím si natáhnout třeba 3 mi dotazy další data tak už se mi to začíná zpomalovat a zpracovávání Rabbitem se mi nevyplatí.

Jak to řešíte vy? Rabbit se mi fakt líbí, ale tyhle problémy bych potřeboval nějak vyřešit. Možná jsem jen něco přehlédl.

Díky

Ondřej Mirtes
Člen | 1536
+
+1
-

Jednoduše – dělej „větší zprávy“ – tedy ne zprávy typu „naimportuj jeden dokument“, ale „naimportuj 100 dokumentů“.

Ale pozor – čím menší jednotky, tím se to lépe paralelizuje. Pokud nastartuješ 10 workerů, tak menší zprávy zpracují pravděpodobně rychleji.

MirekTH
Člen | 20
+
0
-

Díky za odpověď, také už jsem si to na to předělal. Hrál jsem si chvilku i s multiple ack, ale to mi přišlo dost nebezpečné. Takže jsem začal dělat větší zprávy a nějak to funguje. Jen je pak trochu omezenější možnost škálování, ale v mých podmínkách (max 100000 zpráv / den) to zase tak neva.

Editoval MirekTH (26. 2. 2016 9:58)

MirekTH
Člen | 20
+
+2
-

Přišel mi do e-mailu jeden dotaz, tak zde vystavím i svou odpověď ať to máme zaevidované:

Dotaz:

Ahoj,
zaujal mě tvůj dotaz – odvodil jsem z toho že používáš Rabbita na synchronizaci dat mezi databází a elastikem. Řeším teď podobný problém a zatím používám export do JSONu (bulk actions) a import přes CLI do ES.

Má odpověď:
Ahoj,

ano, teď jsem to na to přepisoval. Používám jej i na další fronty a synchronizace, odesílání e-mailů, SMS zpráv, synchronizaci s účetním systémem atd … . Celou aplikaci upravuji na mikroslužby a rabbit je pro toto celkem ideální pomocník. Například na jeden typ synchronizace jsme měli již napsanou knihovnu v Node.js a rabbitem jsme pouze připravili požadovaný formát pro tuto mikroslužbu, která si nyní vyzvedává zprávy z definované queue, takže se přes něj dobře povídá i se službami v jiných jazycích.

Konkrétně synchronizaci s Elasticem máme napsanou jednoduše, bylo to jen pár úprav. Do teď byl stav klasický – pokud se změní nějaký dokument (odchytáváme přes Kdyby\Events v Entitách) tak se přidal záznam do fronty v MySQL a přes cron se spouštěla služba, která to jednou za pár minut poslala do elasticu a označila za zpracované. Jenže fronty v databázi nejsou obecně příliš dobré řešení, takže místo přidání záznamu do databáze se přes producer pošle zpráva do rabbitu (ID dokumentu), nastaví se routing key na elastic.product, zpráva se dostane do definované queuee, kde již čeká worker, který to pošle do Elasticu. Nic víc v tom není. Chtěl jsem to ještě trochu upravit aby se dalo posílat více najednou, ale konkrétně zde to moc nemá smysl. Pokud je potřeba invalidovat celou DB a poslat jí znovu do elasticu, pushujeme opět od rabbita ale s routing key elastic.productMulti a napushujeme tam jednotlivé chunky dokumentů, aby se dal použít bulk. Opět nic složitého.

Editoval MirekTH (26. 2. 2016 11:10)