Erőforrás-kezelés
Queuety az erőforrás-szabályozást négy alapvető rétegre bontja, amelyeket opcionális poolméretezés egészít ki.
Az első réteg azt írja le, mennyibe kerül egy munkaegység. A második korlátozza, hogy egy várólista vagy szolgáltatói csoport mekkora közös terhelést viselhet egyszerre. A harmadik meghatározza, mennyit használhat fel egyetlen munkafolyamat-futás. A negyedik dönti el, hogy a worker azonnal elindítsa-e a következő átvett feladatot, vagy halassza el, amíg a jelenlegi folyamatban és konténerben elegendő tartalék nem marad.
Ezek a rétegek együttműködnek. Egy kezelő jelezheti, hogy nagy terhelésű közös poolhoz tartozik, a várólista korlátozhatja az adott szolgáltatóhoz lefoglalt súlyozott munkát, a munkafolyamat megszabhatja, mennyi ilyen munkát hozhat létre, a worker pedig továbbra is megtagadhatja a munka elindítását, ha a folyamat vagy a konténer már túl közel van a korlátaihoz.
Egy munkaegység költségének leírása
A feladatok, a munkafolyamat-lépések és az állapotba lépéskor végrehajtott műveletek ugyanazt a három erőforrásra vonatkozó jelzést tehetik közzé:
concurrency_groupconcurrency_limitcost_units
A concurrency_group és a concurrency_limit egy downstream rendszer közös terhelését írja le. Ha több kezelő is ugyanazt a szolgáltatót, API fiókot vagy bérlőt veszi igénybe, ugyanazt a csoportot használhatják, így a workerek nem indítanak el egyszerre túl sok feladatot.
A cost_units a relatív súlyt írja le. Egy gyorsítótár-frissítés és egy nagy szolgáltatói hívás egyaránt „egy feladat” lehet, de nem szabad egyformán beleszámítaniuk, amikor egy munkafolyamat kerete vagy a worker felvételi szabálya eldönti, hogy biztonságos-e további munkát indítani.
final class CallProviderStep implements \Queuety\Step
{
public function handle( array $state ): array
{
// ...
}
public function config(): array
{
return [
'concurrency_group' => 'providers',
'concurrency_limit' => 3,
'cost_units' => 5,
];
}
}
Ugyanez vonatkozik az osztálytulajdonságokon keresztül indítható feladatokra, valamint az egyedi dispatch-ekre a PendingJob::concurrency_group() és a PendingJob::cost_units() használatával.
Megosztott várólisták és szolgáltatói csoportok kereteinek beállítása
A közös terhelés szabályozása nem mindig egyszerű párhuzamossági számot jelent. Néha a már futó feladatok együttes súlya a költséges.
A Queuety súlyozott várólista- és csoportkeretekkel biztosítja ezt. A várólistakeretek kulcsa a várólista neve. A csoportkeretek kulcsa a concurrency_group, így egymástól független kezelők is ugyanahhoz a közös kerethez tartozhatnak.
define( 'QUEUETY_RESOURCE_QUEUE_COST_BUDGETS', [
'providers' => 20,
'exports' => 8,
] );
define( 'QUEUETY_RESOURCE_GROUP_COST_BUDGETS', [
'openai' => 12,
'tenant:acme' => 6,
] );
Amikor egy worker átvesz egy feladatot, megvizsgálja azokat az aktív processing sorokat, amelyek már az adott várólistához vagy csoporthoz tartoznak. Ha a jelenleg futó költség és az átvett feladat cost_units értékének összege meghaladná a beállított keretet, a worker visszaadja a feladatot, és később újra próbálkozik.
Ez más szabályozást tesz lehetővé, mint a concurrency_limit. Egy szolgáltató engedélyezhet három párhuzamos kérést, miközben a nagyobb kérésekre kevesebb összes költségegységet tart fenn, mint a kisebbekre.
Egy munkafolyamat kereteinek betartása
A munkafolyamat-keretek olyan esetekre valók, amikor nem egyetlen nehéz feladat okoz gondot, hanem a futás a tervezettnél több munkát talál folyamatosan.
Ez gyakori az ügynökalapú rendszerekben. Egy tervező újra és újra előveheti ugyanazt a költséges ágat, túl sok részfeladatra bonthat egy feladatot, vagy folyamatosan elindíthat gyermek-munkafolyamatokat úgy, hogy közben a normál újrapróbálkozási modell keretein belül marad.
A Queuety munkafolyamat-szintű korlátokat biztosít erre az esetre:
Queuety::workflow( 'research_run' )
->max_transitions( 20 )
->max_for_each_items( 12 )
->max_state_bytes( 32768 )
->max_cost_units( 40 )
->max_started_workflows( 8 )
->then( PlanResearchStep::class )
->for_each( 'tasks', ExecuteResearchTask::class, 'results' )
->dispatch();
A max_cost_units() megakadályozza, hogy a futás a tervezettnél több súlyozott munkát használjon fel. A max_started_workflows() meggátolja, hogy egy szülő korlátlan számú legfelső szintű gyermekfutásból álló fává nőjön. A többi védőkorlát továbbra is fontos, mert nem minden elszabaduló munkafolyamat egyformán költséges.
A munkafolyamat állapota a nyilvános budget adatban teszi elérhetővé a beállított korlátokat és a jelenlegi felhasználást, így a futás ezek érvényessége alatt is nyomon követhető marad.
A munka elhalasztása, ha a folyamat már túlterhelt
Még megfelelő metaadatok és munkafolyamat-keretek esetén is a feladat végrehajtására készülő workerfolyamat hozza meg a végső döntést.
Itt lép működésbe az erőforrás-tudatos felvétel. Egy átvett feladat indítása előtt a Queuety megvizsgálhatja a következőket:
- a feladat megosztott párhuzamossági csoportja
- a súlyozott várólista- és szolgáltatóicsoport-keretek
- a kezelő korábbi futásideje és csúcsmemória-használata
- a jelenlegi worker megmaradt memóriakerete
- a jelenlegi konténer vagy gazdagép megmaradt memóriakerete
- az egyszeri futásokra rendelkezésre álló időkeret
Ha a worker már túl közel van a beállított felső határhoz, a Queuety visszaadja a feladatot, ahelyett, hogy olyan munkát indítana, amely valószínűleg nem fejeződik be problémamentesen.
Ez szándékosan óvatos megoldás. Nem teljes értékű fürtütemező. Olyan biztonsági réteg, amely segít a leterhelt workernek elkerülni a futtató folyamat túlterhelését, és memóriaadatok esetén a körülötte lévő konténer vagy gazdagép túlterhelését is.
A konténerre vagy gazdagépre vonatkozó rész opcionális. Ha a QUEUETY_RESOURCE_SYSTEM_MEMORY_AWARENESS engedélyezve van, a Queuety először cgroup-memóriaadatokat próbál olvasni, Linux gazdagépeken pedig a /proc/meminfo értékhez folyamodik. Ha nem áll rendelkezésre megbízható rendszerszintű pillanatkép, a worker továbbra is a folyamaton belüli ellenőrzéseket használja.
A workerek számának növelése a kapacitás figyelembevételével
A rögzített workerméretek könnyen átláthatók, de a csendes időszakokra és a terhelési csúcsokra is ugyanazt a számot kell megadni.
Az adaptív pooloknál ehelyett alsó és felső határt állíthat be:
wp queuety work --queue=providers --min-workers=2 --max-workers=6
A szülőfolyamat legalább a minimális számú gyermekfolyamatot életben tartja, a felvehető hátralék növekedésekor a maximális szám felé bővíti a poolt, majd a várólista beállított inaktivitási türelmi ideje után csökkenti a méretét.
A méretnövelés továbbra is figyelembe veszi a rendelkezésre álló kapacitást. Ha engedélyezve van a rendszermemória figyelése, és a szülő nem lát elegendő szabad memóriát még egy teljes worker számára, a pool méretét változatlanul hagyja ahelyett, hogy további gyermekfolyamatokat indítana.
A rétegek gyakorlati kombinálása
Képzeljen el egy kutatási munkafolyamatot, amely megtervezi a szolgáltatói hívásokat, szakértői munkafolyamatokat indít, majd összeállítja az eredményt.
A szolgáltatót hívó lépés közzéteheti a cost_units és egy megosztott concurrency_group értéket, így több worker sem terheli túl egyszerre ugyanazt a modell-szolgáltatót. A várólista súlyozott keretet tarthat fenn az adott szolgáltató forgalmára. A szülő-munkafolyamat korlátozhatja a max_cost_units() és a max_started_workflows() értékét, így a tervező nem növelheti korlátlanul a futást. Ezután a worker még mindig elhalaszthat egy újonnan átvett szolgáltatói hívást, ha a legutóbbi csúcsmemória-adatok szerint a folyamat vagy a konténer már túl közel van a felső határához.
Ez négy külön szabályozási lehetőséget ad:
- a munka súlyának leírása
- megosztott várólista- vagy szolgáltatói kapacitás lefoglalása
- annak korlátozása, hogy egy futás mennyi munkát hozhat létre
- a túlterhelt worker visszatartása a szükségesnél több munka indításától
Hol találhatók a részletes API-k
Ez az oldal az alapelveket tekinti át.
A konkrét beállításokért:
- Workerek a felvételi működésről és a futásidejű konstansokról szól
- CLI a rögzített és adaptív workerpool-parancsokat ismerteti
- Munkafolyamat-védőkorlátok a munkafolyamatok kereteiről szól
- Feladatok a feladatok és kezelők metaadatait ismerteti
- Állapotgépek az állapotműveletek erőforrás-metaadatairól szól
- API a pontos metódusokat és visszatérési formákat sorolja fel