2012-04-02 5 views
7

क्या GAE पर कार्य पंक्तियों के साथ FIFO (पहले, पहले बाहर) व्यवहार को आश्वस्त करने का कोई तरीका है?क्या GAE पर कार्य पंक्तियों के साथ FIFO (पहले, पहले बाहर) व्यवहार को आश्वस्त करने का कोई तरीका है?

जीएई दस्तावेज़ीकरण का कहना है कि फीफो उन कारकों में से एक है जो कार्य निष्पादन आदेश को प्रभावित करते हैं, लेकिन एक ही दस्तावेज कहता है कि "सिस्टम का शेड्यूलिंग कतार के सिर पर नए कार्यों को 'कूद' सकता है और मैंने इस व्यवहार की पुष्टि की है एक परीक्षा। प्रभाव: मेरी घटनाओं को क्रम से संसाधित किया जा रहा है।

डॉक्स का कहना है:

https://developers.google.com/appengine/docs/java/taskqueue/overview-push

जिस क्रम में कार्य क्रियान्वित कर रहे हैं निर्भर करता है कई कारकों पर:

कतार में कार्य की स्थिति। ऐप इंजन फीफो> (पहले, पहले आउट) ऑर्डर के आधार पर कार्यों को संसाधित करने का प्रयास करता है। सामान्य रूप से, कतार के अंत में कार्य को सम्मिलित किया जाता है, और कतार के सिर से निष्पादित किया जाता है।

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

कार्य की ईटामिलिस संपत्ति का मूल्य। यह गुण निर्दिष्ट करता है कि कोई कार्य निष्पादित हो सके। पुश कार्यों को संसाधित करने के लिए निर्दिष्ट ईटीए के बाद ऐप इंजन हमेशा तक प्रतीक्षा करता है।

कार्य की उलटी गिनती Millis संपत्ति का मूल्य। यह कार्य किसी कार्य को निष्पादित करने से पहले प्रतीक्षा करने के लिए न्यूनतम सेकंड की संख्या निर्दिष्ट करता है। उलटी गिनती और ईटा पारस्परिक रूप से अनन्य हैं; यदि आप एक निर्दिष्ट करते हैं, तो दूसरे को निर्दिष्ट न करें।

मुझे क्या करना है? मेरे उपयोग के मामले में, मैं वाहनों से आने वाले 1-2 मिलियन कार्यक्रम/दिन संसाधित करूंगा। इन घटनाओं को किसी भी अंतराल (1 सेकंड, 1 मिनट या 1 घंटा) पर भेजा जा सकता है। घटना प्रसंस्करण के आदेश को आश्वस्त किया जाना चाहिए। मुझे टाइमस्टैम्प ऑर्डर द्वारा प्रक्रिया की आवश्यकता है, जो वाहन के अंदर एक एम्बेडेड डिवाइस पर उत्पन्न होता है।

मेरे पास अब क्या है?

  1. एक रेस्ट सर्वलेट जिसे उपभोक्ता द्वारा बुलाया जाता है और एक कार्य बनाता है (ईवेंट डेटा पेलोड पर है)।

  2. इस के बाद, एक कार्यकर्ता सर्वलेट इस कार्य हो और:

    • deserialize ईवेंट डेटा;

    • डेटास्टोर पर ईवेंट डालें;

    • डेटास्टोर पर वाहन अपडेट करें।

तो, फिर से, वहाँ किसी भी तरह से सिर्फ फीफो व्यवहार को आश्वस्त करने के लिए है? या यह पाने के लिए मैं इस समाधान को कैसे सुधार सकता हूं?

+1

आपको सख्त फीफो की आवश्यकता क्यों है? याद रखें कि ऑर्डर-ऑफ-इवेंट्स एक वितरित प्रणाली में अस्पष्ट है - यहां तक ​​कि यह बताते हुए कि कई लगभग एक साथ अनुरोध किए गए पहले मुश्किल (और अक्सर व्यर्थ) होते हैं जब आपके फ्रंटेंड और बैकएंड कई मशीनों में वितरित किए जाते हैं। अंत परिणाम के रूप में, आप क्या हासिल करने की कोशिश कर रहे हैं? –

+0

हम सार्वजनिक बसों को ट्रैक करते हैं, इसलिए हमें यह जानना होगा कि यह बस स्टॉप में कब रुक गया था, या जब यह एक यात्रा खोला गया था, या जब यह वेग सीमा से अधिक हो गया था। समस्या यह है कि कुछ घटनाएं पिछले कार्यक्रमों से संबंधित हैं क्योंकि हम राज्य प्रबंधन भी करते हैं। उदाहरण के लिए: यदि कोई पिछली घटना में 'बंद यात्रा' दर्ज की जाती है तो बस केवल 'एक यात्रा खोल सकती है'। तो, आप कल्पना कर सकते हैं कि क्या हो सकता है यदि मुझे इन घटनाओं को क्रम से बाहर निकाला जा सके ... –

+0

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

उत्तर

3

ठीक है। इस तरह मैंने इसे किया है।

1) Rest servlet that is called from the consumer: 

    If Event sequence doesn't match Vehicle sequence (from datastore) 

     Creates a task on a "wait" queue to call me again 

    else 

     State validation 

     Creates a task on the "regular" queue (Event data is on payload). 


2) A worker servlet gets the task from the "regular" queue, and so on... (same pseudo code) 

इस तरह से मैं घटनाओं को खोए बिना डेटा रखरखाव करने के लिए "नियमित" कतार को रोक सकता हूं।

आपके उत्तरों के लिए धन्यवाद। मेरा समाधान उनमें से एक मिश्रण है।

3

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

+0

समय महत्वपूर्ण है। यह बताना भूल गया कि मुझे टाइमस्टैम्प ऑर्डर द्वारा प्रक्रिया की आवश्यकता है, जो वाहन के अंदर एक एम्बेडेड डिवाइस पर उत्पन्न होता है। –

0

आप डेटास्टोर में एक पंक्ति में काम करने के लिए काम कर सकते हैं और फिर उस टाइमस्टैम्प द्वारा कार्य कार्यों को ला सकते हैं, लेकिन यदि आपके कार्य बहुत जल्दी बनाए जा रहे हैं तो आप विलंबता के मुद्दों में भाग लेंगे।

0

अपने आप को जवाब नहीं पता, लेकिन यह संभव हो सकता है कि एक स्थगित फ़ंक्शन का उपयोग करके लगाए गए कार्यों को सबमिट किए गए क्रम में निष्पादित किया जा सके। जवाब देने के लिए आपको जी से एक इंजीनियर की आवश्यकता होगी। सुझाए गए कतारों को एक अच्छा विकल्प प्रतीत होता है, साथ ही यह आपको अपने put() s को बैच करने पर विचार करने की अनुमति देगा।

sharded काउंटर के बारे में एक नोट: वे monotonically बढ़ती आईडी की संभावना में वृद्धि, लेकिन उनकी गारंटी नहीं है।

+0

स्थगित कार्य कतार का उपयोग करता है। –

+0

ठीक है, बस यह नहीं पता था कि एक स्थगित कार्य बनाम मानक enqueueing से कतार में प्रवेश कार्यों के बारे में कुछ जादू हो सकता है। उत्तर की तरह लगता है "नहीं" जो मैं अनुमान लगाता हूं। – stevep

4

आप तीन अलग-अलग चरणों के साथ इस दृष्टिकोण की जरूरत है:

  1. एक Sharding Counter लागू एक होगा- बढ़ती ID उत्पन्न करने के लिए। जितना अधिक मैं से Google के सर्वर को कार्य आदेश इंगित करने के लिए उपयोग करना चाहता हूं, ऐसा लगता है कि GAE सर्वर के बीच टाइमस्टैम्प आपकी आवश्यकता से अधिक भिन्न हो सकता है।

  2. Push Queue के बजाय अपने कार्यों को Pull Queue पर जोड़ें। जब अपना TaskOption बनाते हैं, तो tag के रूप में चरण # 1 से प्राप्त ID जोड़ें। कार्य जोड़ने के बाद, अपने डेटास्टोर पर ID स्टोर करें।

  3. Pull Queue से अपने कार्यकर्ता servlet lease Tasks by a certain tag है। डेटास्टोर को जल्द से जल्द प्राप्त करने के लिए क्वेरी करें, और ID पट्टा tag के रूप में उपयोग करें। इस तरह, आप अपने कार्य कतार के लिए फीफो व्यवहार का अनुकरण कर सकते हैं।

के बाद आप अपने संसाधन समाप्त होने पर, अपने डेटास्टोर से ID हटा सकते हैं और भी अपने Pull Queue से Task नष्ट करने के लिए मत भूलना। साथ ही, मैं आपको बैकएंड पर अपनी कार्य खपत चलाने की सलाह दूंगा।

अद्यतन: निक जॉनसन और मैगागार्ड द्वारा नोट किया गया है, चरण # 1 में शेरिंग एक monotonically बढ़ती आईडी उत्पन्न करने के लिए व्यवहार्य प्रतीत नहीं होता है, और आईडी के अन्य स्रोतों की आवश्यकता होगी। मुझे याद है कि आप अपने वाहनों द्वारा उत्पन्न टाइमस्टैम्प का उपयोग कर रहे थे, क्या यह एक monotonically बढ़ती आईडी के बदले इसका उपयोग करना संभव होगा?

रास्ता आईडी जेनरेट करने के बावजूद, मूल विचार डेटासंग्रह की क्वेरी तंत्र का उपयोग Tasks की एक फीफो आदेश का निर्माण करने के लिए, और TaskQueue से विशेष कार्य को खींचने के लिए काम Tag उपयोग करने के लिए है।

हालांकि, एक चेतावनी है। उच्च-प्रतिकृति डेटास्टोर पर अंतिम स्थिरता पढ़ने नीति के कारण, यदि आप अपने डेटास्टोर के रूप में एचआरडी चुनते हैं (और आपको, एम/एस को 4 अप्रैल, 2012 के रूप में बहिष्कृत किया जाना चाहिए), तो क्वेरी द्वारा वापस किए गए कुछ पुराने डेटा हो सकते हैं चरण 2।

+0

क्या शर्मीली काउंटर का उपयोग करके एकान्त रूप से बढ़ती आय बनाने के लिए वास्तव में संभव है? मैंने सोचा नहीं - निम्न स्तर एपी डेटास्टोर में आईडी आवंटित करने के लिए कार्य आईडी उत्पन्न कर सकता है लेकिन शायद मुझे सख्त आदेश में नहीं होना चाहिए। – mjaggard

+0

@mjaggard: धन्यवाद, लेकिन मुझे पूरा यकीन नहीं है कि मैं समझता हूं कि आपका क्या मतलब है .. दाढ़ी वाले काउंटर निम्न स्तर डेटास्टोर से जेनरेट आईडी फ़ंक्शन का उपयोग नहीं करते हैं। असल में, हम वह हैं जो खुद काउंटरों को बढ़ाते हैं, लेकिन हम लेखन विवाद को कम करने के लिए कई इकाइयों पर "काउंटर बाल्टी" फैलाते हैं। इस प्रकार, काउंटर monotonically बढ़ रहा होगा। कृपया cmiiw, ज़ाहिर है। –

+1

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

0

इसे संभालने का सबसे अच्छा तरीका, वितरित तरीका या "ऐप इंजन तरीका" शायद आपके टाइमगैम्प के साथ काम करने के लिए आपके एल्गोरिदम और डेटा संग्रह को संशोधित करने के लिए है, जो कार्यों के मनमाने ढंग से क्रमबद्ध करने की इजाजत देता है।

मान लिया जाये कि यह संभव है या बहुत मुश्किल नहीं है, आप इस प्रकार अपने एल्गोरिथ्म को संशोधित कर सकते हैं:

  1. जब कार्य बनाते समय एक साथ पेलोड पर लेकिन डेटासंग्रह में डेटा डाल नहीं है, एक वस्तु के रूप में टाइमस्टैम्प पर ऑर्डर करना और जो भी इकाई आप अपडेट करने का प्रयास कर रहे हैं उसकी एक बच्चे इकाई के रूप में संग्रहीत (वाहन?)। टाइमस्टैम्प क्लाइंट से, सर्वर पर नहीं, उसी ऑर्डरिंग की गारंटी के लिए आना चाहिए।

  2. एक सामान्य कार्य चलाता है जो पहले टाइमस्टैम्प के लिए डेटा लाता है, इसे संसाधित करता है, और उसके बाद लेनदेन के अंदर इसे हटा देता है।

0

इस धागे के बाद, मैं स्पष्ट नहीं हूं कि सख्त फीफो आवश्यकता सभी लेनदेन के लिए या प्रति वाहन आधार पर है या नहीं। लेटर के पास बनाम पूर्व विकल्प हैं।

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