Multi queue, task és worker kezelés koncepció Phpban?

Helló

Ki akarok pár kombinatorika jellegű feladatot próbálni, hogy igazoljam a teóriám. Saját kihívás, önmagam ellen! :)
Van egyrészt egy saját PHP programom, aminek vannak bemeneti paraméterei (jó sok), és generál egy fájl kimenetet, mint eredmény.
Utána abból a fájlból még egy másik programmal kell pár változatot generáljak.
Majd van egy elemző programom, ami megvizsgálja az eredményt.
Arra gondoltam, hogy az első program meghívásához legenerálom az összes, akár milliós nagyságrendű paramétert (N), az összes lehetőséget, hogy akarom meghívni az első programot.

 

Ez volt az első ötlet:

Valahogy meg kellene oldani a queue kezelést, hogy 8 magból mondjuk 4 esetén ez fusson, tehát elosztom a legenerált listát 4 felé és elindítom 4 szálon, így mivel nincs queue kezelésem ez fapad megoldásként hasonló eredményt hoz. Ezzel csak az a baj, hogy lehet nincs elég helyem hozzá. Aztán a létrejött fájlokat kellene másik programmal meghívni, amiből lesz M darab változat. Így lesz N*M fájl, amihez végképp nincs elég helyem. Bár ez az én bajom. Aztán a létrejött N*M fájlt kellene elemezni, és ha valami olyan, ami oké, akkor azt meghagyni, ha nem olyan, amire 99% az esély, akkor törölni, de valahogy elrakni, hogy azt már néztem és nem volt jó.

Ez az első ötlet így nem jó számomra.

Ezek PHP nyelven írt programok és most Windowst használok, mert így kényelemes most épp, de lehetne Ubuntu linux is akár.

 

Második ötlet, ami jobbnak tűnik:

Azt lenne az ideális, hogy lenne egy olyan okos vezérlő, multi process/worker/batch futtató alkalmazás, ami az alábbiakat valósítaná meg:

Queue 1: (kombináció alapján generálás) Figyelne, hogy mindig legyen mondjuk 100 (vagy több, de nem sokkal) az első programmal már legenerált kombináció (az N elemeken menne végig), hogy lehessen a másik programmal (M elemek) kombinációkat legenerálni. Hogy ne fogyjon el a forrás a második lépéshez. Ez a program egy millió soros txt állományon menne végig, és abból venné sorban a paramétereket.

Queue 2: (kombináció előkészítés) Figyelné, hogy legyen mindig legenerált 100 (vagy több, de nem sokkal) elemezhető kombináció (N*M elem összesen). Ez a második folyamatosan dolgozná fel a már legenerált fájlokat és ebből jönnének létre további fájlok, amiket ki kell elemezni. Itt a már létrejött fájlból hozna létre M változatot, ha kész törölné is akár az adott elemet, amiből készítette, de ez végül is mindegy, mikor törlődik.

Queue 3: (kombináció feldolgozás, elemzés) Az előző 2 queue működésen kívül az összes egyéb erőforrással próbálná azt elérni, hogy a legenerált utóbbi, Queue 2 esetén létrejövő N*M elemet meghívni az utolsó, 3. elemző programmal, ami ha oké meghagyja a fájlt. Ha nem oké, törli és loggolja.

 

Elérni, hogy soha ne fogyjon ki a Queue 1 és Queue 2, és mindig legyen fájl a Queue 3 esetében is.

Ez lenne a fő cél, mert így kb ramdisken is futtathatnám, meg nem kellene sok SSD tárhely. Továbbá mindig is akartam látni egy ilyen működést, tehát ez is egy szempont, hogy valami ilyesmi megvalósuljon, mert érdekel.

Egy 8 magos gépen futtatnám, de lehet egy 4 magos gépet is bevonnék, ha megoldható, például megosztott mappán keresztül kommunikálna a processzekkel. Az külön történet, hogy hány processz fogja kihajtani a gépet teljesen, meg hogy mi lesz a szűk keresztmetszet.

 

Az (el)várt működés:

Elindul, majd elsőnek csak a Queue 1 fut, amíg nem lesz 100 legenerált kombináció.

Amint van 100, akkor a Queue 2 is elkezd működni, elkezdi az 1. legenerált fájlból az M változatot elkészíteni.

Amint van 100, vagy végülis ha már 1 is van az M változatból, akkor elkezdheti az elemző kielemezni azt. Azért írtam 100 M változatot, hogy az elemző is tudjon futni folyamatosan, de hát ezt majd látni kell, mi mennyi idő, most én sem tudom, mi fog sok időt igénybe venni.

Így leírva hülyeség ez a 100 fájl kikötés a Queue 1 és Queue 2 esetén, mert ha már 1 fájlból is tud M változatot generálni,  elindulhatna. Csak azért írtam, mert azt hittem, ezzel garantálható, hogy minden a leggyorsabban halad és semmi nem várakozik.

Ha korlátlan tárhelyen és számítási kapacitásom lenne, akkor:

Legenerálnám az N elemeket.

Majd abból az N*M kombinációt.

Majd kielemezné a program, de ezt nem tudom megoldani, mert nagyságrendekkel nagyobb helyet igényelne, mint amit megoldható.

Itt az is nagy kérdés, hogyan, mi módon tároljam, hol tartok.

Ha mindig lemezre írnám, akkor lassú lenne.

Valahogy x percenként leírt állapot elég lenne.

Mysqlt erre használni szerintem nagy lassulást okozna. Nem használnék adattáblákat erre.

 

Ha a program egy txt állományba mentett paramétereket dolgozna fel, és millió soros lenne a txt állomány, az úgy nekem jó lenne, csak tudni kellene, hol tartok.

 

Az elemző program meg mindent el tud végezni, bár ezt még be kell fejeznem. Hogy törli a fájlt ha nem jó és elrakja az adatatokat mondjuk egy txt logba, 1 sor 1 lehetőség.

Itt Nosql még szebb lehetne, ha ebbe loggolna, de nem használtam még ilyeneket, főleg nem Windows 10en. Végülis később is át tudom alakitani a txt logot, ha kell valami komolyabb elemzés, vagy eleve több adatot loggolok.

 

Mindenki máshogy készül a választásra, én inkább elterelem a figyelmem. :)

 

64 bites PHP 8.0 alapokon vagy 7.4, ezen szeretném ezt megvalósítani, ezt ami hívogatná paraméterekkel a programokat. Jó lenne, ha lenne kész ilyesmire alkalmas framework, class, vagy bármi. Tudnátok ajánlani valamilyen kész, vagy félkész megoldást erre? Biztos van ilyesmi készen, csak én nem találtam még meg.

Én nem multi threadben gondolkodom, nem kell, hogy egy Php program önmagán belül legyen multitask. Sima Phpt használnék. Thread safe maradhat, és simán exec lenne a külső program hívása, majd a visszatérő kódból lehetne tudni, hogy sikeres volt vagy sem, meg létrehött-e a paraméterben megadott file vagy sem. Ha igen, akkor oké volt a process futtatás, az adott task sikeresen lefutott.

Esetleg valamilyen kész open source alkalmazást paramétereznék be erre, ha már van ilyen, ha nem sikerülne megírni vagy találni erre valamit. Tudom, C nyelven kellene ezt írni, assembly betétekkel, de hát az nem reális számomra.

Hozzászólások

Szia!

 

Ez nem lesz egy sétagalop... 

Nézd meg ezt: https://github.com/yiisoft/yii2-queue

Yii2 framework-re épül. De legalább docker konténerek kellenek majd hozzá. Viszont ez tuti működik. Van egy éles projektem amivel php-ben ragadtam. 

Hát, jobban utána olvasva tényleg nem lesz egyszerű. Köszönöm, elolvasom amit javasolsz.

Amit találtam azóta:

https://github.com/Rikanishu/php-multi-process

https://github.com/php-enqueue/job-queue

https://blog.forma-pro.com/message-bus-to-every-php-application-42a7d3fbb30b

Szerkesztve: 2022. 04. 03., v – 22:52

ne csinalj 3 queue, mert csak bonyolitod. helyette 3 prioritast vezess be: mindig high prios a legutolso feladat: ha ilyen van, akkor azt mindenkepp el kell vegezni -> igy felszabadul a helyed. a kombinacio elokeszites legyen a normal prios, es a generalas feladat lesz a low prios, ilyet csak akkor csinaljak meg, ha a masik kettobol nincs epp feladat.

annyi workert inditasz ahany cpud van, mindegyik barmelyik feladatot elvegezheti.

ugy inditod az egeszet hogy bekuldod mind az osszes generalas taskot, majd a queue kezelo szepen kiosztja valamelyen sorrendben. a "q2" es "q3" nem fog feltorlodni, mert a magasabb prio miatt eloszor azokat dolgozzak fel.

akar jo lehet e fenti yii2 is, laravelnek is van "konzol"-os verzioja, Laravel Zero neven, ha jol lattam van benne a rendes queue kezeles. ha tudsz wsl-el redist rakni akkor queue driver mehet, ha nem akkor pl valami db alapu.

A vegtelen ciklus is vegeter egyszer, csak kelloen eros hardver kell hozza!

Jó ötlet hogy csak 1 queue legyen priorizálással, miután ezt leírtam már én is gondolkoztam az egyszerűsítési lehetőségeken. Sokat segített ez. A Redis memóriában is tartja, de el is menti a jobokat? Ha kifagy a Redises gép, akkor valami állapot marad, hol tartott?

Jól értem, hogy lehet egy olyan feladat is, hogy 1 percenként ellenőrzi, hogy az alacsony prioritásúakból hány feladat van, és ha 1000-nél kevesebb, akkor hozzáad pár ezret, majd vár újra 1 percet és újra ellenőrzi? Ha több, mint 1000 van, várakozik? Mert N millió jobot hozzáadni nem tűnik jó ötletnek egyben. 

A még egyszerűbb ötlet, hogy a low prioritásos generálás feladatnál mindig berak annyit, hogy + ezer ilyen feladat legyen, ha meghívják, akkor nem kellene +1 job. Vagy hogy érdemes ennél is jobban?

redis menti, van erre beallitas. elvileg nemnagy adat csak a jobok nevei, stb.

igen, lehet olyat hogy a generalo on demand gyartja, bar szerintem ez bonyolultabb.

database alapon biztos diskre kerul, cserebe lehet lassabb.

A vegtelen ciklus is vegeter egyszer, csak kelloen eros hardver kell hozza!

A redist nézd meg, de a redis nem queue de lehet elég lesz neked amit tud.

Nézz meg egy MQTT-t de leginkább egy RabbitMQ-t, azok tényleg queue implementációk.

A RabbitMQ kicsit pilótavizsgás de az MQTT tényleg faék. Kicsit fura faék de tényleg jó.

Gábriel Ákos