[DevoxxFR 2014] Basse fréquence / haut débits les secrets de la finances pour avoir des systèmes réactifs.

double_xx_textePour cette présentation, 2 architectes de la Société Générale nous ont illustré un retour d’expérience sur la mise en place de la programmation réactive pour des enjeux de salles de marché. Pour nous faire comprendre les problématiques de leur métier, Thomas PIERRAIN et  Cyrille DUPUYDAUBY ont imaginé un jeu de rôle ayant pour but la réalisation d’un «Pricer » de pâtes pour un supermarché un peu particulier.

Partant d’une approche naïve qu’ils vont raffiner jusqu’à la simulation de la solution appliquée à la SGCIB, ils vont nous introduire les grands principes de la programmation réactive et les écueils rencontrés. La présentation était très vivante Thomas PIERRAIN ayant pris le rôle de l’équipe technique nous présentant les solutions alors que Cyrille Dupuydauby dans celui du product owner indiquait les problématiques fonctionnelles. En sus un sage diffusait à bon escient quelques principes du reactive manifesto ou des grands principes généraux de la programmation concurrente tels que « qui dit lock… dit deadlock ».

Contexte du « supermarché »

Le supermarché qui va servir d’exemple est un modèle simplifié d’un marché financier il a les règles suivantes

  • le prix des articles fluctue sans cesse
  • dès la mise dans le caddie l’article est acheté
  • on est par contre payé dès que l’on repose un article en rayon

Dans ce supermarché plusieurs types de populations sont susceptibles d’intervenir:

  • L’acheteur ayant reçu les instructions d’achat d’un tiers (investisseurs)
  • Des clients cherchant à profiter des hausses et baisses (arbitragistes / scalper)
  • Des clients hyper spécialisé et hyper efficaces sur un certain type de produit (algorithmes de trading).

Au vu de ces populations on comprend que la fluctuation des prix doit être appliquée très rapidement afin que le supermarché ne soit pas trop pénalisé. Pour répondre à ce besoin, l’équipe veut réaliser un Pricer permettant d’établir en temps réel le prix des pâtes.

Les données du Pricer

Les pâtes peuvent être de différentes formes pennes/farfalles/spaghettis/gnocchi…, avec ou sans œufs, bio ou non, aromatisées aux épinard, carottes.. on a donc 2400 types de pâtes.

Le prix de chaque ingrédient ainsi que celui du carton peut faire varier le prix d’un type de pâtes.

Les informations de variation des prix arrivent sous forme d’événements tout au long de la journée.

Modèle du pricer v1: version séquentielle

Le principe du pricer est le suivant :

    réception des événements --> calcul des prix -->émission des prix

La première version consiste à appliquer l’événement séquentiellement sur chaque type de pâte qu’il peut impacter.

Par exemple pour le prix du blé on va avoir :

    réception du prix du blé
    → calcul du prix des gnocchis → émission
    → calcul du prix des pennes → émission
    ...
    

Problème: le temps de latence sur les derniers calculs.

Modèle du pricer v2: version totalement parallèle

Afin d’essayer d’optimiser les calculs, une deuxième approche consiste à tout paralléliser. On fait ainsi 1 Thread par type de pâte soit 2400 Threads en parallèle

Problème: Context switch trop important on va perdre énormément de temps à passer d’un Thread à l’autre alors que la machine n’a de toute façon pas la capacité de gérer plus d’une dizaine de Threads en parallèle.

Modèle du pricer v3: pool de thread

Un nombre fini de Thread est attribué pour la résolution avec un mécanisme de répartition en entrée afin de répartir équitablement la charge.

Problème: Race condition: on peut se retrouver avec un résultat ne prenant pas en compte les dernières données. Un calcul sur les dernières données peut se retrouver écrasé par la fin d’un calcul sur des données plus anciennes ayant un temps de traitement plus long.

Modèle du pricer v4: séquencer

Un « séquencer » est associé à chaque calcul de prix afin de s’assurer de l’ordre d’exécution des calculs. Lors de son exécution, le calcul interrogera en effet le séquencer pour vérifier s’il ne doit pas attendre la fin d’un calcul en cours.

Problème: Si tous les Thread sont occupés, une file d’attente d’événements entrants va se former. Cela peut conduire lors de la reprise des traitements à faire des calculs sur des données déjà obsolètes. (Si par exemple deux prix de farine différents sont arrivés)

Modèle final: séquencer + conflation

Afin de résoudre ce problème de données déjà obsolètes au moment de leur traitement, un mécanisme de conflation va être mis en place lors des pics de charge pendant lesquels le système est saturé, provoquant l’accumulation des évènements. La conflation consiste à réduire les évènements de la file afin de ne pas conserver de valeurs obsolètes.

2 modèles nous ont été montrés :

  • une approche en annule et remplace : dès qu’un nouveau prix pour la denrée X entre dans la file les prix déjà dans la file pour la denrée X sont supprimés
  • une approche par merge : les événements sont groupés par type et à partir de chaque groupe un événement unique est retransmis.

Ce petit exercice nous a montré quelques principes de programmation réactive, en illustrant les problématiques que peut rencontrer une structure telle que la Société Générale et nous invite à aller plus loin dans la connaissance de ces sujets.

Nombre de vue : 48

COMMENTAIRES 1 commentaire

  1. Fabrice Sznajderman dit :

    Hello,

    Article très clair et intéressant.
    Il n’y aurait pas une petite coquille sur cette phrase : on est par contre payé dès que l’on repose un article en rayon
    Il ne manquerait un : ‘pas’ ?

    Fabrice

AJOUTER UN COMMENTAIRE