web-dev-qa-db-fra.com

Singleton dans un environnement de cluster

Quelle est la meilleure stratégie pour refactoriser un objet Singleton vers un environnement de cluster?

Nous utilisons Singleton pour mettre en cache certaines informations personnalisées de la base de données. Son principalement en lecture seule, mais est actualisé lorsqu'un événement particulier se produit.

Maintenant, notre application doit être déployée dans un environnement en cluster. Par définition, chaque JVM aura sa propre instance Singleton. Ainsi, le cache peut être désynchronisé entre les machines virtuelles Java lorsqu'un événement d'actualisation se produit sur un seul nœud et que son cache est actualisé.

Quelle est la meilleure façon de synchroniser le cache?

Merci.

Edit: Le cache est principalement utilisé pour fournir une liste de saisie semi-automatique (raisons de performances) à l'interface utilisateur et nous utilisons Websphere. Tous les conseils liés à Websphere sont donc les bienvenus.

43
lud0h

Les approches les plus simples sont:

  1. Ajoutez une minuterie d'expiration à votre cache singleton afin que de temps en temps le cache soit purgé et que les appels subséquents récupèrent les données mises à jour à partir de la source (par exemple, une base de données)

  2. Implémentez un mécanisme de notification pour le cache en utilisant quelque chose comme un sujet JMS/tibRV. Obtenez chaque instance de cache pour vous abonner et réagir à tout message de modification diffusé sur ce sujet.

9
pjp

Remplacez votre cache singleton par un cache distribué.

Un tel cache pourrait être JBoss Infinispan mais je suis sûr qu'il existe d'autres technologies de cache et de grille distribuées, y compris des technologies commerciales qui sont probablement plus matures à ce stade.

Pour les objets singleton en général, je ne suis pas sûr. Je pense que j'essaierais de ne pas avoir de singletons en premier lieu.

16
Chris Vest

Vous pouvez utiliser le DistributedMap intégré à WAS.

-Meule

8
Rick

Ou quelque chose comme memcached

http://www.danga.com/memcached/

Qu'est-ce que Memcached? memcached est un système de mise en cache d'objets de mémoire distribuée hautes performances, de nature générique, mais destiné à être utilisé pour accélérer les applications Web dynamiques en allégeant la charge de la base de données.

Danga Interactive a développé memcached pour améliorer la vitesse de LiveJournal.com, un site qui faisait déjà plus de 20 millions de pages dynamiques vues par jour pour 1 million d'utilisateurs avec un tas de serveurs Web et un tas de serveurs de bases de données. memcached a réduit la charge de la base de données à presque rien, entraînant des temps de chargement de page plus rapides pour les utilisateurs, une meilleure utilisation des ressources et un accès plus rapide aux bases de données en cas de défaillance de memcache.

4
monkey_p

Il y a plusieurs façons de gérer cela, selon 1) la façon dont les données sont hors des données et 2) chaque instance doit-elle avoir les mêmes valeurs tout le temps.

Si vous avez juste besoin de données raisonnablement à la hauteur des données, mais que chaque machine virtuelle Java n'a pas besoin d'avoir des données correspondantes, vous pouvez simplement demander à chaque jvm d'actualiser ses données selon la même planification (par exemple, toutes les 30 secondes).

Si l'actualisation doit avoir lieu à peu près au même moment, vous pouvez demander à un jvm d'envoyer un message aux autres en disant "il est temps d'actualiser maintenant".

Si chaque jvm a toujours besoin des mêmes informations, vous devez effectuer une synchronisation, où le maître dit "actualiser maintenant", tous les caches bloquent toutes les nouvelles requêtes, actualisent et indiquent au maître qu'elles sont terminées. Lorsque le maître obtient une réponse de chaque membre du cluster, il envoie un autre message qui dit de continuer.

1
KeithB

Je suis confronté à une situation similaire, mais j'utilise WebLogic d'Oracle et Cohérence .

Je travaille sur une application Web qui utilise un hashmap avec des données en cache lues dans la base de données (texte à afficher des étiquettes du formulaire Web ). Pour ce faire, les développeurs ont utilisé une instance singleton où ils ont stocké toutes ces informations. Cela fonctionnait bien sur un environnement à serveur unique, mais maintenant nous voulons aller dans une solution de cluster et je suis confronté à ce problème avec cette instance singleton.

D'après ce que j'ai lu maintenant, c'est la meilleure solution pour accomplir ce que je veux . J'espère que cela vous aidera aussi avec votre problème.

1
XpiritO

Si possible, utilisez la prise en charge de votre serveur d'applications pour cela, si possible (certains l'ont, d'autres pas). Par exemple, nous utilisons la prise en charge de JBoss pour un "HA Singleton" qui est un service qui s'exécute uniquement sur le nœud maître de cluster. Ce n'est pas parfait (vous devez gérer le cas où parfois le cerveau pète), mais c'est assez bon.

À défaut, vous pourrez peut-être concevoir quelque chose à l'aide de JGroups, qui fournit la découverte automatique et la négociation des nœuds de cluster, mais ce n'est pas trivial.

En dernier recours, vous pouvez utiliser le verrouillage de base de données pour gérer les singletons de cluster, mais c'est sérieusement fragile. Non recommandé.

Au lieu d'un singleton de cluster, vous pouvez utiliser un cache distribué à la place. Je recommande JBossCache (qui n'a pas besoin du serveur d'application JBoss pour fonctionner) ou EhCache (qui fournit maintenant un mécanisme de distribution). Vous devrez réorganiser votre cache pour qu'il fonctionne de manière distribuée (cela ne fonctionnera pas comme par magie), mais ce sera probablement une meilleure solution qu'un singleton de cluster.

1
skaffman

Je suis avec M. Vest Hansen à ce sujet, éloignez-vous le plus possible des singletons. Après avoir été en proie au cauchemar qu'est SAAJ et JAXP et avoir fait fonctionner des versions compatibles sur JBoss, j'en ai fini avec les singletons et les usines. Un message SOAP ne devrait pas avoir besoin d'une fabrique pour l'instancier.

D'accord, déclamez, qu'en est-il de memcache ou quelque chose de similaire? De quelle sorte d'affinité avez-vous besoin pour votre cache? Est-ce mauvais s'il est JAMAIS obsolète, ou y a-t-il une certaine flexibilité dans la façon dont les données peuvent être périmées?

1
Chris K

Il existe des produits pour avoir un cache de mémoire distribué (tel que memcache) qui peuvent aider dans cette situation.

Une meilleure solution, si possible, peut être que les singletons ne soient pas vraiment uniques, mais que l'application tolère d'avoir des instances distinctes (disons que tous reconnaissent quand ils doivent être actualisés) mais pas qu'ils doivent être synchronisés entre les machines virtuelles Java, qui peut transformer votre cache en goulot d'étranglement.

0
Yishai