dimanche 6 novembre 2016

Cluster de serveurs d'application Java EE

Un cluster, oui mais pourquoi ?

Un cluster est un ensemble de serveur d'application qui vont travailler ensemble. En général une instance particulière est appelé Master et les autres slaves, ils sont tous des noeuds (nodes) du cluster.
Plusieurs raisons peuvent justifier de mettre en place un cluster :
  • Avoir de la haute disponibilité (HA) :
    • Permettre de déployer sans interruption ni perte de session des utilisateurs.
    • Permettre d'effectuer des opérations de maintenance sur les nœuds (les uns après les autres) sans interruption
  • Gérer la charge :
    • En multipliant les nœuds sur des machines différentes il est possible d'avoir une puissance démultiplié 
    • On peut ajouter des nœuds dynamiquement pour occasionnellement gérer des montés en charge et les retirer ensuite.

Cluster EJB vs HTTP

Les EJB se clusterisent parfaitement sur les serveurs d'application, en fait c'est le proxy porté par les clients qui répartissent leurs appels sur les nœuds de façon transparente.
Les sessions sont répliquées et une affinité de session se met en place (sur des EJB Statefull).


De base pour HTTP le serveur d'application (ex : jboss) ne sont pas capables de répartir les requêtes HTTP, il faut donc mettre en place un Loadbalancer logiciel (Apache, Nginx...) ou physique (F5...). Ce dernier remplace le proxy de l'EJB client mais introduit aussi un SPOF (single point of failure), une solution est de jouer avec les DNS pour mettre en place plusieurs loadbalancers sur différents IP répondant au même nom de domaine.

Cluster et performances

A puissance égale une machine unique sera toujours plus performante qu'un cluster (la machine unique possède la puissance de l'ensemble des machines du cluster). La performance n'est pas l'objectif principal d'un cluster mais la haute disponibilité. Mais à partir d'un certain seuil le coût d'une machine très puissante dépasse largement la somme de machines plus standard fournissant une puissance équivalente.

Le cluster va entraîner une consommation supplémentaire (flèches bleus en pointillés) :
  • En bande passante pour synchroniser les sessions des nœuds, pour informer l'états des nœuds.
  • En mémoire et CPU chaque nœud devrait avoir l'ensemble des sessions et doit réaliser les mises à jour des actions réalisées sur d'autres nœuds. 
Clairement c'est la gestion des sessions qui va pénaliser le cluster. La solution est simple faire des services stateless, voir des applications web stateless (la session est gérée côté client en javascript, comme le bon vieux client lourd) : éliminer la session. C'est évidement la tendance de ces dernières années avec des service REST stateless, et des frameworks javascript puissants ou des applications mobile.

Mais cela ne résout pas tout...

Cluster et accès à la base de données

On parle d'un cluster de serveur d'application Java EE, souvent il y a une base de données pour y stocker les informations. 
En Java EE on utilise généralement JPA. De base mettre en cluster ne va pas provoquer de problème à moins que le cache de niveau 2 soit activé. Or si vous avez besoin de performance la base de données peu rapidement devenir le point de contention du système et le cache est une solution efficace voir indispensable et JPA propose le cache de niveau 2 pour cela.

Avec ce cache on retrouve sensiblement le même problème que les sessions, il faut impérativement que le cache soit synchronisé sur tous les nœuds sinon le comportement de l'application sera imprévisible et fallacieux. Heureusement le cas est prévu par la plupart des outils de cache (EHCache, Memcached, Infinispan, Coherence...), mais si vous faites cela à la petite semaine avec vos petits doigts il est fort à parier que votre cache maison ne va pas aimer être clusterisé. 
Principalement 2 topologies de cache sont utilisés et une 3ème qui est un peu luxueuse :
  • Répliqué et synchronisé sur tout les nœuds, ainsi chaque nœud du cluster a en local un cache complet et à jour.
  • Distribué sur les nœuds du cluster, chaque nœud à une partie du cache, cela permet d'avoir une capacité disponible plus importante pour la taille du cache.
  • Un mixe des 2 : une distribution du cache avec un facteur de réplication.
Suivant les besoins de votre application l'une ou l'autre des ces topologies sera plus pertinente. 

Caractéristique du cache répliqué : 
  • cache rapide avec un temps de réponse constant quelque soit le nœud.
  • une mise à jour du cache coûteuse et un coût qui augmente avec la taille du cluster.
  • La perte d'un nœud n'a pas d'impact sur le contenu du cache.
Caractéristique du cache distribué :

  • Le cache est potentiellement moins rapide car il peut nécessiter un appel réseau pour aller chercher la valeur sur un autre nœud.
  • Le coût de mise à jour du cache ne dépend pas de la taille du cluster.
  • Lors de la perte d'un nœud une partie du cache est perdu il faudra la reconstituer en sollicitant la base de données, il y aura une charge supplémentaire sur la base de données et une dégradation des performances de l'application.

Ce dernier point n'est pas rédhibitoire, sans cache l'application est sensée répondre dans des temps corrects sur un appel unitaire, si ce n'est pas le cas, on n'est face à un cache "cache misère"... 

La 3ème est en fait une base Nosql, c'est la cas de Coherence d'Oracle par exemple, 
prévoir quelques euros pour la licence et un sous réseau dédié à votre cluster (oui ça broadcast en UDP). Et ça marche bien, il faut juste se demander si on a encore besoin de la base de données pour les données qui vont aller dans ce cache...

mercredi 26 octobre 2016

Mise en oeuvre : Master Data Management (MDM)

Qu'est que le MDM ?

Wikipedia pourra vous renseigner...
En résumé l'objectif du MDM, si dans un système d'information une entité (unité de sens, par exemple le client) est stockée dans plusieurs logiciels ou bases de données dont les informations arrivent dans chaque système avec des processus différents. Le MDM va être le lieu ou toutes ces informations vont être consolidées, identifiés et dont on va extraire un enregistrement de référence (en utilisant des règles), souvent appelé Golden Record, qui sera alors redistribué à tous les systèmes pour unifier la notion (le client) dans l'organisation.

Principe

Ici 3 sources de données sont poussées dans le MDM, pour chaque enregistrement il y a une mise en qualité (quatity gate) qui peut s'appuyer sur des règles, des données de références, une base de connaissances.
Puis l'enregistrement est intégré et rapproché par des règles à un cluster qui contient tous les enregistrements d'une même instance d'entité (ex : le client André Dupont).
A partir de tous les enregistrements du cluster d'une instance, un golden record est réalisé en faisant du picking par des règles sur les champs des enregistrements du cluster.
En théorie un cluster doit être composé d'un enregistrement par source, ou moins.
Si dans un cluster, 2 enregistrements de la même source se retrouvent regroupés alors il a un problème, cela demande une remédiation. Il est possible qu'un doublon soit présent dans une des bases, et cela peut nécessiter une intervention métier pour dédoublonner (ex: que faire des points de fidélité dans le CRM qui sont sur deux comptes alors que c'est la même personne ?), et cela montre qu'il a peut-être une amélioration a réalisé au niveau des processus de ce système.
C'est à ce niveau qu'intervient le workflow de remédiation et le rôle du Data Steaward, il est alerté d'un doublon et a pour objectif d'analyser l'origine du problème :

  • règles de rapprochement à améliorer (les champs utilisés ne sont pas tous pertinants)
  • mise en qualité trop intrusive (modification d'un prénom en utilisant la base de connaissance)
  • problème de  la base d'origine (doublon réel)
  • ...
En suite il doit prendre des actions :
  • Correction manuel du cluster et association avec un autre cluster ou création d'un cluster dédié
  • Ne rien faire cela n'a pas d'impact métier
  • Remonter le problème au responsable de l'application d'origine pour réaliser une intervention métier
  • Modifier les règles de rapprochement
L'approche MDM est l'amélioration continue, on ne sait pas encore quelle donnée posera un problème mais le système est prêt à être amélioré, affiné lorsqu'un nouveau cas est rencontré.

Performance et volumétrie

Regroupant l'ensemble des données de l'organisation pour une unité de sens, stockant l'historique pour permettre l'analyse et retracer le comportement d'un cluster, le MDM va nécessiter une volumétrie beaucoup plus importante que les bases des systèmes métier l'alimentant.

Jouant pour chaque nouvelle enregistrement un ensemble de règles pour le rapprochement à un cluster puis réalisant un nouveau Golden record pour ce cluster (ce dernier est aussi stocké), l'ajout dans le MDM d'un enregistrement est coûteuse. Il est peu probable pour que cela puisse être réalisé en temps réel ou de façon synchrone. En consultation on peut avoir une performance correct mais l'utilisation de cache semble indispensable. 

La rechercher dans le MDM peut-être coûteuse si on souhaite respecter la même logique que celle utilisé pour le rapprochement (mise en qualité et règle de rapprochement). 


Mise en oeuvre

Une fois les unités de sens identifiés, elles représenteront les entités du modèle MDM. Chaque entité doit être sémantiquement indépendante les unes des autres, le modèle MDM n'est pas un modèle relationnel : une table du MDM contient l'intégralité de son sens, le sens d'une entité n'est pas le produits de plusieurs tables, il peut y avoir des relations entre les entités.

Exemple :
Nous souhaitons intégrer à un MDM une entité client, quid de l'adresse. Deux modélisations sont possibles :
  1. Le client doit avoir une adresse cela faire partie de son unité de sens et permet de le déterminer : une entité client
  2. L'adresse et le client sont indépendants mais il y a une relation possible entre les deux : une entité client et une entité adresse
Dans le cas 1 les champs de l'adresse (rue, code postal...) sont ajoutés au client, et permettent de différentier les clients aussi bien que le nom et le n° de téléphone. Le déménagement d'un client risque d'avoir pour conséquence la création d'un nouveau client si cela n'est pas spécifiquement géré côté métier.
Dans le cas 2 les champs de l'adresse ne peuvent être un discriminant pour distinguer les clients et l'entité Adresse contiendra un ensemble d'adresse dont l'objectif sera de fournir des adresses le plus juste possible indépendamment des clients. Le volume de données est aussi moins important.


Les 2 approches sont valides, tout dépendant des volumes et des objectifs du MDM. Si vous êtes un opérateur majeur de la grande consommation et que votre base client est très volumineuse et représente une part importante de la population alors le modèle 2 est plus adéquate car l'entité adresse aura une valeur ajoutée, vous arriverez à discriminer les adresses valides et invalide : un nom de rue rencontrée qu'un fois est suspect, vous aurez rapidement exhaustivité des nom de rue. Sur un ensemble plus restreint, comme sur une base client B2B, le modèle 1 sera plus pertinent.

  

jeudi 26 mai 2016

Java vs .Net C#

C'est un débat sans fin mais comme je développe sur les deux environnements je me dois d'y participer un peu, d'apporter mon caillou au tas de gravats.

Je vais balayer d'un revers de main l'aspect performance : c'est pareil ou presque. Bon quand même on va dire que les Winform sous Windows ont un rendu certainement plus rapide et réactif que du Java swing ou autre. Pour le reste cela dépend beaucoup du développeur et on peut voir une programmation d'un algo en Java battre le même en C à cause de la mise en oeuvre : un mauvais développeur C/C++ fera pire qu'une mauvais développeur Java/C#.
Et on peut jouer avec cela : http://benchmarksgame.alioth.debian.org/
Donc grosso c'est pareil.

Attaquons d'un point de vue langage et syntaxe. Ce sont des syntaxes très proches, C# est fortement inspirées de Java et C et Java est elle-même inspirée de C. Mais plus en détail question langage, le C# est clairement meilleur, plus flexible et plus juste. Son secret, le C# n'est pas rétrocompatible ce qui lui a permis de briser certaines barrières et d'évoluer plus vite.
Ainsi les generics sont vraiment gérés au runtime ce qui n'est pas le cas de Java et dès qu'on s'attaque à faire de la réflexion on réalise que cela a de l'importance.
En suite le gros apport de C# c'est linq qui permet de réaliser des requêtes dans les structures de données les plus divers (SQL, XML, objets...).
Le foreach multi threads et quelques raccourcis pour faire un code utilisant plusieurs threads mais je crois que maintenant il y a un équivalent en Java.
De plus il y a une certaine flexibilité dans la gestion des fichiers de code source : une classe peut-être implémentée dans plusieurs fichiers, pratique pour le code généré, et la structure namespace-classe ne doit pas comme en Java être identique à celle répertoire-fichier (mais cela n'a pas que du bon). 
Enfin à chaque nouvelles versions ils progressent et l'écart se réduit ou change de géométrie.

Ensuite l'environnement de développement, Visual Studio contre Eclipse, Intelij, Netbean... bon aujourd'hui ils sont tous très aboutis, mais le développement d'une application reste complexe, et il fini par y avoir pléthores de menus et sous menu et modules... bref c'est ainsi. Visual Studio intègre nativement plus de chose ce qu'il fait qu'il est plus simple d'approche. Il faut aussi noté qu'il y a dans l'ASP.NET et autre finalement pas mal de code généré par Visual Studio qui est masqué à l'utilisateur. Après pour avoir la couverture de code par les test dans Visual Studio faut s'attaquer à une licence qui vaut quelques milliers d'€...

En en arrive a la réalisation d'un projet Web par exemple, c'est quand même mieux intégré dans Visual Studio, on est tenu par la main. En Java il faut déjà faire beaucoup de choix, Java EE, Spring, JPA, JSF, JSP, GWT... tout ça décliné en version, cela demande un certain savoir faire sans compter que cela change régulièrement aujourd'hui on partirait plus sur Java EE REST, JPA + Angular (ce qui simplifie la donne ou déplace le problème vers le développement javascript). En ASP.NET y a moyen de chercher du Nhibernate, Castle, EntLib, Unity et autres mais étrangement c'est assez peu couru de méditer sur la stack ASP.NET.

Ce que fait la grande différence lors de la réalisation c'est la gestion des librairies tiers, d'un côté Maven (ou Gradle) pour Java et Nuget pour .net. Mais il faut dire que Maven a des années d'avance et une pratique assez généralisée aussi bien dans les projets tiers qu'au sein même de l'entreprise. Nuget commence a entrer dans les mœurs.

Un autre aspect qui fait la différence est l'écosystème, en Java il y a de grandes organisations qui gèrent de l'opensource (Apache, Redhat, Spring...) de gros éditeurs (Oracle, IBM...). Du coup c'est très riche on peut vite s'y perdre, mais il y a aussi Java EE pour normaliser et cadrer un peu tout cela. A contrario le monde .Net est plus fermé, il a quelques éditeurs spécialisés dans les composant d'interfaces et autres outils : Telerik, ComponentArt, ComponentOne. Les projets opensource en c# dans http://www.codeproject.com/ et http://codeplex.com ont rarement un gouvernance clair, les bonnes idées finissent absorbées par Microsoft sous une forme ou une autre, alors souvent le plus simple est de ne surtout rien faire et attendre la prochaine version du framework. Et inversement Microsoft y déverse les éléments qu'il ne souhaite plus maintenir (ex : Entlib, Unity).

Finalement la grande différence c'est le développeur. Le développeur .Net et le développeur Java sont très différents dans leurs approches et leurs travers. Mais cela mérite son propre post.