2012-09-19 10 views
17

Voglio sapere quanti oggetti sono nella mia tabella dynamodb. Dalla guida API, un modo per farlo utilizza un scan come segue:Come posso ottenere il numero totale di elementi in una tabella DynamoDB?

<?php 
$dynamodb = new AmazonDynamoDB(); 

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

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

Tuttavia, questo deve recuperare tutti gli elementi e memorizzarli in una matrice in memoria che non è fattibile in molti casi avrei presumere. C'è un modo per ottenere il conteggio totale degli oggetti in modo più efficiente?

Questi dati non sono disponibili nella console Web AWS Dynamo, che ho già controllato. (all'inizio sembra che sia mostrato accanto ai pulsanti di impaginazione, ma risulta che la cifra aumenta man mano che si passa alla pagina successiva degli elementi).

+0

Usa DescribeTable, dettagli qui: http://stackoverflow.com/a/37036989/3305145 – makinbacon

risposta

19

Posso pensare a tre opzioni per ottenere il numero totale di elementi in una tabella DynamoDB.

  1. La prima opzione utilizza la scansione, ma la funzione di scansione è inefficiente ed è in generale una cattiva pratica, in particolare per le tabelle con letture pesante o tabelle di produzione.

  2. La seconda opzione è quello che è stato menzione per Atharva:

    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.

    L'unico problema è che le operazioni di incremento non sono idempotente. Quindi se una scrittura fallisce o scrivi più di una volta questo si rifletterà nel conteggio. Se hai bisogno di precisione in virgola mobile, usa invece un aggiornamento condizionale.

  3. La soluzione più semplice è DescribeTable che restituisce ItemCount. L'unico problema è che il conteggio non è aggiornato. Il conteggio viene aggiornato ogni 6 ore.

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

5

Aha, v'è un'opzione di Count nel scan API, vedi 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

Come menzionato da Jeremy Lindblom nella sua risposta ed evidenziato da questo: http://docs.aws.amazon.com/amazondynamodb/ latest/developerguide/QueryAndScan.html assicurati di occuparti del limite di 1 MB, ovvero il conteggio restituito può essere un conteggio parziale se la dimensione della tabella è superiore a 1 MB. – Atharva

+0

Ogni volta che eseguo il codice sopra riportato, viene visualizzato quanto segue: 'Errore irreversibile: Classe 'DynamoMetadata' non trovata in C: \ Utenti \ Lenovo \ xampp \ public_html \ upload_file.php sulla riga 73'. Cosa fare per risolverlo? –

10

L'opzione Count è sicuramente quello che si vuole, ma si deve anche tener conto che ci possono essere uno o più " pagina "dei risultati nel risultato della scansione. L'operazione di scansione scansiona solo 1 MB di dati nella tabella alla volta, quindi il valore di Count nel risultato rifletterà solo il conteggio del primo 1 MB della tabella. Sarà necessario effettuare richieste successive utilizzando il valore di LastEvaluatedKey nel risultato (se è presente). Ecco alcuni esempi di codice per fare qualcosa di simile:

<?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 per aver menzionato il limite –

2

Un valore di conteggio voce approssimativa (presumibilmente aggiornato ogni sei ore) è disponibile nella console AWS per DynamoDB. Basta selezionare la tabella e guardare sotto la scheda Dettagli, l'ultima voce è Conteggio articoli. Se questo funziona per te, puoi evitare di consumare il throughput della tua tabella per fare il conteggio.

3

Se si è interessati all'uso del numero totale di elementi in una tabella nella logica dell'applicazione, significa che si sta eseguendo la ricerca dei conteggi totali molto frequentemente. Ora un modo per ottenere questo è usando l'operazione di scansione. Ma ricorda che l'operazione di scansione analizza letteralmente l'intera tabella e quindi consuma molto throughput, quindi tutte le operazioni di query riceveranno Exception Throttled in quella durata. E anche considerando il fatto che la scansione limiterà il conteggio risultante per dimensione di 1 MB, sarà necessario effettuare ripetute operazioni di scansione per ottenere il numero effettivo di elementi se la tabella è molto grande. Ciò richiederà di scrivere una logica di query personalizzata e gestire l'inevitabile limitazione nelle operazioni di query.

Una soluzione migliore che mi viene in mente è mantenere il numero totale di conteggi di articoli per tali tabelle in una tabella separata, in cui ogni elemento avrà il nome della tabella come la sua chiave hash e il numero totale di elementi in quella tabella poiché è attributo non chiave. È quindi possibile mantenere questa tabella possibilmente denominata "TotalNumberOfItemsPerTable" aggiornata eseguendo operazioni di aggiornamento atomico per incrementare/decrementare il numero totale di elementi per una determinata tabella.

Nessun problema di limitazione o limite di 1 MB.

Inoltre, è possibile estendere questo concetto a ulteriore granularità, ad esempio per mantenere il numero totale di elementi corrispondenti a una chiave hash o qualsiasi criterio arbitrario che è possibile codificare in forma stringa per creare una voce nella tabella denominata qualcosa come " TotalNumberOfItemsInSomeCollection "o" TotalNumberOfItemsMatchingSomeCriteria ". Queste tabelle possono quindi contenere voci per il numero di articoli per tabella, per collezione o articoli corrispondenti ad alcuni criteri.

0

Questo è ora disponibile nella pagina panoramica tavolo AWS nella sezione 'Tabella dei dettagli', campo 'Numero di elementi'. Sembra essere solo una discarica di DescribeTable e osserva che è aggiornato approssimativamente ogni sei ore.

0

Ecco come ottengo l'esatto conteggio degli elementi sul mio miliardo di record tabella DynamoDB:

alveare>

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; 

* Si dovrebbe avere un cluster EMR, che viene installato con Hive e DynamoDB registrare Handler. * Con questo comando, il gestore DynamoDB sull'alveare emette "SCANSIONI PARALLELE" con più mapper Mapreduce (AKA Workers) che lavorano su diverse partizioni per ottenere il conteggio. Questo sarà molto più efficiente e più veloce delle normali scansioni.
* Devi essere disposto a sbalzare capacità di lettura molto alta per un certo periodo di tempo. * Su un cluster di 20 nodi di dimensioni decenti, con 10000 RCU ci sono voluti 15 minuti per contare su miliardi di record.
* Le nuove scritture su questa tabella DDB durante questo periodo renderanno il conteggio incoerente.

Problemi correlati