2017-07-05 4 views
3

j'ai pu obtenir avec succès verrou sur /ads/lock/0-test1 et ne pouvait pas obtenir un verrou sur /ads/lockConservateur verrouillage Hiérarchie (serrures) se chevauchent

Comment puis-je résoudre ce problème?

InterProcessMutex lock1 = new InterProcessMutex(client, "/ads/lock/0-test1"); 
if(lock1.acquire(30000, TimeUnit.MILLISECONDS)){ 
    InterProcessMutex lock2 = new InterProcessMutex(client, "/ads/lock"); 

    if(lock2.acquire(30000, TimeUnit.MILLISECONDS)) { //Failing 
    ... 
    } 
} 

Mise à jour: Ce est l'essence de ce qui se passe dans ce https://github.com/Microsoft/Cluster-Partition-Rebalancer-For-Kafka/ZookeeperBackedAdoptionLogicImpl.java Serrures à la ligne 250 (chemin détaillé) et 299 (chemin racine) sont séquentielles. Ainsi, lorsqu'une autre instance essaie de verrouiller un chemin détaillé (250), le verrou échoue lorsque le chemin racine (299) est verrouillé. La logique est valide, mais le verrou racine est jamais obtenue

Mise à jour 2: J'ai écrit un petit programme pour vérifier si les verrous qui se chevauchent et fonctionnent Il fait.

public class LockTesting { 
    public static final String ROOT_LOCK = "/locks"; 
    public static final String CHILD_LOCK = ROOT_LOCK+"/child"; 
    private static CuratorFramework client; 

    public static void main(String[] args) throws Exception { 

     client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", new ExponentialBackoffRetry(1000, 30)); 
     client.start(); 
     InterProcessMutex lock1 = new InterProcessMutex(client, CHILD_LOCK); 
     if (lock1.acquire(30000, TimeUnit.MILLISECONDS)) { 
      System.out.println("Child Locked"); 
      InterProcessMutex lock2 = new InterProcessMutex(client, ROOT_LOCK); 
      if (lock2.acquire(30000, TimeUnit.MILLISECONDS)) { 
       System.out.println("Root Locked"); 
      } 
     } 

    } 
} 
+1

S'il vous plaît regardez Curator Tech Note 7: https://cwiki.apache.org/confluence/display/CURATOR/TN7 - Vous ne pouvez pas avoir des chemins qui se chevauchent comme vous le faites dans votre exemple. En outre, il n'y a aucune raison pour cela. Utilisez un chemin différent pour le deuxième verrou. – Randgalt

+0

Merci. Mais comme vous le voyez dans la mise à jour 2, les verrous qui se chevauchent fonctionnent. Donc, il n'y a rien de mal avec Microsoft/Cluster-Partition-Rebalancer-For-Kafka. Mais comme vous dites aucune raison d'utiliser comme il est utilisé dans la bibliothèque. –

+0

La mise à jour 2 peut toujours échouer. Je vous ai déjà averti plusieurs fois d'avoir des chemins qui se chevauchent. S'il vous plaît ne le faites pas - Le conservateur ne le supporte pas et il n'y a aucune raison de le faire. – Randgalt

Répondre

2

Bien que non documenté explicitement (mais voir technote 7), les mécanismes utilisés par le conservateur pour créer le verrouillage dépendent des nœuds enfants d'un chemin de znode particulier. Le InterProcessMutex est une implémentation du zookeeper lock recipe, dont la documentation inclut ces détails. En essayant d'utiliser une construction hiérarchique comme celle-ci, vous êtes en train de jouer avec la structure interne de la serrure.

Le chemin à verrouiller doit être considéré comme un "objet" dont les znodes internes sont inaccessibles et susceptibles d'être modifiés.

Réponse à mettre à jour

Le code en question est en effet un exemple de cette utilisation inappropriée.

Réponse à Update2

Oui, il peut parfois fonctionner. Mais cela dépend des détails internes de l'implémentation InterProcessMutex. Vous verrez qu'avec certains noms de verrous, cela fonctionnera et avec d'autres, cela ne fonctionnera pas ou vous aurez un comportement indéfini.

+0

Merci Martin. S'il vous plaît jeter un oeil à la mise à jour à la question –

+0

Il est un peu documenté dans cette note technique: https://cwiki.apache.org/confluence/display/CURATOR/TN7 – Randgalt

+0

@randgalt, merci, j'ai mis à jour la réponse –