Taakplanner (cron)
Wat is een taakplanner?
Een taakplanner is software met één opdracht: ander werk starten op een moment dat je op voorhand hebt vastgelegd. Een export om 02.00 uur, een herinneringsronde elke werkdag om 06.00 uur, een sync met de webshop om de tien minuten. Je geeft een tijdstip en een commando, en de planner houdt die afspraak.
Cron is de oudste van de familie, en oud genoeg om de woordenschat gezet te hebben die iedereen vandaag nog gebruikt. Cron draait op de achtergrond op Unix- en Linux-systemen en leest een tabel die de crontab heet, waarin elke regel een tijdspatroon is gevolgd door een commando. Alles wat daarna kwam, heeft die vorm overgenomen: de recurrence-trigger achter een scheduled cloud flow, de timer trigger in Azure Functions, een SQL Server Agent-job, het schedule-veld op een Airflow-DAG.
Eén eigenschap veroorzaakt de meeste verrassingen. In zijn kale vorm kent een planner de klok en verder niets: niet of de vorige run klaar is, niet of het bronsysteem beschikbaar is, niet of het bestand van gisteren is toegekomen. Hij start de job omdat het 06.00 uur is, en de rest is jouw ontwerp.
Een cron-expressie lezen
Vijf velden, gescheiden door spaties, in een vaste volgorde: minuut, uur, dag van de maand, maand, dag van de week. POSIX legt de bereiken vast op minuut 0 tot 59, uur 0 tot 23, dag van de maand 1 tot 31, maand 1 tot 12, en dag van de week 0 tot 6 met 0 als zondag. Linux-cron aanvaardt daarnaast 7 voor zondag en namen zoals Mon. Een sterretje betekent elke waarde, een komma maakt een lijst, een koppelteken een bereik, een schuine streep een stap.
0 6 * * 1-5 lees je dus als: minuut 0, uur 6, elke dag van de maand, elke maand, maandag tot en met vrijdag. Zes uur 's ochtends op werkdagen. Nog eentje om op te oefenen: */15 * * * * is om de kwartier.
In de standaard zit een valstrik waar bijna iedereen intrapt. Vul je zowel dag van de maand als dag van de week in, dan combineert cron die twee met OF, niet met EN. Het voorbeeld uit de handleiding van crontab, 30 4 1,15 * 5, draait om 04.30 uur op de 1ste en de 15de, en daarbovenop elke vrijdag. Cron kan niet zeggen: de 15de, maar enkel als het een vrijdag is. Die voorwaarde zet je in de job zelf. Tel ook de velden: Azure Functions werkt met NCRONTAB en zet de seconden vooraan, dus 0 30 9 * * 1-5 is 09.30 uur op werkdagen.
Vragen die een planning oproept zodra ze draait
Welke klok is 06.00 uur?
De lokale tijd van de server, UTC, of een tijdzone met een naam. Neem die met een naam, want dat is de enige die de omschakeling naar zomer- en wintertijd op eigen kracht overleeft. Azure Functions draait zijn expressies in UTC zolang je WEBSITE_TIME_ZONE niet zet, en Airflow volgt de zone die je opgeeft, dus 0 0 * * * in US/Eastern draait om 04.00 uur UTC tijdens de zomertijd en om 05.00 uur daarbuiten. Klassieke cron vergelijkt enkel met de wandklok, en de handleiding zegt onomwonden wat dat oplevert: jobs in het verdwenen uur draaien nooit, jobs in het uur dat zich herhaalt draaien twee keer. Plan dus niets tussen 02.00 en 03.00 uur.
Wat als de vorige run nog bezig is?
De klok gaat toch af, en twee kopieën van dezelfde import die naar dezelfde tabel schrijven is een dataprobleem, geen snelheidsprobleem. Sommige platformen beletten dat: de timer trigger van Azure Functions draait op één instantie, ook wanneer de app uitschaalt, en gaat niet opnieuw af zolang er nog een aanroep bezig is. Doet die van jou dat niet, laat de job dan bij de start een lock nemen en stoppen wanneer hij die niet krijgt.
Wat als er om 06.00 uur niets draaide?
Overslaan of inhalen, en je moet weten welke van de twee je hebt. De Recurrence-trigger van Logic Apps slaat de gemiste momenten over en pikt de draad weer op bij het volgende interval. Airflow haalt in met catchup=True en maakt dan een run aan voor elk interval dat sinds het laatste niet gedraaid heeft, met catchup_by_default=False als standaard. Haal in wanneer het werk bij een periode hoort, zoals een dagtotaal. Sla over wanneer het werk over de huidige toestand gaat, zoals een voorraadmelding, want de waarschuwingen van gisteren helpen niemand meer.
Wat als hij om 03.00 uur faalt?
Een planner start dingen, hij kijkt er niet naar. De timer trigger van Azure Functions probeert het na een fout niet opnieuw: de functie wordt pas op het volgende geplande moment aangeroepen. Beslis dus per job of hij zichzelf na een wachttijd opnieuw probeert, dan wel of de volgende run het achterstallige werk oppikt, wat enkel klopt als de job veilig te herhalen is.
Hoe weet je dat hij gedraaid heeft?
Alarmeren op fouten vangt alleen jobs die gedraaid en gefaald hebben. Ligt de planner zelf stil, dan faalt er niets, komt er geen melding, en hoor je het van een klant die vraagt waar het rapport blijft. Zet er een melding op afwezigheid naast: de job meldt aan het einde dat hij klaar is, en een aparte controle slaat alarm wanneer dat signaal om 06.30 uur nog niet binnen is. Dat is de controle die stilte opmerkt, en meestal net degene die ontbreekt.
Een nachtelijke keten die stuk loopt
Een groothandel heeft vier jobs, elk een uur na de vorige gepland: om 02.00 uur de bestellingen van gisteren uit het ERP exporteren, om 03.00 uur dat bestand in het datawarehouse laden, om 04.00 uur de transformaties draaien, om 06.00 uur het Power BI-rapport vernieuwen.
Een jaar lang gaat dat goed. Dan verdubbelt het aantal bestellingen, duurt de export tachtig minuten in plaats van veertig, en is hij pas om 03.20 uur klaar. De job van 03.00 uur vindt nog altijd een bestand, leest het en slaagt, want het bestand van de vorige nacht staat waar het altijd staat. Om 06.00 uur vernieuwt het rapport met een volledige dag te weinig en melden alle vier de jobs succes. Er is niets mislukt, dus komt er geen alarm. Dat uur tussen elke job is nooit een keuze geweest. Het is een schatting van hoe lang een stap duurt, vastgezet in de klok, en die schatting klopt steeds minder naarmate je data groeit.
Planner of orkestrator: wat start de volgende job?
Bij een planner start de klok elke job. Vier planningen zijn vier losse afspraken, de laadstap begint om 03.00 uur of de export nu klaar is of niet, en geen van beide jobs weet dat de andere bestaat.
Bij een orkestrator houd je één planning over voor de hele keten, om 02.00 uur, en is het einde van de vorige job wat de volgende start. De export die om 03.20 uur eindigt, start de laadstap om 03.20 uur. Mislukt de export, dan start de laadstap niet, houdt het rapport de cijfers van gisteren in plaats van een halve dag te publiceren, en krijg je één melding die de stap noemt die stukliep. Airflow, Dagster en Fabric Data Pipelines zijn daarvoor de gebruikelijke tools, en de entry over data-orkestratie legt uit hoe je die afhankelijkheden modelleert.
Eén job op een klok is een planning. Drie jobs waarbij elke stap op de vorige wacht, is een afhankelijkheid in vermomming, en je hebt er een gevonden zodra je een tussenruimte breder maakt omdat een stap trager werd.
Waar moet je op letten bij geplande jobs
Niemand weet wat er 's nachts draait
Schrijf elke geplande job op in één lijst: wat hij doet, de expressie en de tijdzone, waar hij draait, wie de eigenaar is, en wat er stukloopt als hij niet draait. Dat kost een namiddag. In de meeste lijsten duikt een job op die op naam staat van iemand die al lang vertrokken is, en diezelfde lijst maakt later een servermigratie haalbaar.
Frequentie is een factuur
Een trigger om de tien minuten is 144 runs per dag en ruim vierduizend per maand, nog voor er iets nuttigs gebeurd is. Bij AI-werk is elke wekbeurt een reeks modelaanroepen, en de entry over de ambient agent gaat daarop dieper in. Microsoft waarschuwt dat extra uitvoeringen op een consumption plan flink duurder kunnen uitvallen. Per uur volstaat meestal, en lukt dat echt niet, dan wil je een event-trigger en geen korter interval.
De job op iemands laptop
Windows Taakplanner op een pc onder een bureau is een echte planner, met een echte afhankelijkheid van die pc die aanstaat en van die collega die hier nog werkt. Doet de job ertoe, dan hoort hij op een server.