Tumbling Window
Comment découper un flux infini en tranches temporelles disjointes pour calculer des agrégats périodiques exacts.
Problème
Un flux EDI est par nature infini : les messages arrivent en permanence depuis le réseau PEPPOL, depuis AS2/AS4, depuis les portails partenaires. On veut périodiquement répondre à des questions du type « combien de factures ont été reçues entre 09:00 et 10:00 ? », « quel est le volume B2B intra-UE pour le rapport DRR du 30 juin 2026 ? », « quel est le top-10 des partenaires par volume horaire ? ». Ces agrégats nécessitent de découper le flux en segments temporels disjoints sur lesquels appliquer la fonction d'agrégation.
Forces
- Cardinalité prévisible : chaque évènement appartient à exactement une fenêtre.
- Event-time vs processing-time : le bon choix dépend de la fonction métier (rapport fiscal = event-time strict).
- Watermarks : nécessaires pour savoir quand une fenêtre est « définitivement complète ».
- Late data : que faire des évènements qui arrivent après la fermeture (drop, side-output, reprocess) ?
- Granularité : trop grosse = latence excessive ; trop fine = overhead state énorme.
Solution
Définir une taille de fenêtre fixe W (ex. 1 heure) et un référentiel temporel (event-time recommandé : timestamp du message à la source). Chaque évènement est routé vers la fenêtre [floor(ts/W)*W, floor(ts/W)*W + W). Quand la watermark dépasse la fin d'une fenêtre, on émet le résultat agrégé et on libère le state. Pour les évènements en retard (late data), choisir un policy : drop, side output vers une dead-letter, ou allowed lateness (Flink) qui maintient la fenêtre ouverte un délai supplémentaire et émet une mise à jour. Apache Flink, Spark Structured Streaming, Kafka Streams, Google Dataflow implémentent toutes ce pattern nativement.
Structure
Time: 09:00────────10:00────────11:00────────12:00────────►
┌────────────┐┌────────────┐┌────────────┐
Window: │ W0 (09h) ││ W1 (10h) ││ W2 (11h) │
└────────────┘└────────────┘└────────────┘
Events: ●● ● ● ●● ●●● ● ●● ● ●●●
│ │ │
09:01 10:05 11:10
│ │
09:42 ↓
09:55 ◄── arrives at 10:03 (LATE for W0!)
→ drop, side-output, or allowed lateness?
When watermark passes 10:00:
W0 closes → emit (W0, count=5)
When watermark passes 11:00:
W1 closes → emit (W1, count=4) Implémentation EDI
Trois cas EDI canoniques. (1) Reporting fiscal périodique : agréger les factures e-invoicing par fenêtre de 24h (UTC pour ZATCA, Europe/Paris pour PPF France) pour produire le batch quotidien à transmettre à l'administration. (2) KPI opérationnels par heure : count par partenaire, latence moyenne d'acquittement, top erreurs syntaxiques sur la dernière heure pour dashboard SRE. (3) Rate limiting comptable : si plus de N factures par minute pour un même émetteur, déclencher une revue manuelle (détection de robot de facturation suspect). Implémentation type Flink : stream.keyBy(senderGLN).window(TumblingEventTimeWindows.of(Time.hours(1))).aggregate(new CountAggregator()). Pour DRR ViDA (Digital Reporting Requirements, juillet 2030), la fenêtre quotidienne event-time avec allowed lateness de 24h est un pattern canonique pour produire le rapport à J+1 même avec quelques messages en retard.
Anti-patterns
- Utiliser processing-time pour un rapport fiscal — les replays produisent des résultats incohérents avec le batch initial.
- Watermark trop agressive — beaucoup de late data perdues, sous-déclaration fiscale possible.
- Fenêtre trop fine sur des flux à fort cardinality — explose le state RocksDB en plusieurs To.
- Pas de gestion du late data — un message PEPPOL qui arrive 6h en retard à cause d'un access point en panne n'est jamais comptabilisé.
- Mélanger fuseaux horaires sans aligner au UTC — la fenêtre 00h-01h Europe/Paris en heure d'été n'est pas alignée sur UTC.
Patterns liés
- Sliding Window — fenêtre glissante (chevauchement).
- Session Window — fenêtre activity-based.
- Watermarks — mécanisme qui clôt les fenêtres.
- Exactly-Once Semantics — souvent requis pour rapport fiscal exact.
Sources
- Akidau T. et al. — The Dataflow Model: A Practical Approach to Balancing Correctness, Latency, and Cost in Massive-Scale, Unbounded, Out-of-Order Data Processing, VLDB 2015. research.google
- Apache Flink documentation — Windows. nightlies.apache.org/flink
- Spark Structured Streaming — Window operations on event time. spark.apache.org
- Akidau T., Chernyak S., Lax R. — Streaming Systems, O'Reilly 2018, chap. 1-3.
- Kafka Streams documentation — Windowing. kafka.apache.org