2010-02-14 11 views
27

मैं दो ऐप्स के बीच साझा पूर्ण टेक्स्ट खोज के लिए Lucene.NET का उपयोग करना चाहता हूं: एक एएसपी.नेट एमवीसी एप्लीकेशन है और दूसरा एक कंसोल एप्लिकेशन है। दोनों अनुप्रयोगों को इंडेक्स को खोजना और अपडेट करना है। समेकन को कैसे संभाला जाना चाहिए?
मुझे tutorial on ifdefined.com मिला जहां समान उपयोग केस पर चर्चा की गई है। मेरी चिंता यह है कि लॉकिंग एक बड़ी बाधा होगी।लुसेन.NET में Concurrency।

पीएस: मैंने यह भी देखा कि इंडेक्सशियर इंडेक्स का एक स्नैपशॉट का उपयोग करता है और ऊपर वर्णित ट्यूटोरियल में केवल खोजकर्ता अद्यतन होने पर ही बनाया जाता है। क्या यह एक अच्छा दृष्टिकोण है? क्या मैं सिर्फ प्रत्येक खोज पर एक नियमित खोजकर्ता वस्तु बना सकता हूं और यदि हाँ ओवरहेड क्या है?

मुझे एक संबंधित प्रश्न Does Lucene.Net manage multiple threads accessing the same index, one indexing while the other is searching? क्या दावा है कि इंटरप्रोसेस समेकन सुरक्षित है। क्या इसका मतलब यह है कि यह सूचकांक के लिए कोई दौड़ की स्थिति नहीं है?

इसके अलावा एक बहुत ही महत्वपूर्ण पहलू। अगर प्रदर्शन कहते हैं कि 10-15 धागे this solution में प्रस्तुत साझा लॉक प्राप्त करने के माध्यम से लुसीन इंडेक्स को अपडेट करने का प्रयास कर रहे हैं तो प्रदर्शन हिट क्या शामिल है?

इसे दो महीनों का उपयोग करने के बाद मुझे खोज के लिए उस ओपनिंग इंडेक्स को जोड़ना होगा, यदि क्वेरी सॉर्टिंग का उपयोग करती है तो उच्च CPU और मेमोरी लोड के तहत आउटऑफमेमरी अपवाद बना सकता है। इंडेक्स ओपनिंग ऑपरेशन की लागत छोटी है (मेरे अनुभव में) लेकिन जीसी की लागत काफी अधिक हो सकती है।

उत्तर

30

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

अब हम लॉक के बारे में बात कर सकते हैं। यह लॉक ऑब्जेक्ट एक फ़ाइल आधारित लॉक है। मिथज़ की तरह पहले उल्लेख किया गया है, वहां बनाई गई 'write.lock' नामक एक फ़ाइल है जिसे बनाया गया है। एक बार जब एक लॉक लॉक ऑब्जेक्ट किया जाता है तो यह अनन्य है! लॉक हटा दिए जाने तक प्रतीक्षा करने के लिए यह लॉक सभी इंडेक्स संशोधित संचालन (इंडेक्सवाइटर, और इंडेक्स रीडर से कुछ विधियों) का कारण बनता है।

कुल मिलाकर आप और एक सूचकांक पर एकाधिक पढ़ते हैं। आप एक ही समय में भी पढ़ और लिख सकते हैं, कोई समस्या नहीं। लेकिन कई लेखकों के साथ एक समस्या है। यदि एक थ्रेड लॉक के लिए बहुत लंबा इंतजार कर रहा है तो यह समय समाप्त हो जाएगा।

1) संभव समाधान # 1 प्रत्यक्ष संचालन

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

2) संभव समाधान # 2 वेब सेवा

के बाद से आप एक वेब समाधान के साथ काम कर रहे हैं यह एक वेब सेवा बनाने के लिए संभव हो सकता है। इस वेब सेवा को लागू करते समय मैं इंडेक्सिंग के लिए एक वर्कर थ्रेड समर्पित करूंगा। मैं काम को शामिल करने के लिए एक कार्य कतार तैयार करूंगा और यदि कतार में कई नौकरियां होंगी, तो उन्हें सभी को पकड़ना चाहिए और उन्हें बैच में करना चाहिए। यह सभी समस्याओं को हल करेगा।

3), एक और सूचकांक बनाने तो विलय

सांत्वना आवेदन करता सूचकांक पर भारी काम आप कंसोल आवेदन आप कंसोल आवेदन में एक अलग सूचकांक बनाने और उसके बाद मर्ज कर सकते हैं होने की जांच के लिए सक्षम हो सकता है, तो indexWriter.AddIndexes का उपयोग कर कुछ सुरक्षित निर्धारित समय पर इंडेक्स।

यहां से आप इसे दो तरीकों से कर सकते हैं, आप सीधे सूचकांक में विलय कर सकते हैं। या आप एक तीसरी अनुक्रमणिका बनाने के लिए विलय कर सकते हैं, और फिर जब यह अनुक्रमणिका तैयार हो तो मूल अनुक्रमणिका को प्रतिस्थापित करें। आपको यह सुनिश्चित करने के लिए कि आप भारी उपयोग में कुछ लॉक नहीं करेंगे और अन्य लेखन कार्यों के लिए टाइमआउट का कारण बनने के लिए यहां क्या कर रहे हैं, इस बारे में सावधान रहना होगा।

4) सूचकांक & खोजें कई अनुक्रमित

व्यक्तिगत तौर पर मैं लोगों को अपने अनुक्रमणिका को अलग करने की जरूरत है। यह कार्यक्रमों की जिम्मेदारियों को अलग करने में मदद करता है और समय को कम करता है और सभी इंडेक्स के लिए एक बिंदु रखने के रखरखाव करता है। उदाहरण के लिए, यदि आपका कंसोल एप्लिकेशन केवल कुछ फ़ील्ड में जोड़ने के लिए ज़िम्मेदार है या आप इंडेक्स को विस्तारित करने के लिए जिम्मेदार हैं, तो आप इंडेक्स को अलग कर सकते हैं, लेकिन प्रत्येक दस्तावेज़ में आईडी फ़ील्ड का उपयोग करके पहचान बनाए रख सकते हैं। अब इसके साथ आप मल्टीशेचर क्लास का उपयोग करके एकाधिक इंडेक्स खोजने के लिए अंतर्निहित समर्थन का लाभ उठा सकते हैं। या यदि आपकी इच्छा है तो एक अच्छी समानांतर मल्टी सर्च क्लास भी है जो दोनों इंडेक्स को एक बार में खोज सकती है।

5) SOLR

में

कुछ और है कि आप सूचकांक के लिए एकमात्र स्थान बनाए रखने के अपने मुद्दे मदद कर सकते हैं, तो आप एक SOLR सर्वर के साथ काम करने के लिए अपने कार्यक्रम को बदल सकता है देखो। http://lucene.apache.org/solr/ एक अच्छी SOLRNET http://code.google.com/p/solrnet/ लाइब्रेरी भी है जो इस स्थिति में सहायक हो सकती है। हालांकि मुझे सोलर के साथ अनुभव नहीं हुआ है, लेकिन मैं इस धारणा के तहत हूं कि इससे आपको इस तरह की स्थिति का प्रबंधन करने में मदद मिलेगी। इसके अलावा अन्य लाभ भी हैं जैसे हिट हाइलाइटिंग और संबंधित आइटमों को खोजना "अधिक पसंद यह", या वर्तनी जांच प्रदान करना।

मुझे यकीन है कि अन्य विधियां हैं लेकिन ये सभी हैं जिनके बारे में मैं सोच सकता हूं। कुल मिलाकर यह आपका समाधान इस बात पर निर्भर करता है कि कितने लोग लिख रहे हैं और आपको जिस खोज इंडेक्स की आवश्यकता है, उसे अद्यतित कैसे करें। कुल मिलाकर यदि आप बाद के समय के लिए कुछ परिचालन रोक सकते हैं और किसी भी स्थिति में कुछ बैच ऑपरेशन आपको सबसे अधिक प्रदर्शन देंगे। मेरा सुझाव यह समझना है कि आप किसके साथ काम करने और वहां से जाने में सक्षम हैं। सौभाग्य

+0

वाह। धन्यवाद। मैं ऐसे समाधान के बारे में सोच रहा था जो किसी भी तरह से 2_ से संबंधित है। इस बीच मेरे पास अन्य प्रश्न है: "समानांतर MultiSearch या मल्टीशेचर समर्थन कितने अनुक्रमणिका कर सकते हैं"? –

6

मेरे पास एक ल्यूसीन सर्च इंडेक्स भी है जो कई क्लाइंट्स द्वारा उपयोग किया जाता है, मैं 'लुसीन सर्च सर्विस' को अपने स्वयं के ऐप डोमेन में चल रही एक अलग वेब सेवा बनाकर इस समस्या को हल करता हूं। चूंकि दोनों क्लाइंट इंडेक्स को खोजने या अपडेट करने के लिए एक ही वेब सेवा पर हिट करते हैं, इसलिए मैं इसे लुसीन के इंडेक्सर्स पर ताले के साथ थ्रेड-सुरक्षित बना सकता हूं।

इसके अलावा यदि आप इसे प्रक्रिया में रखना चाहते हैं तो मैं यह सुनिश्चित करने के लिए फ़ाइल लॉक का उपयोग करने का सुझाव देता हूं कि केवल एक ग्राहक इंडेक्स को लिख सकता है।

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

  • Index.Current> Index.Old
  • Index.New> Index.Current
+0

क्या आप फ़ाइल लॉक के बारे में अधिक स्पष्ट हो सकते हैं? तो आप एक नई अनुक्रमणिका का पुनर्निर्माण कर रहे हैं और फिर नए को स्विच कर रहे हैं और उसके बाद पुराने को हटा दें? धन्यवाद। –

+0

हाँ, मैं सिर्फ फाइल सिस्टम पर 'write.lock' जैसी कुछ खाली फ़ाइल बनाने का मतलब था, यह इंगित करने के लिए कि आप इंडेक्स को लिख रहे हैं। जब आप इंडेक्स को लिखना समाप्त कर लेते हैं तो आप इसे हटा दें। फिर आपको यह सुनिश्चित करना होगा कि लॉक बनाने वाली प्रक्रिया केवल इंडेक्स को पढ़/लिख सकती है। – mythz

5

आप विभिन्न प्रक्रियाओं में कई लेखकों होगा, और वे 10 सेकंड से अधिक खर्च करेगा सूचकांक करने के लिए अपने परिवर्तन लेखन (जो समय समाप्ति के लेखकों इंतजार कर कारण होगा) है, तो आप का उपयोग करके प्रक्रियाओं में पहुँच सिंक्रनाइज़ कर सकते हैं म्यूटेक्स नाम।बस प्रत्येक एप्लिकेशन में एक ही वैश्विक नाम के म्यूटेक्स को खोलें/बनाएं, और लिखने से पहले Mutex.WaitOne का उपयोग करें, और Mutex.ReleaseMutex लिखने के बाद।

var mut = Mutex.OpenExisting("myUniqueMutexName"); // wrap in try..catch to create if non-existent 
mut.WaitOne(); 
try { 
    // write logic 
} 
finally { 
    // recover from write failure 
    mut.ReleaseMutex(); 
} 

संभवतः म्यूटेक्स को सिंगलटन बनाने के लिए बेहतर है क्योंकि वे निर्माण के लिए थोड़ा महंगा हैं।

अद्यतन (टिप्पणी प्रति):

प्रक्रियाओं अलग मशीनों पर कर रहे हैं, मुझे लगता है कि अपने एकमात्र विकल्प अपनी खुद की फाइल सिस्टम ताला परत (पुराने ढंग का ताला फ़ाइलों का उपयोग) का उपयोग सिंक्रनाइज़ करने के लिए है। चूंकि बिल्ट-इन लॉकिंग फाइल सिस्टम लॉक का उपयोग करता है, इसलिए मैं वास्तव में आपको सलाह देता हूं कि इंडेक्सवाइटर टाइमआउट हर बार जब आप एक बनाते हैं तो बढ़ाएं।

var iw = new IndexWriter(); 
iw.WRITE_LOCK_TIMEOUT = 60000; 

आप भी एक निश्चित संख्या की कोशिश कर सकते हैं।

var committed = false; 
var attempts = 0; 
while(!committed && attempts < 10) { 
    try { 
    // write logic 
    committed = true; 
    } catch (LockObtainFailedException) { 
    attempts++; 
    } 
} 
+0

आपके समाधान के लिए धन्यवाद। मैं एक अच्छा होगा लेकिन बुनियादी ढांचे के कारण इसे लागू नहीं किया जा सकता है क्योंकि विभिन्न मशीनों पर प्रक्रियाएं चल रही हैं और साझा नेटवर्क फ़ोल्डर में ल्यूसीन इंडेक्स तक पहुंच रही हैं। तो mutex उन प्रक्रियाओं को अवरुद्ध करने में सक्षम नहीं होगा। –

+0

मेरा बुरा हालांकि मैंने इसे प्रश्न में निर्दिष्ट नहीं किया था। मुझे माफ कर दो। –

+0

मैंने आपकी टिप्पणियों के जवाब में अपना उत्तर अपडेट कर दिया है। –

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