Een bewaking die alleen kan stoppen, maakt van een korte storm een lange stilstand

Mijn agents draaien dag en nacht op een eigen server. Een storm van een paar minuten kostte me ruim twee uur stilstand. Niet door de storm, maar door de bewaking.
Wat een forkstorm is
Elk programma doet zijn werk via processen. Een forkstorm is een server die zo snel nieuwe processen start en weer stopt, dat hij nergens anders meer aan toekomt. Geheugen en rekenkracht lijken vrij, en toch is alles traag.
Op een gewone dag start mijn server 200 tot 300 processen per seconde. In een storm zag ik er meer dan 900, en bij een eerdere storm meer dan 1.200. Bij mensen komt dit zelden voor. Bij agents wel: een agent die een toets draait, doet dat met tientallen kleine opdrachten tegelijk, en 's nachts werken er meerdere agents naast elkaar zonder dat ze van elkaar weten.
Wat er misging
Ik heb een bewaking die dit ziet, een verdachte aanwijst en die bevriest. Dat deed hij ook. Maar bevriezen is een ingreep die iemand ook weer ongedaan moet maken. Het was avond, er keek niemand, en het hart van het werk bleef bevroren. Elke agent stond stil. De storm zelf duurde minuten. De stilstand duurde ruim twee uur.
Een bewaking die alleen kan stoppen, verandert een korte storm in een lange stilstand.
Wat ik veranderde
- Na vijf rustige minuten ontdooit de bewaking zelf.
- Het hart van het werk blijft nooit langer dan tien minuten bevroren, ook niet als de storm doorgaat.
- Komt de storm snel terug bij dezelfde veroorzaker, dan stop ik alleen die, niet het hart.
Ik test dit met een toets die zelf een fork-lus start, eist dat die bevroren wordt en daarna weer aan gaat.
Zes keer bevroren, zes keer bedoeld werk
Ik ging terug door de metingen van een paar dagen. In die tijd greep de bewaking zes keer in. Alle zes keren bevroor hij werk dat ik zelf wilde laten draaien: een toets in een beurt van een agent, de uitrolrij, een agent die een video samenstelde. Niet één keer was het een echte lus. En één keer pakte hij zelfs het verkeerde doel, omdat de schuld terechtkwam bij het proces dat de kleine processen opruimt, in plaats van bij degene die ze startte.
De reden is simpel: het aantal processen per seconde zegt bijna niets. Bedoeld werk piekt hoger dan de problemen. Mijn server loopt op een gewone dag ver onder die pieken, en bedoeld zwaar werk komt er ruim boven. Een telling kan dat niet scheiden.
Wat een lus wel verraadt
Het eigenlijke probleem op mijn server was heel ander. Een controle die aan het begin van elke beurt van elke agent over alle tickets liep, startte per ticket een proces. Dat waren er tienduizenden per ronde, bij elke agent, steeds opnieuw, dag en nacht. Er was geen storm te zien, wel een server die voortdurend bezig was zonder iets te doen. Dat soort lus herken je aan iets anders dan snelheid:
- dezelfde opdracht, steeds opnieuw, vanuit dezelfde ouder, waar bedoeld werk veel verschillende opdrachten start;
- een proces per stukje werk of een controle die om de paar seconden draait, waar bedoeld werk begrensd parallel loopt en na een paar minuten ophoudt;
- aanhoudend of groeiend, zonder dat er voortgang is, en kinderen die falen in plaats van slagen;
- een belasting die ver boven het aantal rekenkernen blijft.
Dat zijn dus patronen over tijd en herhaling, niet over één getal. Mijn bewaking meet daarom per opdracht en per ouder, kijkt naar het aantal lopende processen per groep, en grijpt alleen in bij de groep die zich zo gedraagt. Zwaar werk dat zich aanmeldt krijgt ruimte.
Waarom geen harde grens
De simpelste oplossing is een plafond op het aantal processen per seconde. Dat heb ik bewust niet gedaan. De toetsen die ik elk half uur draai, halen soms ruim 3.000 per seconde, en dat is bedoeld werk. Een harde grens knijpt dat af, of is zo ruim dat hij een storm niet vangt. Ik wil de server maximaal benutten.
Wat wel werkt: onderscheid maken tussen bedoeld zwaar werk en onbedoeld zwaar werk, en elke ingreep omkeerbaar en tijdelijk maken.
Wat je hieruit meeneemt
- Meet het ritme van je server, niet alleen de belasting. Eén regel per minuut is genoeg.
- Laat een agent zijn werk bundelen: niet één proces per stukje werk, en niet alles tegelijk.
- Een bewaking die kan stoppen, moet ook kunnen herstarten.
- Geef elke ingreep een tijdslimiet. "Tot een mens kijkt" is geen limiet.
Dit is hetzelfde patroon als in Het autonome AI-bedrijf: een rol met een bevoegdheid, een beschermende maat en een mens als laatste stap. Een mens die niet altijd kijkt, vraagt om een systeem dat zichzelf weer loslaat.