2012-06-06 13 views
7

मेरे पास एक डेटाबेस तालिका है जिसमें कुछ रिकॉर्ड संसाधित किए गए हैं। तालिका में एक ध्वज स्तंभ है जो निम्न स्थिति मानों का प्रतिनिधित्व करता है। 1 - संसाधित होने के लिए तैयार, 2- सफलतापूर्वक संसाधित, 3- प्रसंस्करण विफल।डेटाबेस रिकॉर्ड के समूह को संसाधित करने के लिए मल्टीथ्रेडिंग का उपयोग करने के विकल्प?

.NET कोड (दोहराव प्रक्रिया - कंसोल/सेवा) उन अभिलेखों की एक सूची ले जाएगा जो संसाधित होने के लिए तैयार हैं, और उनके माध्यम से लूप करें और उन्हें संसाधित करने का प्रयास करें (बहुत लंबा नहीं), सफलता के आधार पर अद्यतन स्थिति या विफलता।

बेहतर प्रदर्शन करने के लिए, मैं इस प्रक्रिया के लिए मल्टीथ्रेडिंग सक्षम करना चाहता हूं। मैं 6 धागे, प्रत्येक धागे एक सबसेट पकड़ने के लिए सोचने के लिए सोच रहा हूँ।

स्पष्ट रूप से मैं अलग-अलग धागे को एक ही रिकॉर्ड को संसाधित करने से बचना चाहता हूं। मैं उस मामले को संभालने के लिए डेटाबेस में "संसाधित होने" ध्वज नहीं चाहता हूं जहां थ्रेड रिकॉर्ड लटकने से क्रैश हो जाता है।

मुझे ऐसा करने का एकमात्र तरीका उपलब्ध रिकॉर्ड्स की पूरी सूची को पकड़ना और प्रत्येक थ्रेड में समूह (शायद आईडी) असाइन करना है। यदि कोई व्यक्तिगत धागा विफल रहता है, तो अगली बार प्रक्रिया चलने पर इसके अनप्रचारित रिकॉर्ड उठाए जाएंगे।

क्या थ्रेड को निर्दिष्ट करने से पहले समूहों को विभाजित करने के लिए कोई अन्य विकल्प है?

+0

क्या आपके पास अपनी तालिका में कोई पहचान कॉलम है? – YavgenyP

+1

आपको वास्तव में कतार के रूप में अपने डेटाबेस का उपयोग नहीं करना चाहिए। http://en.wikipedia.org/wiki/Database-as-IPC – Oded

+0

थ्रेड, और प्रक्रियाएं, अप्रत्याशित रूप से और अधिकतर खराब समय पर मर जाती हैं। एक थ्रेड आईडी/थ्रेड नंबर पर डीबी आईडी ट्राइंग करना एक अच्छा विचार नहीं है। –

उत्तर

6

इस आवश्यकता को लागू करने के लिए सबसे सरल तरीके से उपयोग करने के लिए है टास्क समानांतर लाइब्रेरी की

Parallel.ForEach (या Parallel.For)।

इसे व्यक्तिगत कार्यकर्ता धागे प्रबंधित करने की अनुमति दें।

अनुभव से, मैं सिफारिश करेंगे निम्नलिखित:

  • एक अतिरिक्त स्थिति "प्रसंस्करण"
  • डेटाबेस में एक कॉलम यह दर्शाता है कि जब एक रिकॉर्ड प्रसंस्करण और एक सफाई कार्य के लिए उठाया गया था है/लो प्रक्रिया जो समय-समय पर रिकॉर्डिंग की तलाश करती है जो बहुत लंबे समय तक "प्रसंस्करण" कर रही है (स्थिति को "प्रसंस्करण के लिए तैयार" पर रीसेट करें।
  • भले ही आप इसे नहीं चाहते हैं, "संसाधित होने" को पुनर्प्राप्त करने के लिए आवश्यक होगा परिदृश्य (जब तक आप एक ही रिकॉर्ड को दो बार संसाधित नहीं कर सकते)।

वैकल्पिक रूप से

एक लेन-देन संबंधी कतार (MSMQ या खरगोश MQ मन के लिए आते हैं) का उपयोग पर विचार करें। वे इस समस्या के लिए अनुकूलित कर रहे हैं।

यह मेरी स्पष्ट पसंद होगी, दोनों बड़े पैमाने पर किए गए हैं।

अनुकूलन यह डेटाबेस से डेटा पुनः प्राप्त करने के लिए समय की एक गैर तुच्छ राशि लेता है, तो आप एक निर्माता/उपभोक्ता पैटर्न है, जो काफी BlockingCollection साथ लागू करने के लिए सरल है पर विचार कर सकते हैं। वह पैटर्न एक थ्रेड (निर्माता) को डीबी रिकॉर्ड्स के साथ एक कतार को पॉप्युलेट करने की अनुमति देता है, और कई अन्य धागे (उपभोक्ता) उस कतार से वस्तुओं को संसाधित करने की अनुमति देता है।

एक नया विकल्प

यह देखते हुए कि कई संसाधन चरणों रिकॉर्ड को छूने से पहले ही पूरा माना जाता है, एक संभावित विकल्प के रूप में Windows Workflow Foundation पर एक नजर है।

+0

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

+0

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

+0

@AlexJ: "सफलता या विफलता के लिए सेट होने के बाद, इसे संसाधित माना जाता है" का अर्थ है कि आपको अतिरिक्त स्थिति की आवश्यकता नहीं है। कई सिस्टम कुछ रोलबैक तर्क के बिना आंशिक रूप से संसाधित रिकॉर्ड को फिर से संसाधित करने की अनुमति नहीं दे सकते हैं। चूंकि आप इसे बर्दाश्त कर सकते हैं, इसलिए आप उस संबंध में जाने के लिए अच्छे हैं। मैं बस समानांतर के साथ जाऊंगा। फिर(), और ब्लॉकिंगक्यूयू पेश करें यदि केवल और यदि आप संसाधित किए जाने से पहले डीबी से रिकॉर्ड प्राप्त करने में महत्वपूर्ण समय बिताते हैं। –

2

मुझे कुछ ऐसा करना याद है जो आपने वर्णित किया है ... समय-समय पर एक थ्रेड चेक करता है यदि डेटाबेस में कुछ नया है जिसे संसाधित करने की आवश्यकता है। यह केवल नए आईडी लोड करेगा, इसलिए यदि समय x अंतिम आईडी पढ़ा गया है तो 1000 है, x + 1 पर आईडी 1001 से पढ़ा जाएगा।

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

आपको कार्य foreach धागा से पहले असाइन नहीं करना चाहिए (जब तक कि आप जानते हैं कि फ़ोरैच फ़ाइल प्रक्रिया को एक ही समय लेती है)। यदि कोई धागा काम खत्म कर देता है, तो उसे दूसरे लोगों से लोड लेना चाहिए। इस थ्रेड सुरक्षित कतार का उपयोग करके, आप इसे सुनिश्चित करते हैं।

+0

यदि आप इन-मेमोरी कतार का उपयोग करते हैं, तो आप क्रैश परिदृश्य से पुनर्प्राप्त नहीं हो सकते हैं जब तक कि यह एक ही रिकॉर्ड को कई बार संसाधित करने के लिए स्वीकार्य नहीं है। –

+0

वास्तव में, लेकिन अगर वह उन 3 राज्यों को नहीं बदल सकता है? –

+0

आह, लेकिन वह कर सकता है। उन्होंने अभी कहा कि वह थ्रेड क्रैश रिकवरी के कारण नहीं चाहते हैं, लेकिन वास्तव में उन्हें वसूली को सक्षम करने की आवश्यकता है (रिकॉर्ड की प्रतिलिपि स्वीकार करने की अनुमति नहीं है)। –

0

यहां एक ऐसा दृष्टिकोण है जो अतिरिक्त डेटाबेस कॉलम पर भरोसा/उपयोग नहीं करता है (लेकिन # 4 देखें) या इन-प्रोसेस कतार को जरूरी है। इस दृष्टिकोण का आधार श्रमिकों पर कुछ स्थिर मूल्यों के आधार पर वितरित कैश की तरह "शेर्ड" रिकॉर्ड करना है।

यहाँ मेरी मान्यताओं हैं:

  1. पुन: प्रसंस्करण अवांछित दुष्प्रभाव का कारण नहीं है; ज्यादातर काम पर "बर्बाद हो जाता है"।
  2. स्टार्ट-अप पर धागे की संख्या तय की गई है। यह एक आवश्यकता नहीं है, लेकिन यह कार्यान्वयन को सरल बनाता है और मुझे नीचे दिए गए सरल विवरण में अंतरण विवरण छोड़ने की अनुमति देता है।
  3. "कार्यकर्ता धागे" को नियंत्रित करने वाली केवल एक "कार्यकर्ता प्रक्रिया" (लेकिन # 1 देखें) है। यह श्रमिकों के बीच रिकॉर्ड कैसे विभाजित होते हैं, इस बात से निपटने में आसान बनाता है।
  4. कुछ [अपरिवर्तनीय] "आईडी" कॉलम है जो "अच्छी तरह वितरित" है। यह आवश्यक है इसलिए खोज कार्यकर्ता को समान मात्रा में काम मिल जाए।
  5. कार्य "आदेश से बाहर" किया जा सकता है जब तक कि यह "अंततः किया गया" हो। साथ ही, श्रमिक हमेशा एक अलग कतार पर काम करने के कारण "100% पर" नहीं चल सकते हैं।

प्रत्येक थ्रेड को [0, thread_count) से एक अद्वितीय bucket मान असाइन करें। यदि कोई धागा मर जाता है/पुनरारंभ होता है तो वह वही बाल्टी लेगा जो इसे खाली करता है।

फिर, हर बार एक धागा की जरूरत है एक नया रिकार्ड की जरूरत है यह डेटाबेस से लायेगा:

SELECT * 
FROM record 
WHERE state = 'unprocessed' 
AND (id % $thread_count) = $bucket 
ORDER BY date 

वहाँ निश्चित रूप से अन्य पढ़ने बैच में "इस धागे कार्य" और भंडारण के बारे में मान्यताओं हो सकता है उन्हें स्थानीय रूप से। हालांकि, स्थानीय कतार प्रति थ्रेड (और इस प्रकार एक नए थ्रेड स्टार्टअप पर फिर से लोड हो जाएगी) और इस प्रकार यह केवल bucket के लिए जुड़े रिकॉर्ड से निपटने के लिए होगा।

जब थ्रेड समाप्त हो जाता है तो एक रिकॉर्ड को रिकॉर्ड करना उचित अलगाव स्तर और/या आशावादी समरूपता का उपयोग करके संसाधित किया जाना चाहिए और अगले रिकॉर्ड पर आगे बढ़ना चाहिए।

+0

धागे का प्रबंधन क्यों करें? टीपीएल उस पर इतना अच्छा है ... इसके अलावा, इसे डेटाबेस में कई राउंड-ट्रिप की आवश्यकता होती है जहां अन्यथा कोई भी करेगा। –

+0

@EricJ। मैं धागे के कार्यान्वयन को निर्दिष्ट करने से बचने की कोशिश कर रहा था। इस दृष्टिकोण का विचार कुछ संगत मूल्यों के आधार पर कार्यकर्ता धागे में रिकॉर्ड "शेर्ड" करना है, जो एक वितरित कैश की तरह है। –

+0

लेकिन यह निर्दिष्ट करता है कि कार्यान्वयन * समानांतर नहीं होगा। (प्रत्येक), क्योंकि दोनों थ्रेड लाइफसाइकिल को स्वचालित रूप से प्रबंधित करते हैं और आपकी दूसरी धारणा को पकड़ने के लिए मिश्रित नहीं होंगे। –

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