Full Stack

Article

Hazelcast : présentation et retours d’expériences

Je vous propose une présentation par l’exemple ainsi qu’un retour d’expérience de la solution Hazelcast.

Hazelcast, C’est quoi ?

Hazelcast (ou Hazelcast IMDG depuis quelques temps) est une solution “NoSQL” de table de données (Datagrid) en mémoire distribuée, open source, écrite en Java (disponible ici).
Elle est également disponible en offre Enterprise (disponible là).

Utilisations possibles

Une petite liste des utilisations possibles de Hazelcast dans vos projets (récents ou anciens) :

  • Mise en place d’un cache facilement configurable (distribuée ou non)
  • Stockage d’information dans un Data Grid facilement configurable
  • Une gestion asynchrone de votre persistance facilement configurable
  • Messagerie entre différentes applications sur une même infrastructure facilement configurable avec la création d’un _cluster_ (ou ensemble de noeuds)

Comme vous l’avez sans doute remarqué, le terme facilement configurable revient souvent dans les cas d’utilisation cités, c’est une des forces de Hazelcast.

Par l’exemple

Quelques exigences

Disons que, pour des raisons qui ne regardent que moi, je désire avoir un cache sur mon application me permettant de gérer des notifications pour un utilisateur (humain ou machine) :

  • Un humain ou une machine me contacte par appel REST pour savoir si il y a de nouvelles notifications
  • Ces notifications proviennent de plusieurs applications du même S.I.
  • Les notifications lui sont dédiées par un identifiant utilisateur unique
  • Chaque notification a un identifiant interne unique
  • Une fois la notification transmise, elle ne me sert plus à rien et je ne veux pas que le client l’ait de nouveau
  • Chaque notification a une durée de vie limitée, afin que si le client ne consulte pas l’API REST, on ne charge pas la mémoire pour rien

Voilà comment mettre en place tout ça avec Hazelcast.

On ajoute hazelcast aux sources

Avec Maven c’est facile :

<dependency>
    <groupId>com.hazelcast</groupId>
    <artifactId>hazelcast</artifactId>
    <version>3.10.3</version>
</dependency>

Cette dépendance rapatrie tout ce qu’il faut pour gérer l’instance et un client java (si vous voulez seulement le client c’est juste hazelcast-client).

On définit notre objet distribué et l’instance Hazelcast locale

Hazelcast permet de définir et d’utiliser simplement un objet distribué : Map, MultiMap, Set, Queue, etc…
On fait tout ça avec le bout de code suivant :

Config cfg= new Config();
HazelcastInstance instance = Hazelcast.newHazelcastInstance(cfg);
Map mapCustomers = instance.getMap("notifications");

Et voilà, on a une Map mémoire, potentiellement distribuable, qui a été créée (avec la configuration Hazelcast par défaut)

Vous avez désormais une instance Hazelcast démarrée sur le port 5701, un simple appel à

instance.getMap("notifications");

Quelque part dans le code (de la même application ou non), nous donnera accès à la Map mémoire/distribuée.

/!\ Important : il faut que vos objets soient “Serializable”. /!\

On configure…

Là, on va passer à la partie intéressante : la configuration.

Pour configurer votre/vos instance(s) Hazelcast, il faut avoir un fichier hazelcast-config.xml dans votre classpath ou ajouter des propriétés au bean hazelcast-config dans la configuration Spring.

Cette configuration vous permet de (liste non-exhaustive) :

  • Définir les propriétés de votre objet distribué : taille max, _durée de vie des objets,…
  • Définir le port du noeud hazelcast local et les autres ips/ports potentiels des autres noeuds membres de votre cluster
  • Sécuriser l’accès à votre cluster
  • Déclarer le monitoring de votre cluster(capacités très limités dans la version OpenSource)

Un petit exemple de contenu du fichier de configuration :

<hazelcast xsi:schemaLocation="http://www.hazelcast.com/schema/config hazelcast-config-2.0.xsd" xmlns="http://www.hazelcast.com/schema/config" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- Sécurisation du cluster par login/mdp-->
<group>
<name>dev</name>
<password>password</password>
</group>
<network>
<!-- Port par défaut, si déjà pris sur le cluster on incrémente-->
<port auto-increment="true">5701</port>
<join>
<tcp-ip enabled="true">
<members>10.10.1.2</members>
<!-- Ip de mon noeud, si autres noeuds on met leurs ips ici -->
</tcp-ip>
</join>
<!-- On peut déclarer de le chiffrement symétrique ou asymétrique (inactif par défaut)-->
</network>
<!-- On configure notre map mémoire distribuée ou non (si plusieurs Maps, on en déclare autant que nécessaire en changeant de nom)-->
<map name="notificationsMap">
<!-- supprime l'entrée dans la Map qu y reste plus de 240 secondes (expiration de la notification dans notre exemple) -->
<time-to-live-seconds>240</time-to-live-seconds>
</map>
</hazelcast>

Spring

Bon, tout ça c’est bien, mais dans un conteneur c’est mieux… avec la même déclaration mais avec Spring en ajoutant la dépendances hazelcast-spring (en XML car je suis un sentimental), ça donne :

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:hz="http://www.hazelcast.com/schema/spring" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.hazelcast.com/schema/spring http://www.hazelcast.com/schema/spring/hazelcast-spring-2.3.xsd">
<hz:hazelcast id="instance">
<hz:config>
<hz:group name="dev" password="password"/>
<hz:network port="5701" port-auto-increment="false">
<hz:join>
<hz:tcp-ip enabled="true">
<hz:members>10.10.1.2</hz:members> <!-- Ip de mon noeud, si autres noeuds on met leurs ips ici -->
</hz:tcp-ip>
</hz:join>
</hz:network>
<hz:map name="notificationsMap">
<hz:near-cache time-to-live-seconds="240"/>
</hz:map>
</hz:config>
</hz:hazelcast>
</beans>

Et voilà, désormais une simple déclaration :

@Autowired
private Map notifications;

Vous suffira.

Pour d’autres exemples de configuration c’est ici.

On distribue

Je peux désormais utiliser Hazecast sur une autre application de mon SI, ou une autre instance de ma première application, pour créer un cluster. Cela permet de distribuer ma Map entre chaque application, avec seulement ce qui est déclaré dans le fichier hazelcast-config.xml ou une configuration Spring pour chacune.

La gestion des clusters par Hazelcast apporte de nombreux avantages :

  • La gestion des noeuds Primary, Backup est simple
  • Si un où plusieurs noeuds ne sont plus disponibles dans le cluster les mécanismes de backup se font tous seuls
  • Un noeud de nouveau up se reconnecte tout seul au cluster
  • L’ensemble du cluster peut-être monitoré via le Management Center

Pour notre exemple, les différentes applications effectueront des put sur la Map et notre Rest Api ne fera que des get.

Retours d’expérience

J’ai utilisé Hazelcast pour mettre en place plusieurs Maps distribuées entre deux instances d’une même application en actif/actif avec une forte charge en journée (plateforme mutualisée de signature électronique).

Je l’ai trouvée simple d’utilisation et extrêmement bien configurable !

J’ai pu constater, pendant 2 années d’utilisation en production, sa forte résilience (crash d’une des instances, problèmes réseaux) : le cluster se rétablit toujours sans qu’il n’y ait d’action à faire !

La cerise sur le gâteau, c’est sa documentation très complète (et migrée depuis peu en Asciidoc).

Conclusion

Hazelcast est un outil dont la prise en main a été simplifiée autant que possible pour permettre une utilisation rapide dans un large éventail de situations. Si vous voulez l’utiliser au maximum de ses possibilités, il faudra passer à la version Enterprise (payante), sachant que la version gratuite est déjà bien utile pour de la production.

Dans tous les cas, je vous conseille de l’essayer !

PS: Vous pouvez aussi jeter un œil à son petit frère Hazelcast Jet.

Nouveau commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*

Solve : *
38 ⁄ 19 =


Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.