·
6 min čtení
·
Napsal Tomáš Mikeš
Deadline-bound batch výpočty: jak garantovat, že skončí včas
Měsíční provize pro JUST musí být spočteny do 5. dne následujícího měsíce. Payroll, závěrky, invoice cycles — stejný pattern. Jak navrhnout batch pipeline, která nezmešká deadline, i když vstupní data nerostou lineárně.
„Musí to skončit do 5. dne následujícího měsíce, jinak provize nevyjdou včas a prodejci budou zuřit.“ Tohle jedeadline-bound batch — nestačí, že to jednou skončí, musí to skončit vždy, včas, i když data letos rostla o 40 %.
Totéž platí pro payroll (zákon ukládá výplatu do X dnů), měsíční závěrky, invoice cycles, regulatory reporting. Pokud jsi v tomhle světě, tady je, jak na to.
1. Měř, neodhaduj
První krok: kolik trvá výpočet na reálných datech, a jak to škáluje. Ne „mělo by to být OK“. Konkrétní čísla.
Pro JUST jsme naměřili:
- 1 000 prodejců × provize = 12 sekund
- 3 000 prodejců = 38 sekund (nelinerně — O(N log N) někde uvnitř)
- 10 000 prodejců = 5,5 minuty (extrapolace)
- Očekávaný růst za 3 roky: 1 000 → 8 000 prodejců
Za 3 roky by výpočet trval 3 minuty. Deadline je 5 dní, v tom i 3 minuty v pohodě. Ale co kdyby růst byl 1 000 → 30 000? Pak 30+ minut, a pokud výpočet závisí na něčem jiném (generování faktur pro banku), začíná to být problém.
Měření na začátku = realistický pohled. Kdo neměří, navrhne pro současný stav a za rok má bug.
2. Paralelizuj na úrovni nezávislých jednotek
Batch výpočet je typicky loop přes N položek, kde každá je nezávislá. U JUSTu jeden prodejce = nezávislá jednotka výpočtu. Výsledek není ovlivněn tím, co dělá jiný prodejce (až na provizi z downline struktury, která se dá oddělit do vlastního preprocessingu).
Architecture:
- Preprocessing: zvalidovat data, připravit kontext
- Partition: rozdělit prodejce do N dávek (napr. 100 po 80 prodejcích v 8000 prodejcovém fleet)
- Parallel execute: N workers, každý zpracuje svoji dávku nezávisle
- Aggregate: spočítat výsledky do finálního reportu
Pro JUST jsme v Azure Functions spouštěli 10 parallel workers (později 20). Výpočet se škáloval skoro lineárně s počtem workers, dokud nenarážel na DB connection pool.
3. Deadline monitoring s pre-alerting
Výpočet běží každý měsíc 1. dne. Deadline 5. dne. Kontrola „jestli se stihne“ v den 5 je pozdě. Místo toho:
- Den 1, hour 0: batch start
- Den 1, hour 2: pokud ještě neskončil, pre-alert (informační)
- Den 1, hour 6: pokud ještě neskončil, high-priority alert (něco je vážně pomalé)
- Den 2, hour 0: pokud ještě neskončil, escalation (human intervention)
- Den 3: rollback plán, ruční výpočet, atd.
Pre-alerting dává 3-4 dny rezervy na diagnózu a fix. Bez něj zjistíš problém 5. dne ráno, a to už pozdě.
4. Idempotentní retry + checkpoint
Batch padne uprostřed. Co teď? Dva extrémy:
- Start from scratch — jednoduché, ale při 30min běhu je to 30 minut zpoždění
- Resume from last checkpoint — složitější, ale ušetří čas
Pro deadline-bound systém checkpoint je povinný. Po každé dávce se zapíše do DB `batch_progress` (batch_id, completed_sellers, timestamp). Při retry se načte poslední checkpoint a pokračuje tam, kde se skončilo.
Kritické: výpočet pro jednoho prodejce musí být idempotentní. Spustit ho 2× dává stejný výsledek. To se dá zaručit tak, že DB write se dělá jako UPSERT podle (seller_id, month) klíče.
5. Kompletní test na reálné kopii dat před produkcí
Test na staging s 100 prodejci ti neřekne nic o chování s 10 000. Před každým kvartálem uděláme kompletní dry-run na kopii produkčních dat v staging:
- Klonuj produkční DB do staging
- Spusť batch end-to-end
- Porovnej výsledky s produkční historií
- Měř timing — odpovídá tvému modelu růstu?
3× za poslední rok jsme v dry-runu odhalili problém dřív, než se dostal do produkce — jednou memory leak, dvakrát N+1 query bug, který by nafoukl čas 10×.
6. Degradation strategy pro edge cases
Co když některá data jsou v chybě a blokují výpočet pro celou dávku? Dvě strategie:
- Fail-fast: první chyba stopne batch, human intervention
- Skip-and-log: problémový prodejce se vynechá, batch pokračuje, chyba se loguje pro post-processing
Volba závisí na business kontextu. Pro provize obecně fail-fast nedává smysl — 5 prodejců s chybou by znamenalo, že 10 000 dalších nedostane výplatu. Skip-and-log je lepší — dostanou výplatu všichni kromě těch 5, kterým se to vyřeší manuálně.
Výsledek pro JUST
Po 3 letech provozu:
- Počet prodejců vzrostl z 2 800 na 6 200 (+120 %)
- Výpočet měsíčních provizí: dřív ~8 min, teď ~14 min (škáluje dobře)
- 0 zmeškaných deadlinů za 3 roky
- 2 chyby, kde pre-alert spustil intervenci ve 4-6 hodin po startu, oprava před deadlinem bez stresu
Generalizace
Deadline-bound batch je velmi běžný pattern a přesto se pořád dělá ad-hoc. Pravidla se opakují:
- Měř, neodhaduj
- Paralelizuj na úrovni nezávislých jednotek
- Pre-alerting na několika časových horizontech
- Idempotentní retry + checkpoint pro resume
- Dry-run na reálné kopii dat před každým kritickým cyklem
- Degradation strategy pro edge cases
Payroll, měsíční závěrky, regulatorní reporty, clearing cycles, billing runs — všechno to jsou deadline-bound batch. Pokud jsi v jedné z těch oblastí a tvoje pipeline nemá alespoň 4 z těch 6 věcí, je to otázka času, kdy se ti zmešká deadline.
Řešíš něco podobného?
Domluvme si 30min technický call. Bez obchodních procesů — přímá architekturní zpětná vazba.
Naše služba:
Systémy, které škálují — bez bottlenecků →