2012-09-19 12 views
17

मैं जानना चाहता हूं कि मेरी डायनेमोड तालिका में कितनी वस्तुएं हैं। API मार्गदर्शिका से, एक ही रास्ता है इस प्रकार के रूप में यह एक scan उपयोग कर रहा है क्या करने के लिए:डायनेमोडीबी तालिका में आइटम की कुल संख्या कैसे प्राप्त कर सकता हूं?

<?php 
$dynamodb = new AmazonDynamoDB(); 

$scan_response = $dynamodb->scan(array(
    'TableName' => 'ProductCatalog' 
)); 

echo "Total number of items: ".count($scan_response->body->Items)."\n"; 

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

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

+0

DescribeTable का उपयोग करें, यहां विवरण: http://stackoverflow.com/a/37036989/3305145 – makinbacon

उत्तर

19

मैं डायनेमोडीबी तालिका में आइटमों की कुल संख्या प्राप्त करने के लिए तीन विकल्पों के बारे में सोच सकता हूं।

  1. पहला विकल्प स्कैन का उपयोग कर रहा है, लेकिन स्कैन समारोह अक्षम है और विशेष रूप से भारी पढ़ता है या उत्पादन तालिकाओं के साथ तालिकाओं के लिए, सामान्य एक बुरा व्यवहार में है।

  2. दूसरा विकल्प क्या अथर्ववेद से उल्लेख किया गया है:

    A better solution that comes to my mind is to maintain the total number of item counts for such tables in a separate table, where each item will have Table name as it's hash key and total number of items in that table as it's non-key attribute. You can then keep this Table possibly named "TotalNumberOfItemsPerTable" updated by making atomic update operations to increment/decrement the total item count for a particular table.

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

  3. सबसे आसान समाधान DescribeTable है जो ItemCount देता है। एकमात्र मुद्दा यह है कि गिनती अद्यतित नहीं है। गिनती हर 6 घंटों में अपडेट की जाती है।

http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DescribeTable.html

5

अहा, वहाँ है scan एपीआई में एक Count विकल्प, http://docs.amazonwebservices.com/AWSSDKforPHP/latest/#m=AmazonDynamoDB/scan

<?php 
$dynamodb = new DynamoMetadata(); 

$scan_response = $dynamodb->scan(array(
    'TableName' => 'ProductCatalog' 
    'Count'  => true, 
)); 

echo "Count: ".$scan_response->body->Count."\n"; 
+1

जैसा कि जेरेमी लिंडब्लॉम द्वारा उनके उत्तर में बताया गया है और इसके द्वारा प्रमाणित: http://docs.aws.amazon.com/amazondynamodb/ नवीनतम/developerguide/QueryAndScan.html सुनिश्चित करें कि आप 1 एमबी सीमा का ख्याल रखते हैं, यानी आपकी तालिका का आकार 1 एमबी से अधिक होने पर आंशिक गिनती आंशिक गणना हो सकती है। – Atharva

+0

जब भी मैं उपर्युक्त कोड चलाता हूं, मुझे निम्न मिलता है: 'घातक त्रुटि: कक्षा' डायनेमो मेटाडाटा 'सी: \ उपयोगकर्ता \ लेनोवो \ xampp \ public_html \ upload_file.php पंक्ति 73' पर नहीं मिली है। इसे हल करने के लिए क्या करना है? सीमा का उल्लेख करने के लिए –

10

देख Count विकल्प निश्चित रूप से आप क्या चाहते है, लेकिन आप भी ध्यान में रखना हो सकता है एक या अधिक " पृष्ठ "के परिणामस्वरूप आपके स्कैन परिणाम में। स्कैन ऑपरेशन केवल एक समय में आपकी तालिका में 1 एमबी डेटा स्कैन करता है, इसलिए परिणाम में Count का मान केवल तालिका के पहले 1 एमबी की गणना को प्रतिबिंबित करने जा रहा है। परिणामस्वरूप LastEvaluatedKey के मूल्य का उपयोग करके आपको बाद के अनुरोध करने की आवश्यकता होगी (यदि यह वहां है)।

<?php 

$dynamo_db = new AmazonDynamoDB(); 

$total = 0; 
$start_key = null; 
$params = array(
    'TableName' => 'my-table', 
    'Count'  => true 
); 

do { 
    if ($start_key) { 
     $params['ExclusiveStartKey'] = $start_key->getArrayCopy(); 
    } 

    $response = $dynamo_db->scan($params); 

    if ($response->isOK()) { 
     $total += (string) $response->body->Count; 

     if ($response->body->LastEvaluatedKey) { 
      $start_key = $response->body->LastEvaluatedKey->to_array(); 
     } else { 
      $start_key = null; 
     } 
    } 
} while ($start_key); 

echo "Count: {$total}"; 
+1

+1 –

2

एक अनुमानित आइटम गिनती मूल्य (माना जाता है कि हर छह घंटे में अपडेट) DynamoDB के लिए एडब्ल्यूएस कंसोल में उपलब्ध है: यहाँ ऐसा ही कुछ करने के लिए कुछ नमूना कोड है। बस तालिका का चयन करें और विवरण टैब के नीचे देखें, अंतिम प्रविष्टि आइटम गणना है। यदि यह आपके लिए काम करता है, तो आप गिनती करने के लिए अपनी टेबल थ्रूपुट का उपभोग करने से बच सकते हैं।

3

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

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

थ्रॉटलिंग या 1 एमबी सीमा का कोई मुद्दा नहीं।

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

0

यह अब खंड 'टेबल विवरण', क्षेत्र 'आइटम गिनती' के तहत एडब्ल्यूएस तालिका अवलोकन स्क्रीन में उपलब्ध है। ऐसा लगता है कि यह DescribeTable का एक डंप है, और नोट करता है कि यह लगभग हर छह घंटे अद्यतन किया गया है।

0

यहाँ मैं कैसे मेरे करोड़ रिकॉर्ड DynamoDB मेज पर ठीक वही आइटम गिनती प्राप्त होते हैं:

छत्ता>

set dynamodb.throughput.write.percent = 1; 
set dynamodb.throughput.read.percent = 1; 
set hive.execution.engine = mr; 
set mapreduce.reduce.speculative=false; 
set mapreduce.map.speculative=false; 

CREATE EXTERNAL TABLE dynamodb_table (`ID` STRING,`DateTime` STRING,`ReportedbyName` STRING,`ReportedbySurName` STRING,`Company` STRING,`Position` STRING,`Country` STRING,`MailDomain` STRING) STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' TBLPROPERTIES ("dynamodb.table.name" = "BillionData", "dynamodb.column.mapping" = "ID:ID,DateTime:DateTime,ReportedbyName:ReportedbyName,ReportedbySurName:ReportedbySurName,Company:Company,Position:Position,Country:Country,MailDomain:MailDomain"); 

SELECT count(*) FROM dynamodb_table; 

* आप एक ईएमआर क्लस्टर, जो हाइव और DynamoDB रिकॉर्ड हैंडलर के साथ स्थापित आता है होना चाहिए। * इस कमांड के साथ, हाइव पर डायनेमो डीबी हैंडलर कई मैप्रिडस मैपर (एकेए वर्कर्स) के साथ "पैरालेल स्कैन" मुद्दों को गिनने के लिए अलग-अलग विभाजनों पर काम कर रहा है। यह सामान्य स्कैन से अधिक कुशल और तेज होगा।
* आपको कुछ समय के लिए पढ़ने की क्षमता बहुत अधिक पढ़ने के लिए तैयार होना चाहिए। * एक सभ्य आकार (20 नोड) क्लस्टर पर, 10000 आरसीयू के साथ, अरब रिकॉर्ड पर गिनती करने में 15 मिनट लग गए।
* इस अवधि के दौरान इस डीडीबी तालिका पर नए लिखने से गिनती असंगत हो जाएगी।

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