54 votes

Contrôle distribué de la concurrence

Je travaille sur ce sujet depuis quelques jours maintenant, et j'ai trouvé plusieurs solutions mais aucune d'entre elles n'est incroyablement simple ou légère. Le problème est essentiellement le suivant : Nous avons un cluster de 10 machines, chacune d'entre elles exécutant le même logiciel sur une plateforme ESB multithread. Je peux gérer les problèmes de concurrence entre les threads sur la même machine assez facilement, mais qu'en est-il de la concurrence sur les mêmes données sur différentes machines ?

Essentiellement, le logiciel reçoit des demandes pour alimenter les données d'un client d'une entreprise à une autre via des services web. Cependant, le client peut ou non exister encore sur l'autre système. S'il n'existe pas, nous le créons via une méthode de service web. Cela nécessite donc une sorte de test-and-set, mais j'ai besoin d'une sorte de sémaphore pour empêcher les autres machines de provoquer des conditions de course. Il m'est déjà arrivé qu'un client distant soit créé deux fois pour un seul client local, ce qui n'est pas vraiment souhaitable.

Les solutions que j'ai envisagées sont les suivantes :

  1. Utilisation de notre système de fichiers partagés tolérant aux pannes pour créer des fichiers "verrouillés" qui seront vérifiés par chaque machine en fonction du client.

  2. Utiliser une table spéciale dans notre base de données, et verrouiller toute la table afin de faire un "test-and-set" pour un enregistrement de verrouillage.

  3. Utilisation de Terracotta, un logiciel de serveur à source ouverte qui aide à la mise à l'échelle, mais qui utilise un modèle en étoile.

  4. J'utilise EHCache pour la réplication synchrone de mes "verrous" en mémoire.

Je ne peux pas imaginer que je suis la seule personne à avoir eu ce genre de problème. Comment l'avez-vous résolu ? Avez-vous conçu quelque chose en interne ou avez-vous un produit tiers préféré ?

0voto

user2179737 Points 11

Puisque vous vous connectez déjà à une base de données, avant d'ajouter une autre pièce d'infrastructure, jetez un coup d'oeil à JdbcSemaphore il est simple à utiliser :

JdbcSemaphore semaphore = new JdbcSemaphore(ds, semName, maxReservations);
boolean acq = semaphore.acquire(acquire, 1, TimeUnit.MINUTES);
if (acq) {
 // do stuff
 semaphore.release();
} else {
  throw new TimeoutException();
}

Il fait partie de spf4j bibliothèque.

-1voto

clintp Points 5127

A l'époque, nous utilisions un "serveur de verrouillage" spécifique sur le réseau pour gérer cela. Beurk.

Votre serveur de base de données peut disposer de ressources spécifiques pour faire ce genre de choses. MS-SQL Server dispose de verrous d'application utilisables via la fonction sp_getapplock / sp_releaseapplock procédures.

-5voto

Kamran Points 1

Nous avons développé un cadre de synchronisation distribué à code source ouvert. Actuellement, les verrous DistributedReentrantLock et DistributedReentrantReadWrite ont été implémentés, mais ils sont toujours en phase de test et de refactoring. Dans notre architecture, les clés de verrouillage sont divisées en buckets et chaque nœud est responsable d'un certain nombre de buckets. Ainsi, pour une demande de verrouillage réussie, il n'y a qu'une seule demande de réseau. Nous utilisons également la classe AbstractQueuedSynchronizer comme état de verrouillage local, de sorte que toutes les demandes de verrouillage échouées sont traitées localement, ce qui réduit considérablement le trafic réseau. Nous utilisons les JGroups ( http://jgroups.org ) pour la communication de groupe et Hessian pour la sérialisation.

Pour plus de détails, veuillez consulter http://code.google.com/p/vitrit/ .

Veuillez m'envoyer vos commentaires.

Kamran

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X