Durante la lettura dello recipe for lock di ZooKeeper, mi sono confuso. Sembra che questa ricetta per i blocchi distribuiti non possa garantire "" alcuna istantanea nel tempo in cui due client non ritengono di avere lo stesso blocco ". Ma dal momento che ZooKeeper è ampiamente adottato, se ci fossero tali errori nella documentazione di riferimento, qualcuno avrebbe dovuto indicarlo molto tempo fa, quindi cosa ho frainteso?Preoccupazioni per la ricetta di blocco dello zookeeper
Citando the recipe for distributed locks:
Serrature
serrature completamente distribuiti che globalmente sincrono, significato a qualsiasi istantanea in tempo non esistono due clienti pensano tengono la stessa serratura. Questi possono essere implementati usando ZooKeeeper. Come con le code di priorità, prima definire un nodo di blocco.
- chiamata a creare() con un percorso di "LockNode/guid-Lock" e la sequenza e le bandiere effimere set.
- Chiamare getChildren() sul nodo di blocco senza impostare il flag di controllo (questo è importante per evitare l'effetto herd).
- Se il percorso creato nel passaggio 1 ha il suffisso del numero di sequenza più basso, il client ha il blocco e il client esce dal protocollo.
- Le chiamate client esiste() con il flag di controllo impostato sul percorso nella directory di blocco con il numero di sequenza successivo più basso.
- se esiste() restituisce false, passare al punto 2. In caso contrario, attendere una notifica per il percorso del passaggio precedente prima di passare alla fase 2.
Si consideri il seguente caso:
- Client1 ha acquisito correttamente il blocco (nel passaggio 3), con il nodo ZooKeeper "locknode/guid-lock-0";
- Client2 ha creato il nodo "locknode/guid-lock-1", non è riuscito ad acquisire il blocco e ora sta guardando "locknode/guid-lock-0";
- Successivamente, per qualche motivo (ad esempio, congestione della rete), Client1 non riesce a inviare un messaggio heartbeat al cluster ZooKeeper in tempo, ma Client1 funziona ancora, assumendo erroneamente che sia ancora in possesso del blocco.
Ma, ZooKeeper può pensare seduta di Client1 è scaduta, e quindi
- delete "LockNode/guid-lock-0",
- inviare una notifica al Client2 (o forse inviare la notifica prima?),
- ma non è possibile inviare una notifica di "timeout della sessione" a Client1 in tempo (ad esempio, a causa della congestione della rete).
- Client2 ottiene la notifica, va al passo 2, ottiene l'unico nodo "" LockNode/guid-lock-1" , che essa stessa ha creato,. Quindi, Client2 presuppone che detiene il blocco
- Ma allo stesso tempo, Client1 presuppone che detenga il blocco
Si tratta di uno scenario valido?
Discussione parallela sulla mailing list _zookeeper-users: http://thread.gmane.org/gmane.comp.java.hadoop.zookeeper.user/5065 – seh