2012-03-27 6 views
10

एक पथ "/ जड़/child1/child2/child3"ज़ूकीपर में पथ बनाने का सबसे प्रभावी तरीका जहां पथ के रूट तत्व मौजूद हो सकते हैं या नहीं हो सकते हैं?

चिड़ियाघर संचालक शायद इस का एक हिस्सा मौजूद है में कल्पना कीजिए कल्पना कीजिए, कहते हैं कि "/ जड़/child1"

"mkdir -p का कोई बराबर है "ज़ूकीपर में; इसके अलावा, यदि कोई भी ऑपरेशन विफल रहता है तो ZooKeeper.multi() विफल हो जाएगा, इसलिए "पथ बनाना" वास्तव में एक बहु कॉल में बेक नहीं किया जा सका। इसके अतिरिक्त, आप कुछ अन्य क्लाइंट को एक ही रास्ता बनाने की कोशिश कर सकते हैं ...

यही वह तरीका है जो मैंने पथ बनाने के लिए किया है। मुझे आश्चर्य है कि क्या यह देखने के लायक है कि कोई हिस्सा मौजूद है या नहीं, मौजूदा() कॉल की राउंड ट्रिप को सहेजने के लिए।

//String[] pathParts new String[] { "root", "child1", "child2", "child3" }; 

public void savePath(String[] pathParts) { 
    if (zooKeeper.exists(pathString, false) != null) return; 
    StringBuilder path = new StringBuilder(); 
    for (String pathElement : pathParts) { 
     path.append(UNIX_FILE_SEPARATOR).append(pathElement); 
     String pathString = path.toString(); 
     try { 
      //bother with the exists call or not? 
      if (zooKeeper.exists(pathString, false) == null) { 
       zooKeeper.create(pathString, null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); 
      } 
     } catch (KeeperException e) { 
      if (e.code() != KeeperException.Code.NODEEXISTS) 
       throw e; 
     } 
    } 
} 

क्या यह करने के लिए सबसे कारगर तरीका हो सकता है? मान लीजिए कि ए) आप समय से पहले नहीं जानते कि कितना पथ पहले से मौजूद है और बी) कुछ अन्य ग्राहक एक ही पथ लिखने की कोशिश कर रहे हैं (और हम लॉकिंग से बचना चाहते हैं)।

+0

अनुरोध 1 पर प्रतिक्रिया के लिए सर्वर का इंतजार किए बिना अपने पथ के सभी घटकों को बना सकते हैं कर सकते हैं का उपयोग कर सकते हैं इंस्टेंस वेरिएबल पथ में क्या शामिल है और पथपार्ट पैरामीटर को क्या पास किया जा रहा है इसका एक उदाहरण दें? कोड के बारे में कुछ उलझन में अपने संलग्न पथ के रूप में खुद को उलझन में डाल दिया। –

+0

क्षमा करें - इसमें कुछ गलतियां थीं। अब तय किया गया है, कम या ज्यादा। – marathon

उत्तर

7

एक मौजूद कॉल ग्राहक के लिए सर्वर से 1 राउंड ट्रिप के साथ बनाया जा सकता है।

एक निर्माण कॉल में एक ही दौर यात्रा है, लेकिन एक लेखन ऑपरेशन है जो ज़ेड क्लस्टर में सर्वर के बीच दो और दौर की यात्रा करता है, इसलिए एक निर्माण थोड़ा महंगा है जो अस्तित्व में है।

तो अपने एल्गोरिथ्म के लिए कुल समय, 1 पढ़ने के लिए

समय सेशन * संभावना नोड पहले से मौजूद है + है * (1 लिखने सेशन के लिए समय) (1 - संभावना नोड पहले से मौजूद है)।

तो if(!exist()) create() बनाम create() या तो तेजी से हो सकता है। अंत में यह कोई फर्क नहीं पड़ता।

तुम सच में तेजी से होना चाहते हैं, तो आप async एपीआई ताकि आप द्वारा 1.

final AtomicBoolean success = new AtomicBoolean(false); 
final CountdownLatch latch = new CountdownLatch(1); 
StringCallback cb = new StringCallback() { 
    processResult(int rc, String path, Object ctx, String name) { 
     if(name.equals(pathString) { 
      //wait for the last path 
      success.set(rc == KeeperException.Code.NODEEXISTS || 
         rc == KeeperException.Code.OK); 
      latch.countDown(); 
     } 
    } 
}; 

StringBuilder path = new StringBuilder(); 
for (String pathElement : pathParts) { 
    path.append(UNIX_FILE_SEPARATOR).append(pathElement); 
    String pathString = path.toString(); 
    //send requests to create all parts of the path without waiting for the 
    //results of previous calls to return 
    zooKeeper.create(pathString, null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT, cb); 
} 
latch.await(); 
if(!success.get()) { 
    throw ... 
} 
+0

शानदार उत्तर है। +1 – kirugan

13

आप जो बहुत सरल चिड़ियाघर संचालक का उपयोग कर बनाता है Netflix's curator पुस्तकालय का उपयोग कर सकते

client.create().withMode(CreateMode.PERSISTENT).forPath("/root/child1/child2/child3", new byte[0]).withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE).creatingParentsIfNeeded(); 
+0

लेकिन क्या यह ऊपर से कहीं अधिक कुशल है, या क्या यह इसे छिपाता है? – marathon

+0

EnsurePath (https://github.com/Netflix/curator/blob/master/curator-client/src/main/java/com/netflix/curator/utils/EnsurePath.java) और ZKPaths (https: //github.com/Netflix/curator/blob/master/curator-client/src/main/java/com/netflix/curator/utils/ZKPaths.java) और अपने लिए निर्णय लें –

+0

नेटवर्क कॉल की संख्या, लेकिन इससे भी बदतर क्योंकि उनके पास एक सिंक्रनाइज़ ब्लॉक है। मैं एक परमाणु पथ निर्माण कॉल के लिए पूछने वाले zookeeper लोगों के साथ एक टिकट खोलने जा रहा हूँ। – marathon

संबंधित मुद्दे