2014-10-01 9 views
21

टीएल; डीआर: मैं या तो अपना दिमाग खो रहा हूं, या neo4j के लेनदेन थोड़ा टूटा हुआ है। ऐसा लगता है कि अनुपयुक्त नोड्स प्रतिबद्ध लेनदेन के बाहर उपलब्ध हैं, गायब गुणों के साथ - या कुछ समान रूप से अजीब।क्या neo4j के साइफर लेनदेन टूट गए हैं?

हमारा node.js ऐप neo4j का उपयोग करता है। इसका एक हिस्सा अद्वितीय आईडी उत्पन्न करना है। हमारे पास निम्न साइफर क्वेरी है जो अंतिम :Id-प्रकार नोड का पता लगाने के लिए है और last_uuid+1 के साथ एक नया :Id नोड करने का प्रयास करें।

MATCH (i:Id) WITH i ORDER BY i.uuid DESC LIMIT 1 #with it like a sub-return, will "run" the rest with the last i at read-time 
CREATE (n:Id {label:"Test"}) 
SET n.uuid = i.uuid + 1 
RETURN n 

वहाँ भी एक बाधा है:

neo4j-sh (?)$ schema 
Indexes 
    ON :Id(uuid) ONLINE (for uniqueness constraint) 

Constraints 
    ON (id:Id) ASSERT id.uuid IS UNIQUE 

और डीबी एक (:Id{uuid:1}) साथ आरंभ नहीं हो जाता इस खुशी लात-शुरू करने के लिए।

ऐप कोड मूल रूप से उपरोक्त क्वेरी को तब तक पुनः प्रयास करता है जब तक यह सफल न हो जाए। यदि दो या दो से अधिक आईडी निर्माण अनुरोध एक ही समय में हिट हो जाते हैं, तो उनमें से केवल एक ही जाएगा, बाकी शेष विफल हो जाएंगे और ऐप कोड द्वारा पुनः प्रयास किए जाएंगे।

यह तब तक काम करता है जब तक हम इसे समानांतर में नहीं करते।

कोड ने यूयूआईडी के बिना डेटा वापस करना शुरू कर दिया। बहुत सारी जांच के बाद, यह पता चला है कि क्वेरी का लेखन भाग (CREATE ...) किसी भी तरह से प्राप्त कर रहा है: MATCH से आईडी जिसमें कोई .uuid (या अन्य) गुण नहीं है। यह संभव नहीं होना चाहिए। यह एकमात्र कोड है जो उन नोड्स पर काम करता है।

अजीब (शायद) बात है, कि अगर मैं बचाने i के nodeid आदेश डीबी में उस नोड का पता लगाने का में, यह वास्तव में मौजूद है और एक .uuid संपत्ति है।

इस व्यवहार को अलग करने के लिए मैंने एक पीओसी लिखा: neo4j-transaction-test यह नोडजेस के साथ चलाने के लिए वास्तव में आसान होना चाहिए।

यह मूल रूप से एक बालक थोड़ा ऊपर कोड की तुलना में अधिक है - आईडी बनाने के लिए कोशिश करता है, prev_label, prev_nodeid, और पिछले नोड के (i) मूल्यों के prev_uuid की स्थापना। 9339 और आउटपुट:

> node server.js 
* 1412125626667 Listening on 9339 
Req Id | Datetime | -> $uuid $nodeid 
1 1412125631677 'GET'  # When it first receives the GET request 
1 1412125631710 '->' 9 60 # When neo4j returns; numbers are $uuid $node_id) 

जब चीजें समवर्ती हो रही शुरू, प्रश्नों विफल हो सकता है: यह हर के लिए क्वेरी प्राप्त का अनुरोध यह स्थानीय होस्ट पर प्राप्त करता है चलाता है

3 1412125777096 '(retry) (0)' 'Node 64 already exists with label Id and property "uuid"=[13]' 
4 1412125777098 '(retry) (0)' 'Node 64 already exists with label Id and property "uuid"=[13]' 
de[] 

है जो उम्मीद की जा करने के लिए, और वे कर रहे हैं पुनः प्रयास किया। अगर हम "स्लैम" प्रति सेकंड (ab -n 1000 -c 10 http://localhost:9339/) reqs के एक जोड़े के साथ सर्वर, हम अंत में देखेंगे:

... 
59 1412127103011 'GET' 
23 1412127103024 'ERROR - EMPTY UUID' '{"this_nodeid":22,"prev_nodeid":20,"label":"Test"}' 

Error: Empty UUID received 

(और अंत में से, मैं लगभग तुरंत मतलब) एक नोड वापस, UUID के बिना आता है, prev_uuid या prev_label। this_nodeid और prev_nodeid neo4j की आंतरिक आईडी का संदर्भ लें। अगर हम इन को देखने के लिए, पिछले (i) आईडी नोड के साथ शुरू (nodeid से - 20):

neo4j-sh (?)$ match (i) where id(i)=20 return i; 
+--------------------------------------------------------------------------------------------+ 
| i                       | 
+--------------------------------------------------------------------------------------------+ 
| Node[20]{uuid:10,label:"Test",prev_label:"Test",prev_uuid:9,prev_nodeid:17,this_nodeid:20} | 
+--------------------------------------------------------------------------------------------+ 
1 row 
19 ms 

यह बिल्कुल के रूप में यह होना चाहिए। .uuid और सभी।नया एक वास्तव में बनाया गया है जैसा कि यह ऊपर दिया गया है:

neo4j-sh (?)$ match (i) where id(i)=22 return i; 
+------------------------------------------------------+ 
| i             | 
+------------------------------------------------------+ 
| Node[22]{label:"Test",prev_nodeid:20,this_nodeid:22} | 
+------------------------------------------------------+ 
1 row 
17 ms 

कोई prev_label या prev_uuid नहीं। यह कैसे संभव है? मैं क्या खो रहा हूँ? एक अधूरा है: आईडी नोड मेरी क्वेरी में लीक?

मैंने डेटा डीआईआर को पोंछने के बाद पुनरारंभ करने की कोशिश की है, डेटा डीआईआर को पोंछने के बाद पुनरारंभ किया है, लॉग को खराब कर दिया है (कुछ भी दिलचस्प नहीं है, या यहां तक ​​कि उबाऊ लेकिन सही समय पर - उपरोक्त होने पर)। मैं अब उस बिंदु पर हूं जहां मैं अपनी समझ पर सवाल कर रहा हूं कि यह कैसे काम करना है।

यह 12.04 पर neo4j 2.1.1 के साथ है। More Version Info और Neo4j startup/shutdown logs

मुझे पता है कि यह यूयूआईडी बनाने का एक इष्टतम तरीका नहीं है। यह प्रश्न यह समझने के बारे में है कि नव -4 के लेन-देन की अपेक्षा के अनुसार ये परिणाम कैसे संभव हैं।

+0

मैं इसे समझता हूं। अगर हम neo4j (बहुत संभावना नहीं) के साथ चिपके रहते हैं तो आईडी पीढ़ी कोड डीबी से हटा दिया जाएगा। मैं अभी भी जानना चाहता हूं कि मैं इस परिणाम को कैसे देख रहा हूं - यह साइफर लेनदेन के साथ कुछ तोड़ने का संकेत देता है। –

+3

बनाने के बजाय आपने मर्ज (बेहतर लॉकिंग) का उपयोग किया है? क्या आप नियो 4 जे नोड.जेएस कोड भी ले सकते हैं और ट्रांजैक्शनल एंडपॉइंट को सीधे इस पर शासन करने का प्रयास कर सकते हैं (http://docs.neo4j.org/chunked/stable/rest-api-transactional.html) जैसा कि मुझे लगता है कि विशेष (अनौपचारिक) नोड लाइब्रेरी विरासत एंडपॉइंट हिट करता है (आपका नियो नया है, आपका नोड नहीं है)। फिर आप कच्ची प्रतिक्रिया भी देख सकते हैं। – JohnMark13

+0

@ टासोसबिट्सियो इस पर कोई संकल्प था? – JohnMark13

उत्तर

1

हमने समवर्ती लेनदेन लिखने के दौरान नियो 4 जे में एक समान समस्या देखी और इस पते को हल करने के लिए नियो 4 जे 2.2.5 में एक फिक्स पेश किया गया (हमारे पास एंटरप्राइज़ समर्थन है और यह तय करने के लिए टिकट उठाया गया है)। आपके पास बिल्कुल वही समस्या नहीं हो सकती है, लेकिन 2.2.5 का उपयोग करके फिर से प्रयास करने के लायक हो सकता है यह देखने के लिए कि यह अभी भी एक मुद्दा है या नहीं।

जैसा कि आपने कहा था, आईडी उत्पन्न करने के बेहतर तरीके हैं। इसके अलावा, LIMIT और ORDER BY के बजाय नवीनतम प्राप्त करने के लिए आपको MAX का उपयोग करना चाहिए, लेकिन यह बिंदु के अलावा भी है ;-)।

शुभकामनाएं।

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