Skip to content

Latest commit

 

History

History
793 lines (576 loc) · 18.9 KB

File metadata and controls

793 lines (576 loc) · 18.9 KB
theme default
class text-center
highlighter shiki
lineNumbers false
info ## Architecture Streaming-First Techtalk PMU - De l'échange de fichiers quotidiens au streaming temps réel
drawings
persist
transition slide-up
title Architecture Streaming-First
mdc true
css unocss
layout pmu-cover

::title:: Meetup PMU Tech

::subtitle:: 13 Novembre 2025


layout: pmu-speaker transition: slide-left

::talk:: Architecture Streaming-First

::speaker:: Laurent Valdes


layout: pmu-slide transition: slide-left

::title::

Contexte PMU

::contents::

Une architecture historique à base de fichiers

Notre architecture actuelle repose sur un système de passerelles de fichiers Cette architecture a été transcrite sur AWS :

  • Stockage des fichiers sur S3
  • Traitement via Lambda (serverless)
  • Maintien du paradigme batch dans le cloud

Réflexion stratégique

Aujourd'hui, nous menons une réflexion de fond sur comment dynamiser les échanges :

  • Passer d'une logique de cycles de traitement à une logique de fraîcheur de données
  • Transformer notre approche pour répondre aux besoins temps réel
  • Moderniser notre architecture tout en capitalisant sur l'existant

layout: pmu-slide transition: slide-left

::title::

Objectif de cette présentation

::contents::

Déconstruire un mythe

Batch ≠ Simplicité - Les architectures batch cachent une complexité opérationnelle massive derrière une apparente simplicité.

Démontrer que

  • 🎯 Streaming-First est plus simple à opérer avec les bons outils
  • 📊 La fraîcheur des données est un critère qualitatif fondamental
  • Le temps réel est une nécessité métier, pas un luxe

layout: pmu-slide transition: slide-up

::title::

Agenda

::contents::

  • 📦 Architectures à base de fichiers quotidiens
  • ⚠️ Problématiques métier induites
  • 🚀 Architecture Streaming-First
  • 📊 Comparaison Batch vs Streaming
  • 🏗️ Architecture type & Démo

layout: pmu-section transition: slide-left

::title::

Architectures à base de fichiers quotidiens

::subtitle::

Rappel des caractéristiques des architectures batch traditionnelles


layout: pmu-slide transition: slide-left

::title::

Architecture Batch Traditionnelle

::contents::

graph LR
    A[Système A] -->|CSV J+1| B[FTP]
    C[Système B] -->|XML J+1| B
    D[Système C] -->|JSON J+1| B
    B -->|Batch| E[ETL]
    E --> F[DW]
    F -->|J+1| G[Apps]
    
    style A color:#FFFFFF,stroke:#000
    style C color:#FFFFFF,stroke:#000
    style D color:#FFFFFF,stroke:#000
    style E color:#FFFFFF,stroke:#000
    style G color:#FFFFFF,stroke:#000

    style B fill:#ff6b6b,color:#FFFFFF,stroke:#000
    style E fill:#ff6b6b,color:#FFFFFF,stroke:#000
    style F fill:#ffd93d,color:#000000,stroke:#000
    linkStyle 0 stroke-width:2px,fill:none,stroke:black,color:white;
    linkStyle 1 stroke-width:2px,fill:none,stroke:black,color:white;
    linkStyle 2 stroke-width:2px,fill:none,stroke:black,color:white;
    linkStyle 3 stroke-width:2px,fill:none,stroke:black,color:white;
    linkStyle 4 stroke-width:2px,fill:none,stroke:black,color:white;
    linkStyle 5 stroke-width:2px,fill:none,stroke:black,color:white;

Loading
  • Passerelles de fichiers via FTP, SFTP, partages réseau
  • Schémas hétérogènes : CSV, XML, JSON, formats propriétaires
  • Transformations multiples : nettoyage, normalisation, enrichissement

layout: pmu-slide transition: slide-up

::title::

Impact sur la Gouvernance Data

::contents::

Critère Impact
Fraîcheur des données ❌ J+1 minimum, souvent J+7
Qualité ⚠️ Détection d'erreurs tardive
Traçabilité 📋 Complexe avec transformations multiples
Coût opérationnel 💰 Élevé : stockage, transferts, monitoring
Time-to-insight 🐌 24h+ minimum

layout: pmu-section transition: slide-left

::title::

Problématiques Métier

::subtitle::

Les impacts concrets sur le business


layout: pmu-slide transition: slide-left

::title::

1. Client en Attente du Batch

::contents::

%%{init: {'themeVariables': {'primaryColor':'#ffffff', 'primaryBorderColor':'#000000', 'primaryTextColor':'#000000', 'secondBkgColor':'#ffffff', 'secondBorderColor':'#000000', 'secondTextColor':'#000000', 'tertiaryColor':'#ffffff', 'tertiaryBorderColor':'#000000', 'tertiaryTextColor':'#000000', 'noteBkgColor':'#ffffcc', 'noteBorderColor':'#000000', 'lineColor':'#000000', 'signalTextDirMargin':'10px'}, 'sequence': {'mirrorActors': true, 'messageAlign': 'center', 'actorFontFamily': 'Arial', 'actorFontSize': '14px', 'messageFontFamily': 'Arial', 'noteFontFamily': 'Arial'}}, 'flowchart': {'useMaxWidth': false}}%%
sequenceDiagram
    participant C as Client
    participant A as App
    participant B as Batch
    participant D as Data
    
    C->>A: Action 23h45
    A->>B: Enregistrement
    Note over B: Batch nocturne
    B->>D: Traitement 02h
    D->>A: Dispo 08h
    A->>C: Confirmation J+1
    
    Note over C: 8h d'attente !
Loading

Impact : Expérience client dégradée et perte de confiance


layout: pmu-slide transition: slide-left

::title::

2. Données Marketing Obsolètes

::contents::

Scénario typique

  • Campagne email lundi matin basée sur données du vendredi
  • => clients déjà convertis reçoivent encore des offres.

Résultat:

  • 📉 Taux de conversion réduit
  • 💸 Budget marketing gaspillé
  • 😠 Irritation client

Chiffres:

  • 📉 -30% de pertinence des campagnes
  • 💸 15-20% du budget marketing gaspillé

layout: pmu-slide transition: slide-left


::title::

3. Données Commerciales Périmées

::contents::

Impact sur les équipes commerciales

  • 📦 Stocks : vente de produits indisponibles
  • 💰 Pricing : tarifs non actualisés
  • 🎯 Opportunités : leads qualifiés traités trop tard

Exemple concret

  • 📅 Vendredi 18h : lead qualifié arrive.
  • ⏸️ Weekend : aucun traitement.
  • 📞 Lundi 10h : lead enfin disponible pour le commercial.

🫏 Résultat : le concurrent a déjà contacté le prospect.


layout: pmu-slide transition: slide-left

::title::

4. Désynchronisation Backend

::contents::

graph TB
    A1[Backend A<br/>J-1] 
    B1[Backend B<br/>J-7]
    C1[Backend C<br/>J-3]
    D[Frontend]
    
    D --> A1
    D --> B1
    D --> C1
    
    style D fill:#ffe66d,color:#000000
    style A1 fill:#ffe66d,color:#000000
    style B1 fill:#ff6b6b,color:#000000
    style C1 fill:#ffa94d,color:#000000
    linkStyle 0 stroke-width:3px,fill:none,stroke:black,color:white;
    linkStyle 1 stroke-width:3px,fill:none,stroke:black,color:white;
    linkStyle 2 stroke-width:3px,fill:none,stroke:black,color:white;

Loading

Conséquence : incohérences applicatives, bugs et perte de confiance utilisateur


layout: pmu-slide transition: slide-up

::title::

5. Qualité des Données Réduite

::contents::

La fraîcheur = Critère qualitatif majeur

Dimension Qualité Impact Batch
Exactitude ⚠️ Données périmées = données fausses
Complétude ❌ Données manquantes jusqu'au batch
Cohérence ❌ Versions multiples en circulation
Actualité ❌ Délai minimum 24h
Fiabilité ⚠️ Échecs de batch = données manquantes

Référentiel DAMA-DMBOK

  • Les 6 dimensions de qualité des données incluent l'actualité (Timeliness) comme critère critique.
  • => Des données exactes mais périmées sont inutilisables.

layout: pmu-section transition: slide-left

::title::

Architecture Streaming-First

::subtitle::

Le paradigme du temps réel


layout: pmu-slide transition: slide-left

::title::

Principe Fondamental

::contents::

Streaming-First = Streaming par défaut

  1. Faire les choses d'abord en streaming
  2. Ne pas faire en streaming uniquement si impossible

Rappel important

  • 📄 Un fichier est un stream de données
  • 📦 Un groupe de fichiers est un stream de streams
  • 🌊 Dans une architecture streaming-first : un stream est juste un stream

Mindset shift

On parle de flux de données avant de parler de fichiers ou de messages. On optimise la fraîcheur avant de parler du middleware.


layout: pmu-slide transition: slide-left

::title::

Architecture (processing)

::contents::

IngestionBrokerProcessing

graph LR
    F[Fichiers] --> FC[File<br/>Connector]
    API[APIs] --> HC[HTTP<br/>Source]
    DB[(DB)] --> CDC[CDC<br/>Debezium]
    IOT[IoT] --> MQTT[MQTT<br/>Connector]
    
    FC --> K[Kafka<br/>Broker]
    HC --> K
    CDC --> K
    MQTT --> K
    
    K -.-> SR[Schema<br/>Registry]
    
    K --> SP[Stream<br/>Processing]
    
    SP --> T[Transform]
    SP --> J[Join]
    SP --> A[Aggregate]
    SP --> W[Window]
    
    style K fill:#4ecdc4,color:#000000
    style SP fill:#95e1d3,color:#000000
    style F color:#FFFFFF
    style API color:#FFFFFF
    style DB color:#FFFFFF
    style FC color:#FFFFFF
    style CDC color:#FFFFFF
    style MQTT color:#FFFFFF
    style IOT color:#FFFFFF
    style HC color:#FFFFFF
    style K color:#000000
    style SR color:#FFFFFF
    style SP color:#000000
    style T color:#FFFFFF
    style J color:#FFFFFF
    style A color:#FFFFFF
    style W color:#FFFFFF

    linkStyle 0 stroke-width:3px,fill:none,stroke:black,color:white;
    linkStyle 1 stroke-width:3px,fill:none,stroke:black,color:white;
    linkStyle 2 stroke-width:3px,fill:none,stroke:black,color:white;
    linkStyle 3 stroke-width:3px,fill:none,stroke:black,color:white;
    linkStyle 4 stroke-width:3px,fill:none,stroke:black,color:white;
    linkStyle 5 stroke-width:3px,fill:none,stroke:black,color:white;
    linkStyle 6 stroke-width:3px,fill:none,stroke:black,color:white;
    linkStyle 7 stroke-width:3px,fill:none,stroke:black,color:white;
    linkStyle 8 stroke-width:3px,fill:none,stroke:black,color:white;
    linkStyle 9 stroke-width:3px,fill:none,stroke:black,color:white;
    linkStyle 10 stroke-width:3px,fill:none,stroke:black,color:white;
    linkStyle 11 stroke-width:3px,fill:none,stroke:black,color:white;
    linkStyle 12 stroke-width:3px,fill:none,stroke:black,color:white;
    linkStyle 13 stroke-width:3px,fill:none,stroke:black,color:white;

Loading

layout: pmu-slide transition: slide-left

::title::

Architecture (mise à disposition)

::contents::

ProcessingStockageConsommation

%%{init: {'flowchart': {'rankSpacing': 110, 'nodeSpacing': 25, 'diagramMarginX': 100, 'diagramMarginY': 50, 'useMaxWidth': true}}}%%
graph LR
    subgraph Processing["⚙️ Processing"]
        SP[Flink/Streams]
    end
    
    subgraph Storage["💾 Stockage"]
        DW[(ClickHouse<br/>OLAP)]
        TS[(TimescaleDB<br/>Time Series)]
        ES[(Elasticsearch<br/>Search)]
    end
    
    subgraph Consumption["📊 Consommation"]
        BI[Superset<br/>BI/OLAP]
        RT[Apps<br/>Temps Réel]
        DASH[Dashboards]
        ML[ML/Analytics]
    end
    
    SP --> DW
    SP --> TS
    SP --> ES
    
    DW --> BI
    DW --> ML
    TS --> DASH
    ES --> RT
    
    style SP fill:#95e1d3,color:#000000
    style DW fill:#f38181,color:#000000
    style TS fill:#f38181,color:#000000
    style ES fill:#f38181,color:#000000
    style BI fill:#aa96da,color:#000000
    style RT color:#FFFFFF
    style DASH color:#FFFFFF
    style ML color:#FFFFFF

    linkStyle 0 stroke-width:3px,fill:none,stroke:black,color:white;
    linkStyle 1 stroke-width:3px,fill:none,stroke:black,color:white;
    linkStyle 2 stroke-width:3px,fill:none,stroke:black,color:white;
    linkStyle 3 stroke-width:3px,fill:none,stroke:black,color:white;
    linkStyle 4 stroke-width:3px,fill:none,stroke:black,color:white;
    linkStyle 5 stroke-width:3px,fill:none,stroke:black,color:white;
    linkStyle 6 stroke-width:3px,fill:none,stroke:black,color:white;

Loading

layout: pmu-slide transition: slide-left

::title::

Stack Technologique De Référence

::contents::

Pour faire une architecture streaming-first, il faut:

Un Broker

  • Apache Kafka : standard industrie, écosystème riche
  • Apache Pulsar ou NATS Jetstream : multi-tenancy, geo-replication native OU léger, performant, simple

Du Stream Processing

  • Apache Flink ou Kafka Streams : état de l'art, exactly-once, stateful

Un Data Warehouse

  • ClickHouse : OLAP temps réel, ingestion streaming native
  • Apache Druid : analytics temps réel, sub-second queries

De la Visualisation & de la BI

  • Apache Superset OU Looker : BI moderne, OLAP, exploration de données

layout: pmu-slide transition: slide-up

::title::

Composants de l'Architecture

::contents::

Ingestion Streaming vers DW

-- ClickHouse Kafka Engine with AVRO Format
CREATE TABLE sales_stream (
    timestamp DateTime64(3),
    product_id String,
    amount Decimal(10,2)
) ENGINE = Kafka()
SETTINGS
    kafka_broker_list = 'kafka:29092',
    kafka_topic_list = 'sales',
    kafka_format = 'AvroConfluent',
    [...]

BI & Visualisation Temps Réel

  • Requêtes ad-hoc directes sur ClickHouse, drill-down hiérarchique
  • Applications custom via WebSocket depuis Kafka pour le temps réel.

layout: pmu-section transition: slide-left

::title::

Comparaison

::subtitle::

Batch vs Streaming-First


layout: pmu-slide transition: slide-left

::title::

Tableau Comparatif

::contents::

Critère Architecture Batch Architecture Streaming-First
Latence 24h - 7 jours Millisecondes - Secondes
Fraîcheur données ❌ J+1 minimum ✅ Temps réel
Scalabilité ⚠️ Verticale limitée ✅ Horizontale illimitée
Monitoring 📊 Batch (post-mortem) 📈 Continu (proactif)
Coût infrastructure 💰 Pics nocturnes 💰 Lissé 24/7
Gestion erreurs ❌ Détection tardive ✅ Détection immédiate
Time-to-market 🐌 Lent (dépendances batch) 🚀 Rapide (découplage)

layout: pmu-slide transition: slide-left

::title::

Tableau Comparatif (suite)

::contents::

Critère Architecture Batch Architecture Streaming-First
Cohérence données ⚠️ Versions multiples ✅ Source unique de vérité
Gouvernance 📋 Complexe (multiples copies) ✅ Simplifiée (event log)
Réactivité métier 🐌 Lendemain ⚡ Immédiate
Debugging 🔍 Difficile (logs dispersés) 🔍 Facilité (replay events)
Évolutivité ⚠️ Refonte complète ✅ Ajout de consumers
Cas d'usage Reporting historique Temps réel + Historique

layout: pmu-section transition: slide-left

::title::

Architecture Type & Démo

::subtitle::

Mise en pratique avec Docker


layout: pmu-slide transition: slide-left

::title::

Architecture Technique de la Démo

::contents::

graph LR
    subgraph "Production de Données"
        FG[File Generator<br/>Python + Faker]
        FG -->|CSV/JSON| INPUT[/data/input/]
    end

    subgraph "Ingestion Avro"
        INPUT -->|Lecture| CSV2K[CSV-to-Kafka<br/>Producer]
        CSV2K -->|Avro| KAFKA

        SP[Streaming<br/>Producer<br/>Python] -->|Avro<br/>Temps Réel| KAFKA
    end

    subgraph "Kafka Ecosystem"
        ZK[Zookeeper]
        KAFKA[Kafka Broker<br/>Port 9092]
        SR[Schema Registry<br/>Port 8081]

        ZK -.->|Coordination| KAFKA
        KAFKA <-->|Schémas Avro| SR
    end

    subgraph "Consommation"
        KAFKA -->|Topic: bets<br/>Format: AvroConfluent| CH
        KAFKA -->|Topic: customers<br/>Format: AvroConfluent| CH

        CH[(ClickHouse<br/>OLAP Engine<br/>Port 8123)]

        CH -->|Kafka Engine| CHTABLES[Tables MergeTree<br/>+ Vues Matérialisées]
    end

    subgraph "Visualisation"
        CHTABLES -->|SQL| SUPERSET[Superset<br/>BI Analytics]
        CHTABLES -->|HTTP API| SLIDEV[Slidev<br/>Stats Temps Réel]
    end

    subgraph "Monitoring"
        KAFKA -.->|Monitoring| KAFKAUI[Kafka UI<br/>Port 8080]
    end

    style KAFKA fill:#FFFFFF,color:black,stroke:#000,stroke-width:3px
    style SR fill:#FFFFFF,color:black,stroke:#000,stroke-width:3px
    style CH fill:#FFFFFF,color:black,stroke:#000,stroke-width:3px
    style SUPERSET fill:#FFFFFF,color:black,stroke:#000,stroke-width:3px
    style SLIDEV fill:#FFFFFF,color:black,stroke:#000,stroke-width:3px
    style CSV2K fill:#FFFFFF,color:black,stroke:#000,stroke-width:3px
    style SP fill:#FFFFFF,color:black,stroke:#000,stroke-width:3px
    style CHTABLES fill:#FFFFFF,color:black,stroke:#000,stroke-width:3px

    linkStyle 0 stroke-width:3px,fill:none,stroke:black,color:black;
    linkStyle 1 stroke-width:3px,fill:none,stroke:black,color:black;
    linkStyle 2 stroke-width:3px,fill:none,stroke:black,color:black;
    linkStyle 3 stroke-width:3px,fill:none,stroke:black,color:black;
    linkStyle 4 stroke-width:3px,fill:none,stroke:black,color:black;
    linkStyle 5 stroke-width:3px,fill:none,stroke:black,color:black;
    linkStyle 6 stroke-width:3px,fill:none,stroke:black,color:black;
    linkStyle 7 stroke-width:3px,fill:none,stroke:black,color:black;
    linkStyle 8 stroke-width:3px,fill:none,stroke:black,color:black;
    linkStyle 9 stroke-width:3px,fill:none,stroke:black,color:black;
    linkStyle 10 stroke-width:3px,fill:none,stroke:black,color:black;
    linkStyle 11 stroke-width:3px,fill:none,stroke:black,color:black;

Loading
--- layout: pmu-slide transition: slide-up --- ::title::

Démo Time! 🚀

::contents::

Lançons l'architecture streaming-first

docker-compose up -d

layout: pmu-slide transition: slide-left

::title::

📊 Statistiques Temps Réel (fin de la démo !)

::contents::


layout: pmu-section

::title::

Merci !

::subtitle::

Des questions ? Ouvrez ce QR code pour participer !

QR Code for Questions