Hoppa till innehåll

Resurshantering

Queuety delar upp resursstyrningen i fyra grundläggande lager, med valfri dimensionering av pooler ovanpå dem.

Det första lagret beskriver kostnaden för en arbetsenhet. Det andra begränsar hur stor delad belastning en kö eller leverantörsgrupp får bära åt gången. Det tredje anger hur mycket en enskild arbetsflödeskörning får förbruka. Det fjärde avgör om en arbetare ska starta nästa hämtade jobb direkt eller skjuta upp det tills den aktuella processen och containern har tillräckligt med marginal.

Lagren samverkar. En hanterare kan ange att den tillhör en gemensam pool med hög kostnad, en kö kan reservera en begränsad mängd viktat arbete för en leverantör, ett arbetsflöde kan sätta ett tak för hur mycket sådant arbete det får skapa, och arbetaren kan ändå vägra starta mer när den aktuella processen eller containern redan ligger för nära sina gränser.

Beskriv kostnaden för en arbetsenhet

Jobb, arbetsflödessteg och åtgärder vid tillståndsövergångar kan alla ange samma tre resurshänvisningar:

  • concurrency_group
  • concurrency_limit
  • cost_units

concurrency_group och concurrency_limit beskriver delad belastning på ett nedströms system. Om flera hanterare anropar samma leverantör, konto API eller klient, kan de använda samma grupp så att arbetarna inte startar för många jobb samtidigt.

cost_units beskriver relativ vikt. En cacheuppdatering och ett stort anrop till en leverantör kan båda vara ”ett jobb”, men de bör inte räknas lika när en arbetsflödesbudget eller en regel för arbetarinsläpp avgör om det är säkert att starta mer arbete.

PHP
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,
        ];
    }
}

Samma princip gäller för jobb som kan skickas, via klassegenskaper, och för enskilda jobb som skickas, via PendingJob::concurrency_group() och PendingJob::cost_units().

Budgetera delade köer och leverantörsgrupper

Delad belastning handlar inte alltid om ett enkelt antal samtidiga jobb. Ibland är det den sammanlagda vikten av det som redan körs som är dyrast.

Queuety stöder detta med viktade budgetar för köer och grupper. Köbudgetar baseras på könamnet. Gruppbudgetar baseras på concurrency_group, vilket gör att orelaterade hanterare kan ingå i samma gemensamma ram.

PHP
define( 'QUEUETY_RESOURCE_QUEUE_COST_BUDGETS', [
    'providers' => 20,
    'exports' => 8,
] );

define( 'QUEUETY_RESOURCE_GROUP_COST_BUDGETS', [
    'openai' => 12,
    'tenant:acme' => 6,
] );

När en arbetare hämtar ett jobb tittar den på de aktiva raderna i processing som redan hör till kön eller gruppen. Om den aktuella körkostnaden plus det hämtade jobbets cost_units skulle överskrida den konfigurerade budgeten släpper arbetaren jobbet och försöker igen senare.

Det ger en annan typ av styrning än concurrency_limit. En leverantör kan tillåta tre samtidiga anrop och ändå reservera färre kostnadsenheter för större anrop än för mindre.

Håll ett arbetsflöde inom en ram

Arbetsflödesbudgetar finns för situationer där problemet inte är ett enskilt tungt jobb, utan att en körning fortsätter att hitta mer arbete än avsett.

Det är vanligt i agentbaserade system. En planerare kan återvända till samma kostsamma gren, dela upp den i för många underuppgifter eller fortsätta starta underordnade arbetsflöden, samtidigt som den tekniskt sett håller sig inom en vanlig modell för omförsök.

Queuety tillhandahåller gränser på arbetsflödesnivå för detta:

PHP
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();

max_cost_units() hindrar körningen från att förbruka mer viktat arbete än avsett. max_started_workflows() hindrar ett överordnat arbetsflöde från att bli ett obegränsat träd av överordnade underordnade körningar. De andra skyddsräckena behövs också, eftersom alla arbetsflöden som skenar inte är kostsamma på samma sätt.

Arbetsflödets status visar de konfigurerade gränserna och den aktuella användningen via den offentliga nyttolasten budget, så körningen går att granska medan gränserna gäller.

Låt arbetare skjuta upp arbete när processen redan är för hårt belastad

Även när metadata- och arbetsflödesbudgetar är väl konfigurerade är det fortfarande den arbetare som ska utföra jobbet som fattar det slutliga beslutet.

Det är här resursmedveten tilldelning kommer in. Innan ett hämtat jobb startar kan Queuety kontrollera:

  • jobbets delade samtidighetsgrupp
  • viktade budgetar för köer och leverantörsgrupper
  • historik över handläggarens senaste körtider och högsta minnesanvändning
  • hur mycket minnesutrymme den aktuella arbetaren har kvar
  • hur mycket minnesutrymme den aktuella containern eller värden har kvar
  • den återstående tidsramen för engångskörningar

Om arbetaren redan ligger för nära den konfigurerade gränsen släpper Queuety jobbet i stället för att starta arbete som sannolikt inte kan slutföras på ett säkert sätt.

Det här är avsiktligt en försiktig lösning. Det är ingen fullständig klusterschemaläggare, utan ett skyddslager som hjälper en belastad arbetare att undvika att överbelasta processen den körs i och, när minnesdata finns tillgängliga, den omgivande containern eller värden.

Delen för containern eller värden är valfri. När QUEUETY_RESOURCE_SYSTEM_MEMORY_AWARENESS är aktiverat försöker Queuety först läsa minnesdata från cgroup och använder /proc/meminfo som reserv på Linux värdar. Om det inte finns någon tillförlitlig ögonblicksbild på systemnivå fortsätter arbetaren att använda kontrollerna för den lokala processen.

Skala arbetarpooler utan att ignorera kapaciteten

Det är lätt att förstå fasta arbetarpooler, men de tvingar dig också att välja ett enda antal för både lugna perioder och arbetstoppar.

Med anpassningsbara pooler kan du i stället ange ett minimum och ett maximum:

Shell
wp queuety work --queue=providers --min-workers=2 --max-workers=6

Den överordnade processen håller minst det minsta antalet underprocesser igång, skalar upp mot maxantalet när mängden hämtbara jobb ökar och skalar ned igen när kön har varit lugn under den konfigurerade inaktivitetsperioden.

Uppskalningen tar fortfarande hänsyn till tillgänglig kapacitet. Om systemminnesmedvetenhet är aktiverad och den överordnade processen inte kan se tillräckligt med ledigt minne för ytterligare en fullständig arbetsram behåller poolen sin nuvarande storlek i stället för att starta fler underprocesser.

Ett realistiskt sätt att kombinera lagren

Tänk dig ett forskningsarbetsflöde som planerar anrop till leverantörer, startar specialiserade arbetsflöden och sedan sammanställer resultatet.

Steget som kommunicerar med leverantören kan publicera cost_units och en delad concurrency_group så att flera arbetare inte överbelastar samma modellleverantör med anrop. Kön kan reservera en viktad budget för trafiken till den leverantören. Det överordnade arbetsflödet kan begränsa max_cost_units() och max_started_workflows() så att en planerare inte kan låta körningen växa i all oändlighet. Arbetaren kan sedan fortfarande skjuta upp ett nyligen hämtat anrop till leverantören om data över den senaste högsta minnesanvändningen visar att processen eller containern redan ligger för nära sin gräns.

Det ger dig fyra separata kontroller:

  1. beskriv arbetets vikt
  2. reservera delad kapacitet för kön eller leverantören
  3. begränsa vad en körning får skapa
  4. förhindra att en belastad arbetare startar mer arbete än den bör

Var du hittar de detaljerade API:erna

Den här sidan är en konceptuell översikt.

För de konkreta inställningarna:

  • Workers täcker antagningsbeteende och körningskonstanter
  • CLI täcker kommandon för fasta och anpassningsbara worker-pooler
  • Workflow Guardrails täcker arbetsflödesbudgetar
  • Jobs täcker metadata för jobb och hanterare
  • State Machines täcker metadata för tillståndsåtgärdsresurser
  • API listar de exakta metoderna och returformaten