feat: add perf test

This commit is contained in:
Freezlex 2024-07-28 23:58:25 +02:00
parent d10712e1af
commit 873b1acc1d
4 changed files with 37 additions and 8 deletions

View File

@ -68,7 +68,7 @@ Le schéma @three-tier-archi-diagram ci-dessous représente les trois tiers de l
=== Présentation de PostgreSQL
PostgreSQL est un système de gestion de base de données relationnelle (SGBDR#display-def("SGBDR")). Le projet est initié en 1986 par Michael Stonebraker et Andrew Yu à l'Université de Californie à Berkley.
PostgreSQL est un système de gestion de base de données relationnelle (#ref-glossary(term: "SGBDR")[SGBDR]). Le projet est initié en 1986 par Michael Stonebraker et Andrew Yu à l'Université de Californie à Berkley.
L'une des force majeur de ce système est d'être OpenSource, ce qui signifie qu'il est développé et maintenu par la communauté en plus des développements apportés par la société mère PostgreSQL.

View File

@ -10,20 +10,26 @@ Je présente dans cette section le travail réalisé durant les neuf mois au sei
== Pertinence et philosophie
Lorsque le sujet de mettre à jour le SGBDR a été présenté, il n'a pas été décidé de remplacer PostgreSQL. Comme expliqué précédemment, PostgreSQL excelle dans la gestion de données géographiques et attributaires, il est complet et surtout très bien maintenu par ses développeurs. Ces différentes raisons en font un candidat parfait pour l'environnement InfSuite plus que tout autre système proposé par la concurrence.\
Maintenir PostgreSQL en tant SGBDR de l'application écarte déjà un bon nombre de solutions niveau logiciel. Je peux dores et déjà abandonner les logiciels payants et long d'expertises autres que PgAdmin pour effectuer cette migration qui reste le logiciel le plus adéquat puisque nous ne cherchons pas à changer d'environnement.
Maintenir PostgreSQL en tant SGBDR de l'application écarte déjà un bon nombre de solutions niveau logiciel. Je peux dores et déjà écarter les logiciels payants et long d'expertises autres que PgAdmin pour effectuer cette migration qui reste le logiciel le plus adéquat puisque nous ne cherchons pas à changer d'environnement.
L'application InfSuite souhaite utiliser une fonctionnalité important de PostgreSQL: Les timestamps, ou horodatages en français.
En effet, InfSuite utilise un système de version basé sur de l'horodatage. Quand un utilisateur met à jour les informations d'un document dans l'application (inspection, restauration,...) alors, il créait une nouvelle version du document.\
L'application InfSuite souhaite utiliser une fonctionnalité important de PostgreSQL: Les ``` timestamps```, ou horodatages en français.
En effet, InfSuite utilise un système de version basé sur de l'horodatage. Quand un utilisateur met à jour les informations d'un document dans l'application (inspection, restauration, etc.) alors, il créait une nouvelle version du document.\
Si deux utilisateurs récupèrent la même version d'un document, qu'ils effectuent tous deux des mises à jour sur ce document, que l'utilisateur A sauvegarde ses changements en premier, que l'utilisateur B essaye de sauvegarder le document avec ses changements après que la version ait changé, alors le serveur lui signalera qu'il ne possède pas la dernière version du document qui a été modifiée entre temps et donc qu'il ne peut pas sauvegarder ses modifications sans mettre à jour la version de son document.\
Pour assurer ce suivi de version le document contient une version en base, qui est un ``` timestamp``` sans fuseau horaire. Un problème peut alors apparaître si deux utilisateurs, sur des fuseaux horaires différents, effectuent des modifications au même instant.\
Le serveur ne pourra pas vérifier l'information de fuseau horaire puisqu'elle n'est pas sauvegardée en base et donc si l'utilisateur effectue une sauvegarde même avec une ancienne version du document, cette dernière écrasera les derniers changements.
Dans le schéma @file-versionning-schema, deux utilisateurs génèrent des versions de fichiers différentes. Un utilisateur enregistre ses changements en premier et génère la version ``` AB``` du document. Quand le second utilisateur souhaite enregistrer ses changements ``` C```, un conflit de fichier l'en empêche. ``` C``` a comme origine la version ``` A``` et non pas ``` AB```, l'utilisateur doit donc récupérer les changements de la version ``` AB``` avant d'enregistrer ses changements.
#figure(
image("../assets/images/file-versionning.png"),
caption: [Schéma d'un conflit de version entre deux version d'un document]
)<file-versionning-schema>
De plus, un point important pour lequel le souhait de mettre à jour la base de données a été exprimé, est de pouvoir profiter des améliorations du #ref-glossary(term: "SGBDR")[SGBDR] PostgreSQL. Il y a par exemple des mises à jour de sécurité du système. Mettre à jour une application et ses différents composants permet de profiter des mises à jour de sécurité afin d'éviter des vulnérabilités qui pourraient mettre en péril les données des clients et l'intégrité de l'entreprise.\
Les vulnérabilités sont connues sous le nom de Common Vulnerabilities and Exposures et en prenant pour exemple la mise à jour pour corriger la faille ``` CVE-2023-5869```, PostgreSQL résout un problème permettant d'écrire des octets arbitraires en mémoire, qui facilitait l'exécution de code arbitraire. Normalement, les ORM permettent de faire automatiquement de la paramétrisation de requêtes pour prévenir d'injections potentielles. Mais il se peut que des failles supplémentaires se cachent dans le code et permettent donc, malgré tout, d'exploiter ces failles. Les corriger sur le système permet alors d'éliminer en grande partie le risque d'attaque.\
En complément des vulnérabilités, les mises à jour apportent des améliorations de performances cruciales. En théorie les ORM jouent un rôle essentiel dans les performances d'une application, car ils utilisent un cache pour éviter d'effectuer des requêtes vers la base de donnée à trop haute fréquence.\
Dans le cas de la base PostgreSQL, elle est aussi utilisée pour le système d'information GIS, il y a donc beaucoup de données à délivrer et avec un grand nombre de requêtes. Améliorer les performances permet de réduire la latence ressentie par l'utilisateur lorsqu'il cherche à charger des données dans l'application. Sur la version 16 de PostgreSQL, il est promis une amélioration de 10% des performances du #ref-glossary(term: "SGBDR")[SGBDR]. Un tel gain de performance premer d'améliorer grandement l'experience utilisateur.
Il faut maintenant déterminer quel est le type de migration le plus adéquat dans ce cas de figure pour éviter les coûts supplémentaires qui peuvent être facilement évités.\
Je dois dans un premier temps chercher les technologies utilisées dans l'application et m'assurer que ces dernières soient compatibles avec la nouvelle base. Par la suite, je vais devoir valider la compatibilité entre la version de la base source et de la base cible. Avec cette confirmation, je pourrais alors chercher la meilleure manière d'effectuer cette migration parmi les différentes options disponibles que j'ai pu exposer précédemment.
@ -32,8 +38,8 @@ Je dois dans un premier temps chercher les technologies utilisées dans l'applic
En regardant côté architecture, je cherche quelles sont les applications qui risquent de rencontrer un problème lors de la migration. Les seuls systèmes qui établissent une relation directe avec la base de données sont côté #ref-glossary(term: "Back-End")[back-end]. On limite donc l'impact sur l'application globale s'il y a des changements et des mises à jour à réaliser pour permettre à l'application de continuer à fonctionner avec la base de données.
Le projet #ref-glossary(term: "Back-End")[back-end] de l'application est développé en C\# avec .NET qui gère la partie web de l'application. Un certain nombre de librairies sont utilisées par le projet InfSuite pour permettre d'étendre les fonctionnalités de l'application sans devoir dépenser de temps de développement.
Il existe des packages alimentés par Microsoft par exemple comme .NET, #ref-glossary(term: "EF")[#display-def("EF")], ... et d'autres librairies qui sont elles développés par des développeurs tiers qui ont souhaité ajouter une nouvelle fonctionnalité à l'écosystème.\
Quand on souhaite effectuer une mise à jour de l'application, l'environnement Microsoft nous propose d'effectuer la mise à jour de ces librairies nommées Nugget Packages dans l'écosystème C\# via NuGet, le gestionnaire de dépôts associé.
Il existe des paquets alimentés par Microsoft par exemple comme .NET, #ref-glossary(term: "EF")[#display-def("EF")], ... et d'autres librairies qui sont elles développés par des développeurs tiers qui ont souhaité ajouter une nouvelle fonctionnalité à l'écosystème.\
Quand on souhaite effectuer une mise à jour de l'application, l'environnement Microsoft nous propose d'effectuer la mise à jour de ces librairies nommées NuGet Packages dans l'écosystème C\# via NuGet, le gestionnaire de dépôts associé.
Il permet de faire du versionnement des librairies, sur le même principe que PostgreSQL qui utilise le concept de versionnement pour livrer ses mises-à-jour.\
Chaque version d'une librairie peut notifier des incompatibilités avec certaines versions d'autres librairies. Je dois donc étudier les composants qui permettent de faire la liaison à la base de données et également les librairies dont peut ou qui peuvent dépendre de ces composants.\
Il faut prêter attention à chaque composant mis à jour indépendamment qui pourrait causer d'autres problèmes de compatibilité avec l'application et casser des fonctionnalités.\
@ -48,7 +54,7 @@ Dans mon cas, la solution #ref-glossary(term: "Back-End")[back-end] d'InfSuite e
caption: [Arbre de dépendances du projet WebApi d'InfSuite]
)<ik-webapi-dependencies>
Si je souhaite par exemple mettre à jour un package dans le projet "Geometry", tous les projets dépendants sont impactés par cette mise à jour, il faut donc s'assurer que rien ne vient casser le bon fonctionnement de l'application en profondeur.
Si je souhaite par exemple mettre à jour un package dans le projet "Geometry", tous les projets dépendants sont impactés par cette mise à jour, il faut donc s'assurer que rien ne vient casser le bon fonctionnement de l'application en profondeur. Je m'intéresse donc aux liens entre les différents projets ainsi qu'aux librairies que je souhaite mettre à jour pour m'assurer de leur compatibilité pour toute l'application.
=== Compatibilité
@ -57,10 +63,33 @@ Ce qui m'intéresse particulièrement ici, est de mettre à jour le package Npgs
La version post mise à jour de Npgsql était la version ``` 4.1.13``` et la dernière version disponible qui utilise les horodatages avec fuseau horaire est la version ``` 8.0.3```. En essayant de le mettre à jour avec cette version, je me suis rendu compte qu'#ref-glossary(term: "EF")[EF] n'était pas compatible avec la version ``` 8.0.3```. La dernière version du paquet Npgsql disponible pour #ref-glossary(term: "EF")[EF] étant la version ``` 6.4.3``` je dois donc me contenter de cette version.\
Avant de valider l'utilisation de ce dernier dans toute l'application, je dois valider qu'elle supporte les horodatages avec fuseau horaire et qu'elle est également compatible avec le reste de l'application. En se référant à la documentation fournie, la première version à intégrer les horodatages avec fuseau horaire est bien la version ``` 6.X.X``` d'Npgsql, elle est donc compatible avec le besoin de sauvegarder les fuseaux horaires pour les versions.
Si on souhaite passer sur la nouvelle version du paquet Npgsql, la version ``` 8.X.X```, il n'y a pas d'autre choix que de passer d'EF à EFCore. Faire le choix de mettre à jour l'application EFCore permettrait de compléter l'objectif de maintenir l'application à jour et saine. En effet, pour rappel, EF n'est maintenant plus mis à jour régulièrement. L'étude d'impact des couts et des changements impliqués par une telle mise à jour a déjà été réalisé à priori de mon analyse et il en est ressorti que pour l'année courrante, un tel budget ne pouvait pas être accordé pour cette mise à jour. Si je veux mettre à jour l'application pour utiliser les dernières fonctionnalités disponibles sans passer par une mise à jour d'EF, le seul choix qu'il reste est de mettre à jour Npgsql vers la version ``` 6.X.X```. Le schéma @npgsql-versions-incompatibilty ci-dessous résume la situation d'incompatibilités entre les versions des trois éléments à savoir respectivement : à gauche Entity Framework, au centre le paquet Npgsql et à droite la base de données PostgreSQL.
#figure(
image("../assets/images/npgsql-versions-incompatibilty.png"),
caption: [Problématique d'incompatibilité entre les différents éléments permettant au serveur et à la BDD d'échanger des informations.]
)<npgsql-versions-incompatibilty>
=== Tests de performance
La dernière étape permettant de valider cette étape de migration est de s'assurer que la nouvelle version de PostgreSQL installée à de meilleures performances que la version remplacée. Pour valider cela, il a été développé un système en interne de test de performance. L'architecture complexe de la base et la relation avec des données géographiques et attributaires peut rendre les requêtes parfois plus longues d'exécution.
Pour effectuer un test de performance, le système utilise une fonctionnalité gourmande en ressource, les groupes. Dans l'environnement InfSuite, il est possible d'afficher sur la carte les objets d'infrastructure. Par défaut tous les objets d'un dataowner sont affichés. Pour permettre d'axer son travail sur des objets d'infrastructures particuliers, alors il est possible d'appliquer un filtre à toutes ces entités. Le mode "Groupe" de l'application permet de créer alors deux types différents de filtres.
Le premier type de filtres est un filtre statique. Peu gourmand en ressource et très simple d'utilisation, on peut y ajouter des entités manuellement et cela va permettre de n'afficher que les objets sélectionnés dans l'application. Fonctionnellement parlant ce n'est qu'une relation de base de données.
Le second type de filtre, plus complexe, est le filtre dynamique. Les filtres dynamiques permettent de gérer automatiquement les entités qui seront incluses ou exclues de l'affichage. Pour ce type de filtre, il est possible créer des règles de filtrage avancées pour permettre à l'utilisateur plus de flexibilité.\ Un peu à la manière d'une requête SQL, peut construire une requête qui va être exécutée pour permettre de retrouver les entités à partir de ces critères. Il peut par exemple demander de filtre les ouvrages par position géographique en ne prenant en compte que ceux au-dessus d'une certaine latitude et uniquement les ouvrages qui contiennent un certain numéro dans leur nom.\
Il est possible de créer des règles avec chaque propriété d'un objet d'infrastructure, d'appliquer un ordre pour les conditions, de faire des agrégats…. Les utilisateurs ont la liberté de créer leur propre requête, une requête pouvant devenir rapidement complexe, elle peut prendre plus de temps à filtrer les objets d'infrastructures pour les retourner à l'utilisateur.
Ce que l'outil permet de tester est ce système de groupe/filtres. Il va chercher les différents filtres existants en base de données, peu importe le client qui a pu les créer, et les exécuter.\
Cette méthode permet de connaître les performances réelles de la base dans un cas pratique et non pas d'avoir des performances théoriques fournies par les développeurs du #ref-glossary(term: "SGBDR")[SGBDR] qui peuvent être tournées en leur faveur. Nous cherchons donc à savoir si le chiffre de 10% de performances en plus donné par les développeurs est véridique.
#pagebreak(weak: true)
== Adaptation du code
Dans l'application, 24 projets au total utilisent le paquet Npgsql. Ces projets ne sont pas uniquement dédiés à la partie #ref-glossary(term: "Back-End")[back-end] de l'application, mais sont également des outils tiers développés pour des besoins spécifiques. Je peux par exemple citer l'outil IkCoordToRvg que j'ai pu aborder dans mon mémoire de licence, qui était le projet sur lequel j'ai pu développer durant ma troisième année de licence. Comme pour tout autre projet, il utilise des dépendances au projet Core d'InfSuite qui nécessite lui-même le paquet Npgsql. Lorsque j'ai tenté une première fois de mettre à jour le paque, jee me suis retrouvé confronté à de nombreuses erreurs
#pagebreak(weak: true)
== Résultats
=== Performances finales

BIN
main.pdf

Binary file not shown.

View File

@ -116,7 +116,7 @@
margin: (left: 30mm, right: 30mm, top: 30mm, bottom: 30mm)
)
set text(font: "Times New Roman", size: 12pt)
set par(justify: true)
set par(justify: true, leading: 0.8em)
init-acronyms(acronyms)
counter(page).update(1)