Je veux savoir combien d'éléments sont dans ma table dynamodb. Dans le guide de l'API, une façon de le faire consiste à utiliser scan comme suit:
<?php
$dynamodb = new AmazonDynamoDB();
$scan_response = $dynamodb->scan(array(
'TableName' => 'ProductCatalog'
));
echo "Total number of items: ".count($scan_response->body->Items)."\n";
Cependant, cela doit aller chercher tous les éléments et les stocker dans un tableau en mémoire, ce qui n’est pas faisable dans la plupart des cas, je suppose. Existe-t-il un moyen d’obtenir le nombre total d’items plus efficacement?
Ces données ne sont pas disponibles dans la console Web AWS Dynamo, j'ai déjà vérifié. (au début, on dirait qu’il apparaît à côté des boutons de pagination, mais il s’avère que la figure grossit au fur et à mesure que vous passez à la page d’articles suivante).
Je peux penser à trois options pour obtenir le nombre total d'éléments dans une table DynamoDB.
La première option consiste à utiliser l'analyse, mais la fonction d'analyse est inefficace et est en général une mauvaise pratique, en particulier pour les tables avec des lectures lourdes ou des tables de production.
La deuxième option est ce qui a été mentionné par Atharva:
Une meilleure solution qui me vienne à l’esprit est de maintenir le total nombre de comptes d'articles pour ces tables dans une table séparée, où chacun item aura le nom de la table car c'est la clé de hachage et le nombre total d'articles dans cette table comme c'est l'attribut non-clé. Vous pouvez alors garder cette table éventuellement nommé "TotalNumberOfItemsPerTable" mis à jour en rendant atomique met à jour les opérations pour incrémenter/décrémenter le nombre total d’éléments pour un table particulière.
Le seul problème est que les opérations d'incrémentation ne sont pas idempotentes. Donc, si une écriture échoue ou si vous écrivez plus d'une fois, cela sera reflété dans le décompte. Si vous avez besoin d'une précision ponctuelle, utilisez plutôt une mise à jour conditionnelle.
La solution la plus simple est la DescribeTable, qui renvoie ItemCount. Le seul problème est que le compte n'est pas à jour. Le compte est mis à jour toutes les 6 heures.
http://docs.aws.Amazon.com/amazondynamodb/latest/APIReference/API_DescribeTable.html
L'option Count
est certainement ce que vous voulez, mais vous devez également prendre en compte le fait qu'il peut y avoir une ou plusieurs "page" de résultats dans votre résultat d'analyse. L’opération Scan n’analyse que 1 Mo de données de votre table à la fois. La valeur Count
du résultat ne reflète donc que le nombre de 1 Mo de la table. Vous devrez faire des requêtes ultérieures en utilisant la valeur LastEvaluatedKey
dans le résultat (s'il y en a une). Voici un exemple de code permettant de faire quelque chose comme ça:
<?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}";
Aha, il existe une option Count
dans l'API scan
, voir 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";
Si vous souhaitez utiliser le nombre total d'éléments d'une table dans la logique de votre application, cela signifie que vous allez interroger le nombre total de fois assez souvent. Une méthode pour y parvenir consiste à utiliser l'opération de numérisation. Mais rappelez-vous que l'opération d'analyse parcourt littéralement l'ensemble de la table et consomme donc beaucoup de débit, de sorte que toutes les opérations de requête recevront une exception étranglée pendant cette durée. Et même en considérant le fait que l'analyse limitera le nombre résultant par taille de 1 Mo, vous devrez effectuer des opérations d'analyse répétées pour obtenir le nombre réel d'éléments si la table est très grande. Cela nécessitera d'écrire une logique de requête personnalisée et de gérer les limitations inévitables dans les opérations de requête.
Une meilleure solution qui me vienne à l’esprit est de conserver le nombre total de comptes d’éléments pour ces tables dans un tableau séparé, chaque élément ayant le nom de table comme clé de hachage et le nombre total d’éléments de cette table comme attribut non-clé. . Vous pouvez ensuite garder cette table éventuellement nommée "TotalNumberOfItemsPerTable" mise à jour en faisant en sorte que les opérations de mise à jour atomique incrémentent/décrémentent le nombre total d'éléments pour une table particulière.
Aucun problème de limitation ou de limite de 1 Mo.
En outre, vous pouvez étendre ce concept à une granularité encore accrue, par exemple pour maintenir le nombre total d’éléments correspondant à une clé de hachage ou à tout critère arbitraire que vous pouvez coder sous forme de chaîne pour créer une entrée dans votre table portant le nom "TotalNumberOfItemsInSomeCollection" ou " TotalNumberOfItemsMatchingSomeCriteria ". Ces tables peuvent ensuite contenir des entrées pour le nombre d'éléments par table, par collection ou d'éléments correspondant à certains critères.
Une valeur approximative du nombre d'éléments (supposément mise à jour toutes les six heures) est disponible dans la console AWS pour DynamoDB. Il suffit de sélectionner la table et de regarder sous l'onglet Détails, la dernière entrée est Nombre d'éléments. Si cela fonctionne pour vous, vous pouvez éviter de consommer le débit de votre table pour effectuer le décompte.
Cette option est désormais disponible dans l'écran de synthèse de la table AWS, dans la section "Détails de la table", champ "Nombre d'éléments". Il semble qu’il s’agisse d’un simple vidage de DescribeTable et note qu’il est mis à jour environ toutes les six heures.
Voici comment obtenir le nombre exact d'articles sur mon milliard d'enregistrements dans la table DynamoDB:
Ruche>
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;
* Vous devez disposer d'un cluster EMR installé avec Hive et le gestionnaire d'enregistrement DynamoDB . * Avec cette commande, le gestionnaire DynamoDB sur Hive lance "Analyses parallèles" avec plusieurs mappeurs Mapreduce (AKA Workers) travaillant sur différentes partitions le décompte. Cela sera beaucoup plus efficace et plus rapide que les analyses normales.
* Vous devez être prêt à augmenter considérablement la capacité de lecture pendant un certain laps de temps * Sur un cluster de taille décente (20 nœuds), avec 10000 unités de contrôle, il a fallu 15 minutes pour compter des milliards d’enregistrements. .
* Les nouvelles écritures sur cette table DDB pendant cette période rendront le compte incohérent.