2016-03-12 13 views
13

मुझे डायनामो डीबी तालिका में डेटा के साथ सिंक में आईओएस ऐप पर स्थानीय डेटा रखने की जरूरत है।कोई स्पष्ट हैश कुंजी के साथ दिनांक (रेंज कुंजी) द्वारा DynamoDB से कैसे क्वेरी करें?

  • id (UUID)
  • lastModifiedAt (टाइमस्टैम्प)
  • name
  • latitude
  • : DynamoDB तालिका ~ 2K पंक्तियाँ, केवल एक हैश कुंजी (id) के साथ, और निम्न विशेषताओं है longitude

मैं वर्तमान में स्कैनिंग कर रहा हूं और lastModifiedAt द्वारा फ़िल्टरिंग, जहां lastModifiedAt ऐप की आखिरी रीफ्रेश तिथि से अधिक है, लेकिन मुझे लगता है कि यह महंगा हो जाएगा।

सर्वोत्तम answer मुझे लगता है कि lastModifiedAt के साथ वैश्विक माध्यमिक इंडेक्स को श्रेणी के रूप में जोड़ना है, लेकिन जीएसआई के लिए कोई स्पष्ट हैश कुंजी नहीं है।

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

उत्तर

6

जबकि D.Shawley के जवाब सही दिशा में मुझे बिंदु मदद की, यह दो एक जीएसआई के लिए विचार याद किया:

  1. हैश + रेंज अद्वितीय होने चाहिए, फिर भी दिन + टाइमस्टैम्प (अपने दृष्टिकोण अनुशंसित) होगा जरूरी नहीं कि अद्वितीय हो।
  2. केवल हैश के रूप में उपयोग करके, मुझे अंतिम ताज़ा तिथि (जो महीनों या साल पहले हो सकता है) के बाद से प्रत्येक दिन के परिणाम प्राप्त करने के लिए बड़ी संख्या में प्रश्नों का उपयोग करना होगा।

    • YearMonth के रूप में हैश कुंजी के साथ एक वैश्विक माध्यमिक सूचकांक (जीएसआई) बनाया गया (जैसे, 201508) और सीमा id
    • क्वेरी के रूप में:

जैसे, यहाँ दृष्टिकोण मैं ले लिया है जीएसआई कई बार, अंतिम ताज़ा तारीख के बाद से प्रत्येक महीने के लिए एक प्रश्न। प्रश्न lastModifiedAt > [given timestamp] के साथ भी फ़िल्टर किए गए हैं।

+0

कृपया अतिरिक्त विचारों के लिए मेरा उत्तर देखें। सादर। – bsd

+3

मेरे पास आपके जैसी ही स्थिति है और एक ही समाधान में आया है। इसे यहां पोस्ट करने के लिए धन्यवाद। एक टिप्पणी: जीएसआई को अद्वितीय होने की आवश्यकता नहीं है: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GuidelinesForGSI.html – ustroetz

2

आप हैश के रूप में टाइमस्टैम्प के "दिन" हिस्से का उपयोग कर सकते हैं और सीमा के रूप में पूर्ण टाइमस्टैम्प का उपयोग कर सकते हैं।

+0

हैश कुंजी के लिए 'eq' स्थिति की आवश्यकता होती है, तो क्या मुझे ऐप के आखिरी रीफ्रेश के बाद से हर दिन एक प्रश्न करने की आवश्यकता होगी? (ऐप स्थानीय रूप से 'lastRefreshedAt' टाइमस्टैम्प स्टोर करता है)। ऐसा लगता है कि स्कैन से अधिक महंगा होगा। –

+0

शायद मैं टाइमशैम्प के "साल-महीने" हिस्से को हैश कुंजी के रूप में स्टोर कर सकता हूं? इससे "प्रश्न" भाग का उपयोग करने की तुलना में, एक वर्ष में पहली बार अपना ऐप खोलने पर आवश्यक प्रश्नों की संख्या में काफी कमी आएगी। उस बिंदु पर, ऐसा लगता है कि रेंज कुंजी अप्रासंगिक हो जाती है, क्योंकि हैश कुंजी द्वारा पूछताछ उन सभी वस्तुओं को लाएगी जिन्हें 'lastRefreshedAt' के बाद से अपडेट किया गया है। –

17

हालांकि एक Global Secondary Index अपनी आवश्यकताओं को फिट करने के लिए लगता है, किसी भी प्रयास को अपने Hash Key का हिस्सा सबसे अधिक संभावना पैदा करेगा क्या "के रूप में गर्म विभाजन" है, जो अत्यंत अवांछनीय है के रूप में जाना जाता है timestamp संबंधित जानकारी शामिल करने के लिए।

असमान पहुंच तब होगी जब सबसे हालिया वस्तुओं को पुराने लोगों की तुलना में अधिक आवृत्ति के साथ पुनर्प्राप्त किया जा रहा है। इससे न केवल आपके प्रदर्शन पर असर पड़ेगा बल्कि आपके समाधान को कम लागत प्रभावी भी बनाया जाएगा।, अगर एक मेज भारी पहुँचा विभाजन कुंजी मान, संभवतः एक भी बहुत बड़ी मात्रा में प्रयोग विभाजन कुंजी मूल्य का एक बहुत छोटी संख्या है,

उदाहरण के लिए यातायात का अनुरोध:

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

क्या कहा गया है के आधार पर, id अपने Hash Key (उर्फ। Partition Key) के लिए एक अच्छा विकल्प के रूप में जीएसआई चाबियाँ विभाजन के रूप में एक ही तरीके से काम करते हैं जहाँ तक, मुझे लगता है कि परिवर्तन नहीं होगा होने के लिए वास्तव में लगता है। एक अलग नोट के रूप में, जब आप पूरे Primary Key प्रदान करके अपना डेटा पुनर्प्राप्त करते हैं तो प्रदर्शन अत्यधिक अनुकूलित होता है, इसलिए हमें एक समाधान खोजने का प्रयास करना चाहिए जो कि जब भी संभव हो।

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

ए। आपके दैनिक अपडेट निम्नलिखित नामकरण सम्मेलन के साथ तालिकाओं में संग्रहीत किए जा सकते हैं: updates_DDMM

बी। updates_DDMM टेबल में केवल id (अन्य तालिका की हैश कुंजी)

अब कहें कि नवीनतम ऐप रीफ्रेश तिथि 2 दिन पहले (04/07/16) थी और आपको हाल के रिकॉर्ड प्राप्त करने होंगे , तो आपको इसकी आवश्यकता होगी:

i। सभी हैश कुंजी प्राप्त करने के लिए तालिका updates_0504 और updates_0604 स्कैन करें।

ii। अंत में सभी प्राप्त हैश कुंजी के साथ BatchGetItem सबमिट करके मुख्य तालिका (लेट/एलएनजी, नाम, आदि युक्त) से रिकॉर्ड्स प्राप्त करें।

BatchGetItem सुपर फास्ट है और कोई अन्य ऑपरेशन की तरह काम करेगा।

कोई तर्क दे सकता है कि अतिरिक्त टेबल बनाने से आपके समग्र समाधान में लागत बढ़ जाएगी ... अच्छी तरह से, GSI के साथ आप अनिवार्य रूप से अपनी तालिका को डुप्लिकेट कर रहे हैं (यदि आप सभी फ़ील्ड पेश कर रहे हैं) और सभी ~ 2k रिकॉर्ड्स के लिए अतिरिक्त लागत जोड़ना , उन्हें हाल ही में अद्यतन या नहीं किया जा रहा ...

यह इस तरह काउंटर सहज ज्ञान युक्त बनाने टेबल लगता है, लेकिन यह वास्तव में एक सबसे अच्छा अभ्यास जब समय श्रृंखला डेटा के साथ काम कर (एडब्ल्यूएस DynamoDB प्रलेखन से) है:

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

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

स्रोत: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GuidelinesForTables.html

मुझे आशा है कि मदद करता है। सादर।

+1

यह एक अच्छा सुझाव है। इस पर विचारशीलता के लिए धन्यवाद। यह मुझे आश्चर्यचकित करता है कि आरडीएस एक बेहतर समाधान है, समय-आधारित डेटा तक पहुंचने की जटिलताओं को देखते हुए। –

+1

यह भी सावधान रहें कि बैचगेटइटम 100 आइटम तक सीमित है। –

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