Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Quand performance, scalabilité et robustesse bo...

Quand performance, scalabilité et robustesse bousculent votre architecture et vos habitudes de développement

Le projet sur lequel vous travaillez doit être capable d'intégrer des centaines de millions d'événements par jour.
Face à cette volumétrie de traitements et de calculs, votre architecture doit tenir et auto-scaler pour encaisser les variations de charge.

Il s'agit ici de faire un retour d'expérience sur les points d'attention et les patterns à suivre dès le départ.
Nous verrons comment découper et organiser vos traitements, comment décorréler votre modèle métier de votre modèle de stockage et comment définir une stratégie de tests dans un tel système.

Céline Gilet

November 09, 2018
Tweet

More Decks by Céline Gilet

Other Decks in Programming

Transcript

  1. Quand performance, scalabilité et robustesse bousculent votre architecture et vos

    habitudes de développement Retour d’expérience Céline Gilet
  2. Faisons connaissance • Tribu Software Craftsmanship à OCTO Technology •

    Développeuse depuis + de 10 ans • Conseil & accompagnement sur les pratiques de qualité logicielle • Formation (Test Driven Development, Clean Code, Legacy Code..) @celinegilet Céline Gilet
  3. Contexte du retour d’expérience • Le futur système de comptabilité

    d’un des grands acteurs du secteur bancaire • Design d’une architecture capable de répondre aux enjeux croissants de volumétrie • Intégration, calcul et export sur des centaines de millions de données par jour • Performance, scalabilité et robustesse comme ligne directrice • Plateau de développement agile de 30 personnes sur 10 mois ◦ Mise à l’épreuve de l’architecture sur la réalisation de fonctionnalités clés ◦ Différents profils : architectes, business analysts, coachs, développeurs, ops
  4. Le composant comme unité clé de l’architecture COMPOSANT • Un

    rôle clair - pouvoir pitcher le job du composant en 1 phrase : son why • Une déclinaison logique et cohérente de ses fonctionnalités • Une mise à disposition de ses services sous plusieurs formes • Une responsabilité à vision fonctionnelle ou technique • Un modèle de passage à l’échelle (scalabilité / auto-scalabilité) • Testable facilement et rapidement • Autonome et indépendant au niveau “build” et “deploy” • Ouvert aux changements et évolutions (frameworks, stockage...) • Garant des performances sur des échelles de volumétries cibles • Tolérant aux pannes et mécanismes de rejeu (robustesse) Périmètre Caractéristiques
  5. Un exemple : le composant d’intégration INTEGRATION Objectif : intégrer

    le plus rapidement possible les données des mouvements financiers d’entités pour pouvoir déclencher les agrégations et calculs comptables Fonctionnalités et traitements métier du composant Fichier de mouvements financiers Mouvements financiers présents en comptabilité Parsing de données Contrôle de validité Defaulting Enrichissement
  6. Assemblage et orchestration des composants • Un composant est un

    maillon de la chaîne pour réaliser un traitement métier de bout en bout • La succession de composants représente un pipeline • Un pipeline se définit par : ◦ Un déclencheur ◦ Des données en entrée ◦ Une séquence de composants à appeler ◦ Un résultat produit • Deux typologies de pipelines : Flux et Batch • Émergence d’un nouveau composant d’orchestration : pas de communication directe entre composants métier Pipeline : “Intégration des mouvements financiers” INTÉGRATION COMPOSANT X COMPOSANT Y EXPORT Cluster Cassandra ORCHESTRATION Oracle Mouvements Financiers Fichiers produits
  7. Stockage des données d’un pipeline • Chaque composant dialogue avec

    UNE seule base de données ◦ Composants métiers => Cassandra ◦ Composant orchestration => Oracle • L’écriture d’une table est gérée par UN seul composant • La lecture d’une table est possible par plusieurs composants • Un quadrigramme par composant pour identifier facilement quel composant est responsable de l’écriture d’une table ◦ Composant INTÉGRATION => INTG ◦ Table INTG_FINANCIAL_POSTING Pipeline : “Intégration des mouvements financiers” INTÉGRATION COMPOSANT X COMPOSANT Y EXPORT Cluster Cassandra ORCHESTRATION Oracle Mouvements Financiers Fichiers produits
  8. Relationnel vs Non-Relationnel Base de données relationnelles ๏ Avantages <

    Technologie mature (SQL) < Transactions ACID < Requêtes complexes avec jointures multiples ๏ Inconvénients < Modèle de scaling vertical < Volumétrie moyenne < Concurrence / performance limitée < Coût de licence Apache Cassandra ๏ Avantages < Modèle de scaling horizontal < Base de données distribuée < Performance prédictible < Haute disponibilité < Scalabilité linéaire < Forte volumétrie “Big Data” ๏ Inconvénients < Langage dédié : CQL < Pas de transactions natives < Pas de jointures
  9. Pourquoi Apache Cassandra ? Cassandra impose une modélisation & un

    stockage spécifiques pour pouvoir prétendre à la performance et à la scalabilité linéaire Cassandra n’est pas là pour remplacer les bases de données relationnelles Les besoins sont différents et les 2 approches peuvent cohabiter Modélisation • Partir des cas d’utilisation métier pour avoir les patterns d’accès aux données • Design per query : disposer des requêtes de lecture pour pouvoir écrire de façon à avoir de la performance Stockage • L’unité de traitement clé : les partitions • Distribution des partitions parmi les noeuds du cluster • Cible : 1 requête, 1 partition, 1 noeud
  10. La Clean Architecture comme point de départ • La valeur

    d’un composant réside dans ses cas d’utilisation et ses services métiers • Isoler et protéger cette valeur des changements et évolutions techniques • Décorréler le modèle métier du modèle de stockage • Le domaine métier d’un composant n’ évolue pas au même rythme que les éléments techniques (frameworks, base de données, infra…) • Pas de dispersion de la logique métier dans plusieurs couches • Des tests ciblés sur une problématique précise : rapidité, fiabilité et robustesse • Une prise en compte des aspects techniques à posteriori • Un découpage par responsabilité pour favoriser les évolutions et accélérer le cycle des déploiements
  11. La Clean Architecture comme point de départ INFRASTRUCTURE USE CASES

    DOMAIN COMPOSANT POINTS D'ENTRÉE FOURNISSEURS DE DONNÉES APIs JMS EVENTS JOBS GUI Bases de données Système de fichiers CONFIGURATION
  12. Stratégie de tests d’un composant en 2 volets MÉTIER PERFORMANCE

    Fonctionnalités métier INFRASTRUCTURE USE CASES DOMAIN • Clean Architecture • Piloté par les tests (TDD)
  13. Stratégie de tests d’un composant : le volet métier MÉTIER

    Unitaire Intégration Fonctionnel Coût Temps d’exécution Précision / Fiabilité Rapidité Quantité de tests Fonctionnalités métier INFRASTRUCTURE USE CASES DOMAIN • Clean Architecture • Piloté par les tests (TDD) • Example Mapping (BDD) • Event Storming (DDD) Méthodologie • Appropriation du contexte métier à travers des exemples et des sessions d’Event Storming • Valider au plus tôt le bon fonctionnement des use-cases : “Apport rapide de valeur” • Respect de la pyramide des tests • Automatisation du calcul de la pyramide des tests et du respect de la clean archi dans la phase de qualimétrie des builds
  14. Stratégie de tests d’un composant : le volet perf PERFORMANCE

    Temps de réponse sur des volumétries cibles Linéarité des temps de réponse Fonctionnalités métier INFRASTRUCTURE USE CASES DOMAIN • Clean Architecture • Piloté par les tests (TDD) Méthodologie • Des uses-cases valides fonctionnellement mais qui potentiellement n’ont pas des temps de réponse acceptable et linéaire • Discussion avec le métier pour trouver un axe de parallélisation / répartition des calculs • Passage éventuel des use-cases sous Apache Flink (Framework de traitements distribués)
  15. Performance d’un composant : une démarche en 3 phases EXPÉRIMENTER

    FORMALISER ANALYSER PHASE D’EXPLORATION / APPRENTISSAGE RÉCOLTER LES MÉTRIQUES LANCER LES SCÉNARIOS DE PERF ALERTER PHASE D’AUTOMATISATION / INDUSTRIALISATION HISTORISER RÉCOLTER LES MÉTRIQUES LANCER LE SCÉNARIO A OPTIMISER PHASE D’OPTIMISATION TESTER UNE PISTE A LA FOIS 1 2 3
  16. Performance d’un composant : “Formaliser” Formaliser une démarche et une

    stratégie de performance • Définir les scénarios envisagés pour le composant (qualité vs quantité) • Établir des échelles de volumétrie progressives • Disposer de données représentatives métier (récupération de fichiers de données de production) • Identifier les éventuels composants en dépendance (amont / aval) + les systèmes externes pour bouchonnage • Prévoir un mécanisme d’injection de données pour le composant (référentiels, paramétrage…) EXPÉRIMENTER FORMALISER ANALYSER PHASE D’EXPLORATION / APPRENTISSAGE FORMALISER 1
  17. Performance d’un composant : “Expérimenter” Expérimenter la démarche formalisée sur

    une FAIBLE volumétrie • Figer une version applicative stable et durcie (périmètre fonctionnel validé) • Disposer d’un environnement dédié à la performance en isolation complète (pas de conflits sur les données et fichiers manipulés) • Pouvoir être indépendant vis à vis des problématiques d’infrastructure : cluster Kubernetes, stack ELK… • Pouvoir lancer le composant sur un poste de développeur pour des besoins de debug et pour avoir une boucle de feedback rapide EXPÉRIMENTER FORMALISER ANALYSER PHASE D’EXPLORATION / APPRENTISSAGE EXPÉRIMENTER 1
  18. Performance d’un composant : “Analyser” Analyser les résultats pour apprendre

    avant d’automatiser • Déterminer les moyens de collecte des métriques applicatives : api, logs, requêtes en base de données… • Prévoir des endpoints donnant l’état d’avancement d’un traitement en mode asynchrone • Adapter la configuration des logs pour avoir le bon niveau d’information (level + logger dédié à la perf) • Etre vigilant sur l’analyse des logs : présence d’erreurs et niveau de verbosité pouvant altérer les performances • Contrôler la collecte des métriques système : CPU, Mémoire, I/O EXPÉRIMENTER FORMALISER ANALYSER PHASE D’EXPLORATION / APPRENTISSAGE ANALYSER 1
  19. Performance d’un composant : son automatisation RÉCOLTER LES MÉTRIQUES LANCER

    LES SCÉNARIOS DE PERF ALERTER PHASE D’AUTOMATISATION / INDUSTRIALISATION HISTORISER 2 Cette automatisation ne doit pas intervenir trop tôt : il faut connaître suffisamment le système pour pouvoir poser des assertions et mettre en place un mécanisme d’alerte efficace L’objectif est de lancer les scénarios régulièrement et sur une volumétrie représentative pour : • Garantir la tenue des performances dans le temps • Détecter au plus vite des régressions suite à des développements • Confirmer les gains d’une campagne d’optimisation
  20. Performance d’un composant : son optimisation RÉCOLTER LES MÉTRIQUES LANCER

    LE SCÉNARIO A OPTIMISER PHASE D’OPTIMISATION TESTER UNE PISTE A LA FOIS 3 • Un cycle d’optimisation est constitué de plusieurs itérations • Chaque itération doit permettre de confirmer ou infirmer UNE seule piste d’optimisation • Besoin d’avoir une volumétrie ni trop petite ni trop grande pour avoir des temps de réponse représentatifs et une boucle de feedback acceptable (de 3 à 4 minutes) • La difficulté consiste à identifier et trouver des pistes d’optimisation : nécessité d’un outil permettant de faire du profiling
  21. Performance d’un composant : le profiling à l’aide Scénario à

    optimiser : • La chaîne d’intégration de fichiers de mouvements financiers • Volumétrie de 1 million de mouvements financiers • Composant (integration.jar) qui tourne dans un container docker • Contexte multi-thread • Sous-utilisation des capacités CPU • Identifier les points de contentions / blocages Adoption de YourKit : • Intégration facile au composant (process java : springboot / flink) • Profiling possible sur des containers docker à distance • Profiling des threads • Capture et suivi d'événements (IO, socket, écriture cassandra..) • Ecriture possible de sondes personnalisées • Prise de snapshots pour historiser le profiling de campagnes de tirs 2 outils de profiling
  22. Performance d’un composant : le profiling à l’aide Exemples de

    pistes d’amélioration : • Passer les sauvegardes Cassandra en mode asynchrone • Supprimer l’utilisation de spring-data-cassandra pour utiliser directement le driver cassandra • Mise en place d’un cache applicatif sur la récupération des données de référentiel • Révision du mécanisme de parsing avec FlatPack • Révision de la génération des identifiants en contexte multi-threading 1h53 3h 10h 17h Optimisation de Cassandra en écriture Optimisation sur les requêtes en lecture Optimisation applicative Intégration de 150 millions de mouvements financiers
  23. Le passage d’un composant vers la scalabilité Besoins • S’adapter

    au rythme des demandes et en particulier aux montées en charge • Maintenir les fonctionnalités et les performances de traitement Comment ? • Utilisation de la plateforme Kubernetes pour gérer le passage à l’échelle • Fonctionne avec la technologie de conteneurisation Docker • Manipulation et configuration de ressources Kubernetes 1 pod = 1 conteneur docker = 1 composant
  24. Le passage d’un composant vers la scalabilité Définition d’un nombre

    fixe d’instances • Définition du nombre de réplicas dans la configuration du ReplicaSet • Les ReplicaSets s’assurent du respect du taux de réplication en re-créant ou supprimant des pods replicas : 3 Définition d’une fourchette min/max d’instances • Définition de l’auto-scaling dans la configuration du ReplicaSet : HorizontalPodAutoScaler minReplicas: 3 maxReplicas: 10 A la demande • Utilisation de l’API Kubernetes pour manipuler les ressources nécessaires (création / suppression) • Dépendance / Couplage à la plateforme Kubernetes dans les développements Prédictibilité des sollicitations du composant
  25. Robustesse d’un composant Partir du principe qu’un composant peut tomber

    à n’importe quel moment ORCHESTRATEUR COMPOSANT COMPOSANT Requête (Demande : 1234) Pas d’acquittement de la demande (1234) au bout d’un certain temps (timeout) Envoi de la demande : rejeu avec un nouvel identifiant (1235) Requête (Demande : 1235) Réponse (Demande : 1235) Détecter la perte et redémarrer une nouvelle instance du composant (prise en charge directement par la plateforme Kubernetes) Relancer les traitements métiers arrêtés en plein milieu (développement d’un mécanisme de rejeu) 2 1 1 2
  26. Les pipelines comme colonne vertébrale ROBUSTESSE PERFORMANCE SCALABILITÉ INTÉGRATION COMPOSANT

    X COMPOSANT Y EXPORT Cluster Cassandra ORCHESTRATION Oracle Mouvements Financiers Fichiers produits Pipeline : Intégration des mouvements financiers • Validation unitaire par composant des aspects de performance, scalabilité et robustesse • Permet d’accélérer le travail au niveau pipeline avec le chaînage de plusieurs composants
  27. Les pipelines : notre contrat avec le métier ROBUSTESSE PERFORMANCE

    SCALABILITÉ ❏ Test end-to-end au vert ❏ Template d’analyse de perf • Description du contexte et des configurations infra (Kubernetes, Flink, Cassandra) • Temps de réponse par volumétrie des tirs de performance • Recommandation sur l’infrastructure cible ❏ Test end-to-end au vert ❏ Template d’analyse de scalabilité • Description du contexte et des configurations infra • Démarche de montée en charge • Linéarité des temps de réponse • Recommandation sur le choix du mode de passage à l’échelle ❏ Test end-to-end au vert ❏ Destruction aléatoire des composants du pipeline ❏ Template d’analyse de robustesse • Description du contexte et des configurations infra • Liste des pods détruits par les règles Chaos
  28. Performance, scalabilité, robustesse : les points d’attention • Adresser toujours

    ces problématiques autour de cas d’utilisation métier : n’en faîtes pas des sujets technico-technique • Sagesse et patience : commencer petit et unitaire avant d’envisager l’automatisation et la volumétrie la plus grosse • Un seul combat à la fois : performance puis scalabilité puis robustesse • Des bonnes guidelines de design et d’architecture : rôle et responsabilité des composants, principes d’orchestration, standards de communication, stockage en mode append-only... • Et des bonnes pratiques de développement : clean archi, utilisation des streams, idempotence des uses-cases pour le rejeu, mode stateless, twelve-factor app…