Utilisation d'analyses dans DynamoDB - Amazon DynamoDB

Utilisation d'analyses dans DynamoDB

Une opération Scan dans Amazon DynamoDB lit tous les éléments d'une table ou d'un index secondaire. Par défaut, une opération Scan retourne tous les attributs de données pour chaque élément de la table ou de l'index. Vous pouvez utiliser le paramètre ProjectionExpression de telle sorte que Scan retourne uniquement certains des attributs, plutôt que leur totalité.

Scan retourne toujours un jeu de résultats. Si aucun élément correspondant n'est trouvé, le jeu de résultats est vide.

Une seule demande Scan peut extraire un maximum de 1 Mo de données. Le cas échéant, DynamoDB peut appliquer une expression de filtre à ces données, en affinant les résultats avant qu'ils soient renvoyés à l'utilisateur.

Filtrer les expressions pour l'opération Scan

Si vous avez besoin d'affiner davantage les résultats de l'opération Scan, vous pouvez fournir une expression de filtre facultative. Une expression de filtre détermine les éléments dans les résultats de Scan qui doivent vous être renvoyés. Tous les autres résultats sont ignorés.

Une expression de filtre est appliquée après la fin de l'opération Scan, mais avant que les résultats soient renvoyés. Par conséquent, une opération Scan utilise la même capacité de lecture, qu'une expression de filtre soit présente ou non.

Une opération Scan peut extraire au maximum 1 Mo de données. Cette limite s'applique avant que l'expression de filtre soit évaluée.

Avec Scan, vous pouvez spécifier tous les attributs dans une expression de filtre, y compris les attributs de clé de partition et de clé de tri.

La syntaxe d'un expression de filtre est identique à celle d'une expression de condition. Les expressions de filtre peuvent utiliser les mêmes comparateurs, fonctions et opérateurs logiques qu'une expression de condition. Pour plus d'informations, veuillez consulter, Expressions de condition.

Exemple

L'exemple AWS Command Line Interface (AWS CLI) analyse la table Thread et renvoie uniquement les derniers éléments publiés par un utilisateur particulier.

aws dynamodb scan \ --table-name Thread \ --filter-expression "LastPostedBy = :name" \ --expression-attribute-values '{":name":{"S":"User A"}}'

Limiter le nombre d'éléments dans le jeu de résultats

L'opération Scan permet de limiter le nombre d'éléments renvoyés dans le résultat. Pour ce faire, définissez le paramètre Limit sur le nombre maximal d'éléments que vous souhaitez que l'opération Scan retourne, avant l'évaluation de l'expression de filtre.

Par exemple, supposons que vous effectuiez une opération Scan sur une table, avec une valeur Limit de 6 et sans expression de filtre. Le résultat Scan contient les six premiers éléments de la table.

Supposons maintenant que vous ajoutiez une expression de filtre à l'opération Scan. Dans ce cas, DynamoDB applique l'expression de filtre aux six éléments renvoyés et supprime ceux qui ne correspondent pas. Le résultat final Scan contient six éléments au plus, selon le nombre d'éléments filtrés.

Pagination des résultats

DynamoDB pagine les résultats des opérations Scan. Avec la pagination, les résultats Scan sont répartis en « pages » de données d'une taille maximum de 1 Mo. Une application peut traiter la première page des résultats, puis la deuxième page, et ainsi de suite.

Une opération Scan retourne uniquement un ensemble de résultats correspondant à la limite de taille de 1 Mo.

Pour déterminer si le nombre de résultats est plus important et pour récupérer une page à la fois, les applications doivent procéder de la manière suivante :

  1. Examinez le résultat de Scan de niveau inférieur :

    • Si le résultat contient un élément LastEvaluatedKey, passez à l'étape 2.

    • S'il n'y a pas de LastEvaluatedKey dans le résultat, il n'y a plus aucun élément à récupérer.

  2. Construisez une nouvelle demande Scan, avec les mêmes paramètres que la précédente. Cependant, cette fois, acceptez la valeur LastEvaluatedKey de l'étape 1 et utilisez-la comme paramètre ExclusiveStartKey dans la nouvelle demande Scan.

  3. Exécutez la nouvelle demande Scan.

  4. Passez à l'étape 1.

En d'autres termes, l'élément LastEvaluatedKey provenant d'une réponse Scan doit être utilisé comme ExclusiveStartKey pour la demande Scan suivante. Si aucun élément LastEvaluatedKey n'est présent dans la réponse Scan, vous avez extrait la dernière page de résultats. (L'absence de LastEvaluatedKey est le seul moyen de savoir que vous avez atteint la fin du jeu de résultats.)

Vous pouvez utiliser AWS CLI pour afficher cet comportement. L'AWS CLI envoie des demandes Scan de bas niveau à DynamoDB de manière répétée jusqu'à ce que LastEvaluatedKey ne figure plus dans les résultats. Prenez en considération l'exemple AWS CLI suivant qui analyse la table Movies entière mais renvoie uniquement les films d'un genre particulier.

aws dynamodb scan \ --table-name Movies \ --projection-expression "title" \ --filter-expression 'contains(info.genres,:gen)' \ --expression-attribute-values '{":gen":{"S":"Sci-Fi"}}' \ --page-size 100 \ --debug

D'ordinaire, AWS CLI gère la pagination automatiquement. Cependant, dans cet exemple, le paramètre AWS CLI --page-size limite le nombre d'éléments par page. La paramètre --debug imprime les informations de niveau inférieur relatives aux requêtes et aux réponses.

Note

Vos résultats de pagination diffèrent également en fonction des paramètres d'entrée que vous transmettez.

  • L'utilisation de aws dynamodb scan --table-name Prices --max-items 1 renvoie un NextToken

  • L’utilisation de aws dynamodb scan --table-name Prices --limit 1 renvoie un LastEvaluatedKey.

Sachez également que l'utilisation de --starting-token en particulier requiert la valeur NextToken.

Si vous exécutez l'exemple, la première réponse de DynamoDB est à similaire à ce qui suit.

2017-07-07 12:19:14,389 - MainThread - botocore.parsers - DEBUG - Response body: b'{"Count":7,"Items":[{"title":{"S":"Monster on the Campus"}},{"title":{"S":"+1"}}, {"title":{"S":"100 Degrees Below Zero"}},{"title":{"S":"About Time"}},{"title":{"S":"After Earth"}}, {"title":{"S":"Age of Dinosaurs"}},{"title":{"S":"Cloudy with a Chance of Meatballs 2"}}], "LastEvaluatedKey":{"year":{"N":"2013"},"title":{"S":"Curse of Chucky"}},"ScannedCount":100}'

Le LastEvaluatedKey de la réponse indique que certains éléments n'ont pas été récupérés. L'AWS CLI émet alors une autre demande Scan à DynamoDB. Ce modèle de requête et de réponse se poursuit jusqu'à l'obtention d'une réponse finale.

2017-07-07 12:19:17,830 - MainThread - botocore.parsers - DEBUG - Response body: b'{"Count":1,"Items":[{"title":{"S":"WarGames"}}],"ScannedCount":6}'

L'absence de LastEvaluatedKey indique qu'il n'y a pas plus de d'élément à récupérer.

Note

Les kits SDK AWS manipulent les réponses de DynamoDB de bas niveau (y compris la présence ou l'absence de LastEvaluatedKey), et fournissent diverses abstractions pour la pagination des résultats de Scan. Par exemple, l'interface de document du kit SDK pour Java fournit le support java.util.Iterator pour vous permettre de parcourir les résultats un par un.

Pour des exemples de code dans diverses langues de programmation, consultez le Guide de mise en route Amazon DynamoDB et la documentation du kit SDK AWS pour votre langage.

Comptabilisation des éléments dans les résultats

Outre les éléments qui correspondent à vos critères, la réponse d'une opération Scan contient les éléments suivants :

  • ScannedCount – Nombre d'éléments évalués avant l'application de ScanFilter. Une valeur ScannedCount élevée avec peu ou pas de résultats Count indique une opération Scan inefficace. Si vous n'avez pas utilisé de filtre dans la demande, ScannedCount et Count ont la même valeur.

  • Count – Nombre d'éléments qui restent après l'application d'une expression de filtre (le cas échéant).

Note

Si vous n'utilisez pas d'expression de filtre, alors ScannedCount et Count ont la même valeur.

Si la taille de l'ensemble de résultats Scan est supérieure à 1 Mo, les opérations ScannedCount et Count représentent seulement un compte partiel du total des éléments. Vous devez effectuer plusieurs opérations Scan pour pouvoir extraire tous les résultats (consultez Pagination des résultats).

Chaque réponse Scan contient les ScannedCount et Count des éléments traités par cette demande Scan particulière. Pour obtenir les totaux de toutes les demandes Scan, vous pouvez garder un compte actif de ScannedCount et de Count.

Unités de capacité consommées par l'opération Scan

Vous pouvez effectuer une opération Scan sur un table ou un index secondaire quelconques. Les opérations Scan consomment des unités de capacité de lecture, comme suit.

Si vous effectuez une opération Scan sur... DynamoDB consomme des unités de capacité de lecture de…
Tableau Capacité de lecture allouée à la table.
Index secondaire global Capacité de lecture allouée à l'index.
Index secondaire local Capacité de lecture allouée à la table de base.

Par défaut, l'opération Scan ne renvoie pas de données concernant la consommation de capacité de lecture. Vous pouvez toutefois spécifier le paramètre ReturnConsumedCapacity dans une demande Scan pour obtenir ces informations. Les paramètres suivants sont valides pour   ReturnConsumedCapacity:

  • NONE – Aucune donnée de capacité consommée n'est renvoyée. (Il s'agit de l'option par défaut.)

  • TOTAL – La réponse inclut le nombre agrégé d'unités de capacité de lecture consommées.

  • INDEXES – La réponse indique le nombre agrégé d'unités de capacité de lecture consommées, ainsi que la capacité consommée pour chaque table et index consultés.

DynamoDB calcule le nombre d'unités de capacité de lecture consommées en fonction de la taille d'un élément, pas de la quantité de données renvoyées à une application. Pour cette raison, le nombre d'unités de capacité consommées sera le même que vous demandiez tous les attributs (comportement par défaut) ou seulement certains d'entre eux (avec une expression de projection). Le nombre sera également le même que vous spécifiez ou non une expression de filtre.

Cohérence en lecture de l'opération Scan

Par défaut, une opération Scan effectue des lectures éventuellement cohérentes. Cela signifie que les résultats de l'opération Scan peuvent ne pas refléter des modifications apportées par des opérations PutItem ou UpdateItem récentes. Pour plus d'informations, consultez Cohérence en lecture.

Si vous avez besoin de lectures cohérentes fortes au moment où l'opération Scan commence, définissez le paramètre ConsistentRead à la valeur true dans la demande Scan. Cela garantit que toutes les opérations d'écriture qui ont pris fin avant que l'opération Scan ne commence seront incluses dans la réponse Scan.

La définition de ConsistentRead sur true peut être utile dans la sauvegarde des tables ou les scénarios de réplication, en conjonction avec DynamoDB Streams. Vous utilisez d'abord Scan avec ConsistentRead définie sur la valeur true pour obtenir une copie cohérente des données de la table. Pendant l'opération Scan, DynamoDB Streams enregistre toute activité d'écriture supplémentaires qui se produit sur la table. Une fois l'opération Scan terminée, vous pouvez appliquer l'activité d'écriture du flux vers la table.

Note

Notez qu'une opération Scan avec ConsistentRead ayant la valeur true consomme deux fois plus d'unités de capacité en lecture, par comparaison avec le fait de laisser ConsistentRead à sa valeur par défaut (false).

Analyse parallèle

Par défaut, l'opération Scan traite les données de manière séquentielle. Amazon DynamoDB renvoie des données à l'application par incréments de 1 Mo, et une application effectue des opérations Scan supplémentaires pour extraire le Mo de données suivant.

Plus la table ou l'index en cours d'analyse sont grands, plus l'opération Scan prend du temps. En outre, il arrive qu'une opération Scan séquentielle ne puisse pas utiliser pleinement la capacité de débit de lecture approvisionné. Même si DynamoDB distribue les données d'une grande table sur plusieurs partitions physiques, une opération Scan ne peut lire qu'une seule partition à la fois. C'est pourquoi le débit d'une opération Scan est limité par le débit maximum d'une partition.

Pour résoudre ce problème, l'opération Scan peut diviser logiquement une table ou un index secondaire en plusieurs segments, et avoir plusieurs employés d'application qui analysent les segments en parallèle. Chaque employé peut être une unité d'exécution (quand le langage de programmation prend en charge les unités d'exécution multiples) ou un processus de système d'exploitation. Pour effectuer une analyse en parallèle, chaque employé émet sa propre demande Scan avec les paramètres suivants :

  • Segment – Segment à analyser par un employé particulier. Chaque employé doit utiliser une valeur différente pour Segment.

  • TotalSegments – Nombre total de segments pour l'analyse en parallèle. Cette valeur doit être identique au nombre d'employés que votre application va utiliser.

Le diagramme suivant illustre la manière dont une application à unités d'exécution multiple exécute une opération Scan en parallèle avec trois degrés de parallélisme.

Dans ce diagramme, l'application produit trois unités d'exécution auxquels elle attribue un numéro (les segments étant de base zéro, le premier numéro est toujours 0). Chaque unité d'exécution émet une demande Scan, définissant la valeur Segment sur son numéro désigné, et la valeur TotalSegments sur 3. Chaque unité d'exécution analyse son segment désigné en extrayant des données 1 Mo à la fois, et renvoie les données au thread principal de l'application.

Les valeurs Segment et TotalSegments s'appliquent à des demandes Scan individuelles, et vous pouvez utiliser différentes valeurs à tout moment. Il se peut que vous deviez expérimenter ces valeurs et le nombre d'employés que vous utilisez, jusqu'à ce que votre application atteigne des performances optimales.

Note

Une analyse en parallèle avec un grand nombre d'employés peut facilement consommer tout le débit approvisionné pour la table ou l'index analysé. Il est préférable d'éviter de telles analyses si d'autres applications soumettent également la table ou l'index à une intense activité de lecture ou d'écriture.

Pour contrôler la quantité de données renvoyées par demande, utilisez le paramètre Limit. Cela peut vous aider à éviter des situations où un employé consomme tout le débit approvisionné, au détriment des autres employés.