2012-09-19 26 views
17

Chcę wiedzieć, ile elementów znajduje się w mojej tabeli dynamodb. Od przewodnika API, jednym ze sposobów na to jest za pomocą scan następująco:Jak mogę uzyskać całkowitą liczbę przedmiotów w tabeli DynamoDB?

<?php 
$dynamodb = new AmazonDynamoDB(); 

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

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

Jednak ta musi sprowadzić wszystkie przedmioty i przechowywać je w tablicy w pamięci, które nie jest możliwe w większości przypadków bym przypuszczać. Czy istnieje sposób na wydajniejsze liczenie łącznych przedmiotów?

Dane te nie są dostępne w konsoli internetowej AWS Dynamo, już sprawdziłem. (na początku wygląda na to, że jest wyświetlany obok przycisków stronicowania, ale okazuje się, że liczba rośnie w miarę przechodzenia do następnej strony pozycji).

+0

Użyj DescribeTable, szczegóły tutaj: http://stackoverflow.com/a/37036989/3305145 – makinbacon

Odpowiedz

19

Mogę wymyślić trzy opcje, aby uzyskać całkowitą liczbę pozycji w tabeli DynamoDB.

  1. Pierwszą opcją jest użycie skanowanie, ale funkcja skanowania jest nieefektywne i jest na ogół złe praktyki, zwłaszcza dla tabel z ciężkiego odczytuje lub stoły produkcyjne.

  2. Drugą opcją jest to, co było wzmianki o Atharwa:

    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.

    Jedynym problemem jest to, że operacje inkrementacji nie idempotent. Więc jeśli zapis nie powiedzie się lub napiszesz więcej niż raz, zostanie to odzwierciedlone w zliczeniu. Jeśli potrzebujesz dokładności typu pin-point, użyj zamiast tego aktualizacji warunkowej.

  3. Najprostszym rozwiązaniem jest DescribeTable, która zwraca ItemCount. Jedynym problemem jest to, że liczba nie jest aktualna. Liczba jest aktualizowana co 6 godzin.

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

5

Aha, istnieje opcja w scan API Count patrz 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

Jak wspomniano przez Jeremy'ego Lindbloma w jego odpowiedzi i o czym świadczy: http://docs.aws.amazon.com/amazdzieńamodb/ latest/developerguide/QueryAndScan.html upewnij się, że dbasz o limit 1 MB, tzn. liczba zwrócona może być częściową liczbą, jeśli Twój rozmiar tabeli jest większy niż 1 MB. – Atharva

+0

Po uruchomieniu powyższego kodu otrzymuję: Błąd krytyczny: Klasa "DynamoMetadata" nie została znaleziona w C: \ Users \ Lenovo \ xampp \ public_html \ upload_file.php na linii 73'. Co zrobić, aby go rozwiązać? –

10

Opcja Count jest na pewno to, co chcesz, ale trzeba też wziąć pod uwagę, że może być jeden lub więcej " stronę "wyników w wynikach skanowania. Operacja Skanowanie skanuje tylko 1 MB danych w tabeli na raz, więc wartość Count w wyniku będzie odzwierciedlać tylko liczbę pierwszych 1 MB tabeli. Będziesz musiał wykonać kolejne żądania, używając wartości LastEvaluatedKey w wyniku (jeśli tam jest). Oto przykładowy kod robi coś takiego:

<?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 za podanie limitu –

2

Przybliżona wartość liczby pozycja (podobno aktualizowana co sześć godzin) jest dostępny w konsoli AWS dla DynamoDB. Po prostu wybierz tabelę i spójrz na zakładkę Szczegóły, ostatni wpis to Liczba przedmiotów. Jeśli to działa dla Ciebie, możesz uniknąć zużywania swojej tabeli, aby wykonać liczenie.

3

Jeśli jesteś zainteresowany wykorzystaniem całkowitej liczby pozycji w tabeli w logice aplikacji, oznacza to, że będziesz często wyszukiwał liczbę całkowitą. Teraz jednym ze sposobów na osiągnięcie tego jest użycie operacji skanowania. Ale pamiętaj, że operacja skanowania dosłownie skanuje całą tabelę, a zatem zużywa dużo przepustowości, więc wszystkie operacje kwerendy będą otrzymywać opóźniony wyjątek w tym czasie. I nawet biorąc pod uwagę fakt, że skanowanie ograniczy liczbę wypadków przez wielkość 1 MB, będziesz musiał wykonać powtarzające się operacje skanowania, aby uzyskać faktyczną liczbę pozycji, jeśli tabela jest bardzo duża. Będzie to wymagało napisania niestandardowej logiki zapytań i obsługi nieuniknionego dławienia w operacjach zapytań.

Lepszym rozwiązaniem, które przychodzi mi do głowy, jest zachowanie całkowitej liczby elementów dla takich tabel w osobnej tabeli, w której każdy element będzie miał nazwę tabeli, ponieważ jest to klucz skrótu i ​​całkowita liczba pozycji w tej tabeli, tak jak jest Bez klucza. Następnie można zachować tę tabelę o nazwie "TotalNumberOfItemsPerTable", aktualizując operację aktualizacji atomowej, aby zwiększyć/zmniejszyć całkowitą liczbę elementów dla konkretnej tabeli.

Brak problemu z ograniczeniem przepustowości lub limitem 1 MB.

Co więcej, można rozszerzyć tę koncepcję, aby uzyskać jeszcze większą szczegółowość, na przykład w celu zachowania całkowitej liczby elementów pasujących do jakiegoś hasza lub dowolnego dowolnego kryterium, które można zakodować w postaci ciągu znaków, aby pozycja w tabeli miała nazwę " TotalNumberOfItemsInSomeCollection "lub" TotalNumberOfItemsMatchingSomeCriteria ". Tabele te mogą następnie zawierać wpisy dotyczące liczby pozycji w tabeli, kolekcji lub elementów pasujących do niektórych kryteriów.

0

To jest teraz dostępny w oknie głównej tabeli AWS w sekcji 'Właściwości tabeli', pole 'Item count'. Wygląda na to, że jest tylko zrzutem DescribeTable i zauważa, że ​​jest aktualizowany mniej więcej co sześć godzin.

0

Oto jak uzyskać dokładną liczbę artykuł na moim miliard rekordy DynamoDB tabeli:

ula>

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; 

* Trzeba klaster EMR, który preinstalowane z ula i DynamoDB rekordowym Handler. * Za pomocą tego polecenia, program obsługi DynamoDB w ulu wydaje "RÓWNOLEGŁY SCANS" z wieloma mapaperami Mapreduce (AKA Workers) pracującymi na różnych partycjach w celu uzyskania liczby. Będzie to znacznie wydajniejsze i szybsze niż zwykłe skany.
* Musisz być gotów podnieść wydajność odczytu bardzo wysoki przez określony czas. * W klastrze o przyzwoitym rozmiarze (20 węzłów), przy 10000 RCU, zajęło 15 minut, aby liczyć na miliardy rekordów Około.
* Nowe zapisy na tej tabeli DDB w tym okresie spowodują niespójność liczby.

Powiązane problemy