2015-09-10 40 views
14

मैं बहुत अमेज़न Kinesis के लिए नया हूँ तो शायद यह मेरी समझ में सिर्फ एक समस्या है, लेकिन AWS Lambda FAQ में यह कहते हैं:अमेज़न Kinesis और एडब्ल्यूएस लैम्ब्डा पुनर्प्रयास

अमेज़न Kinesis और DynamoDB भेजा रिकॉर्ड धाराओं आपके एडब्ल्यूएस लैम्ब्डा फ़ंक्शन को सख्ती से क्रमशः क्रमबद्ध किया जाता है। इसका मतलब यह है कि यदि आप एक ही शार्ड में दो रिकॉर्ड डालते हैं, तो लैम्ब्डा गारंटी देता है कि दूसरे रिकॉर्ड के साथ आपके लैम्ब्डा फ़ंक्शन को पहले रिकॉर्ड के साथ सफलतापूर्वक बुलाया जाएगा। यदि एक रिकॉर्ड समय के लिए आमंत्रण, थ्रॉटल किया गया है, या किसी भी अन्य त्रुटि का सामना कर रहा है, तो अगले रिकॉर्ड पर जाने से पहले लैम्ब्डा फिर से सफल हो जाएगा (या रिकॉर्ड 24 घंटे की समाप्ति तक पहुंच जाएगा)। विभिन्न shards में रिकॉर्ड के आदेश की गारंटी नहीं है, और प्रत्येक शार्ड की प्रसंस्करण समानांतर में होती है।

मेरा प्रश्न है, तो क्या होता है किसी कारण से कुछ विकृत डेटा एक निर्माता से एक ठीकरा पर डाला जाता है और लैम्ब्डा समारोह इसे बाहर उठाता अप यह त्रुटियों जब और फिर बस पुन: प्रयास लगातार रहती है? इसका मतलब है कि उस विशेष शार्ड की प्रक्रिया को त्रुटि के 24 घंटे के लिए अवरुद्ध कर दिया जाएगा।

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

उत्तर

23

इसे ओवरथिंक न करें, किनेसिस सिर्फ एक कतार है। अगले चरण में जाने के लिए आपको सफलतापूर्वक एक कतार (यानी कतार से पॉप) का उपभोग करना होगा। एक फीफो ढेर की तरह।

उपयुक्त तरीका होना चाहिए:

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

वैसे, यदि रिकॉर्ड की प्रसंस्करण 1 मिनट से अधिक समय लेती है, तो यह स्पष्ट है कि आप कुछ गलत कर रहे हैं। चूंकि किनेसिस प्रति सेकंड हजारों रिकॉर्ड को संभालने के लिए डिज़ाइन किया गया है, इसलिए आपको उनमें से प्रत्येक के लिए ऐसी लंबी नौकरियों को संसाधित करने की लक्जरी नहीं होनी चाहिए।

जो सवाल आप पूछ रहे हैं वह कतार प्रणाली की एक सामान्य समस्या है, जिसे कभी-कभी "जहरीला संदेश" कहा जाता है। सुरक्षित होने के लिए आपको उन्हें अपने व्यावसायिक तर्क में संभालना होगा।

http://www.cogin.com/articles/SurvivingPoisonMessages.php#PoisonMessages

+0

उचित लगता है लेकिन डायनेमो डीबी बिट के बारे में सिर्फ एक त्वरित सवाल है, मुझे स्थिति को कायम रखने की आवश्यकता क्यों है (मुझे लगता है कि आप अनुक्रम संख्या का मतलब है)? – Stefano

+0

क्योंकि जब आप "Kinesis उपभोक्ता अनुप्रयोग" नोड को रोकते हैं और बाद में शुरू करते हैं; आप अंतिम बिंदु से जारी रखने में सक्षम होना चाहिए। – az3

+0

आह हाँ, यह समझ में आता है। – Stefano

14

यह Kinesis में घटनाओं के प्रसंस्करण और मैं तुम्हें कुछ बिंदुओं "भ्रष्ट" डेटा के साथ इस तरह के मुद्दों को संभालने के लिए अपने लैम्ब्डा समारोह के निर्माण के लिए देने की कोशिश करता हूँ पर एक आम सवाल है। चूंकि यह आपके सिस्टम के अलग-अलग हिस्सों को किनेसिस स्ट्रीम और केनेसिस स्ट्रीम से पढ़ने वाले अन्य हिस्सों में लिखने का सबसे अच्छा अभ्यास है, इसलिए यह सामान्य है कि आपको ऐसी समस्याएं होंगी।

पहला, आपके पास ऐसी समस्याग्रस्त घटनाएं क्यों हैं?

अपनी घटनाओं को संसाधित करने के लिए किनेसिस का उपयोग करना एक जटिल प्रणाली को तोड़ने का एक अच्छा तरीका है जो फ्रंट एंड प्रोसेसिंग (अंतिम उपयोगकर्ताओं की सेवा), और साथ ही कोड/बैक-एंड प्रोसेसिंग (घटनाओं का विश्लेषण) दोनों कर रहा है, आपके सिस्टम के दो स्वतंत्र में। फ्रंट-एंड लोग अपने व्यापार पर ध्यान केंद्रित कर सकते हैं, जबकि बैक-एंड लोगों को फ्रंट एनाल में कोड परिवर्तनों को धक्का देने की आवश्यकता नहीं है, अगर वे अपने विश्लेषणात्मक उपयोग मामलों की सेवा करने के लिए कार्यक्षमता जोड़ना चाहते हैं। किनेसिस घटनाओं का एक बफर है जो दोनों सिंक्रनाइज़ेशन की आवश्यकता को तोड़ता है और व्यापार तर्क कोड को सरल बनाता है।

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

अब यह उन टीमों पर निर्भर है जो स्ट्रीम से पढ़ रहे हैं ताकि वे इस तरह की लचीली घटनाओं को कुशल तरीके से संसाधित कर सकें और हर बार ऐसा परिवर्तन हो रहा है। इसलिए, यह सामान्य होना चाहिए कि आपका लैम्ब्डा फ़ंक्शन उन घटनाओं को देखेगा जो इसे संसाधित नहीं कर सकते हैं, और "जहर-गोली" ऐसा दुर्लभ घटना नहीं है जैसा आप उम्मीद कर सकते हैं।

दूसरा, आप ऐसी समस्याग्रस्त घटनाओं को कैसे संभालेंगे?

आपका लैम्ब्डा फ़ंक्शन बैच प्रक्रियाओं की प्रक्रियाओं के लिए प्राप्त करेगा। कृपया ध्यान दें कि आपको घटनाओं को एक-एक करके नहीं मिलना चाहिए, बल्कि घटनाओं के बड़े बैचों में। यदि आपके बैच बहुत छोटे हैं, तो आप जल्दी ही स्ट्रीम पर बड़े झटके प्राप्त करेंगे।

प्रत्येक बैच के लिए आप घटनाओं पर पुन: प्रयास करेंगे, उन्हें संसाधित करेंगे और फिर बैच के अंतिम अनुक्रम-आईडी डायनेमो डीबी में चेक-पॉइंट देखेंगे। लैम्ब्डा के साथ स्वचालित रूप से (: http://docs.aws.amazon.com/lambda/latest/dg/walkthrough-kinesis-events-adminuser-create-test-function.html यहाँ और अधिक देखें): इनमें से अधिकांश चरणों कर रही है

console.log('Loading function'); 

exports.handler = function(event, context) { 
    console.log(JSON.stringify(event, null, 2)); 
    event.Records.forEach(function(record) { 
     // Kinesis data is base64 encoded so decode here 
     payload = new Buffer(record.kinesis.data, 'base64').toString('ascii'); 
     console.log('Decoded payload:', payload); 
    }); 
    context.succeed(); 
}; 

यह वही है, "खुश पथ" में हो रहा है, तो सभी घटनाओं किसी भी समस्या के बिना संसाधित कर रहे हैं। लेकिन अगर आपको बैच में कोई समस्या आती है और आप "" सफलता अधिसूचना वाले ईवेंट नहीं करते हैं, तो बैच विफल हो जाएगा और आपको बैच में सभी घटनाएं फिर से मिलेंगी।

अब आपको यह तय करने की आवश्यकता है कि प्रसंस्करण में विफलता का कारण क्या है।

  • अस्थाई समस्या (थ्रॉटलिंग, नेटवर्क समस्या ...) - यह एक दूसरे प्रतीक्षा करें और समय की एक जोड़ी के लिए पुन: प्रयास करने के लिए ठीक है। कई मामलों में समस्या स्वयं को हल कर देगी।

  • कभी-कभी समस्या (स्मृति से बाहर ...) - लैम्ब्डा फ़ंक्शन की स्मृति आवंटन को बढ़ाने या बैच आकार को कम करने के लिए सबसे अच्छा है। कई मामलों में इस तरह के संशोधन मुद्दे को हल करेंगे।

  • लगातार विफलता - इसका अर्थ है कि आप या तो समस्याग्रस्त घटना की अनदेखी (एक DLQ में रख - मृत अक्षर-पंक्ति) के लिए है कि या इसे संभाल करने के लिए अपने कोड को संशोधित।

समस्या आपके कोड में विफलता के प्रकार की पहचान करने और इसे अलग-अलग संभालने की समस्या है। आपको इसे पहचानने के लिए अपना लैम्ब्डा कोड लिखने की आवश्यकता है (उदाहरण के लिए अपवाद का प्रकार) और अलग-अलग प्रतिक्रिया दें।

आप कंसोल को ऐसी विफलताओं को लिखने और प्रासंगिक अलार्म बनाने के लिए क्लाउडवॉच के साथ एकीकरण का उपयोग कर सकते हैं। आप क्लाउडवॉच लॉग का उपयोग अपने "मृत-अक्षर-कतार" को लॉग करने के तरीके के रूप में भी कर सकते हैं और देख सकते हैं कि समस्या का स्रोत क्या है।

+1

बैच में होने वाली घटनाओं में से कुछ * सफल होने पर आप कैसे संभालेंगे, लेकिन अन्य विफल रहे? एक लैम्ब्डा पर विचार करें जो प्रत्येक ईवेंट के लिए एसईएस का उपयोग करके एक ईमेल भेजता है। मुझे 100 घटनाओं का बैच मिल सकता है, और पहले 20 ईमेल सही तरीके से भेज सकते हैं, लेकिन फिर एसईएस के पास शेष समय के लिए आउटेज है। मैं पहले 20 कार्यक्रमों की सफलता की रिपोर्ट करना चाहता हूं (ताकि मैं लोगों को स्पैम न करूं), लेकिन मैं बाद वाले 80 को पुनः प्रयास करना चाहता हूं। क्या यह संभव है? –

+0

डुप्लीकेट से बचने के लिए आप लुकअप कार्यक्षमता के साथ एक सूची प्रबंधित कर सकते हैं। आप ईमेल के रूप में कुंजी के साथ डायनेमोडीबी तालिका का उपयोग कर सकते हैं, और अंतिम ईमेल के मूल्य को भेजा जा सकता है। एक और आम समाधान ईमेल कुंजी के टीटीएल के साथ ElastiCache में Redis का उपयोग करना है। ईमेल भेजने से पहले, आप जांचते हैं कि पिछली बार उसे ईमेल कब भेजा गया था, और आप प्रत्येक सफल प्रेषण पर रिकॉर्ड अपडेट करते हैं। – Guy

+0

मुझे एक ही परिदृश्य @ कैम जैकसन का सामना करना पड़ रहा है। डायनेमो डीबी अब टीटीएल का समर्थन करता है जो इस –

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