Comment interroger DynamoDB par date (clé range), sans clé de hachage évidente?

j'ai besoin de garder les données locales sur une application iOS en synchronisation avec les données dans une table de DynamoDB. La table DynamoDB est constituée de lignes ~2K, avec seulement une touche de hachage ( id ), et les attributs suivants:

  • id (uuid)
  • lastModifiedAt (timestamp)
  • name
  • latitude
  • longitude

je suis actuellement numérisation et filtrage par lastModifiedAt , où lastModifiedAt est plus grand que la dernière date de rafraîchissement de l'application, mais j'imagine que cela va devenir coûteux.

Le meilleur réponse je trouve, c'est pour ajouter un Index Secondaire Global avec lastModifiedAt comme la gamme, mais il n'est pas évident de clé de hachage pour le GSI.

Quelle est la meilleure pratique lorsque vous devez effectuer une recherche par domaine en utilisant un GSI, mais qu'il n'y a pas de clé de hachage évidente? par ailleurs, si une analyse complète est la seule option, y a-t-il des pratiques exemplaires pour réduire les coûts?

22
demandé sur Community 2016-03-12 23:58:53

3 réponses

bien qu'un Global Secondary Index semble correspondre à vos besoins, toute tentative d'inclure timestamp informations connexes dans le cadre de votre Hash Key sera très probablement créer ce qui est connu sous le nom de" cloison chaude", qui est extrêmement indésirable.

L'inégal accès se fera comme les éléments les plus récents vont être récupérées avec plus de fréquence que les anciens. Cela aura non seulement un impact sur votre performance, mais rendra également votre solution moins rentable.

voir certains détails dans la documentation:

par exemple, si une table a un très petit nombre de partition des valeurs clés, peut-être même une seule très utilisée valeur de la clé de partition, le trafic de requête est concentré sur un petit nombre des cloisons-potentiellement une seule cloison. Si la charge de travail est fortement déséquilibrée, ce qui signifie qu'il est focalisée sur un ou quelques partitions, le les demandes n'atteindront pas l'objectif global le débit réservé. Pour tirer le meilleur parti de DynamoDB débit, créer des tables où la clé de partition a un grand nombre des valeurs distinctes, et les valeurs sont demandées assez uniformément, au hasard comme possible.

basé sur ce qui est indiqué, le id semble effectivement être un bon choix pour votre Hash Key (alias. Partition Key ), Je ne changerais pas que les clés GSI fonctionnent de la même manière partitionner. Comme une note séparée, la performance est fortement optimisée lorsque vous récupérez vos données en fournissant le Primary Key entier , donc nous devrions essayer de trouver une solution qui prévoit que chaque fois que possible.

je suggérerais de créer des tables séparées pour stocker les clés primaires basées sur la façon dont elles ont été mises à jour. Vous pouvez segmenter les données en tableaux en fonction de la granularité qui correspond le mieux à vos cas d'utilisation. Par exemple, disons que vous souhaitez segmenter les mises à jour par jour:

A. Vos mises à jour quotidiennes pourraient être stockées dans des tables avec la convention de nommage suivante: updates_DDMM

B. Les tables updates_DDMM auraient seulement les id 'S (touches de hachage de l'autre table)

maintenant, dites que la dernière date de rafraîchissement de l'application était il y a 2 jours (04/07/16) et vous avez besoin d'obtenir les enregistrements récents, vous auriez alors besoin de:

I. Scanner les tables updates_0504 et updates_0604 pour obtenir toutes les clés de hachage.

ii. Obtenir enfin les enregistrements de la table principale (contenant lat/lng, nom, etc) en soumettant un BatchGetItem avec toutes les clés de hachage obtenues.

BatchGetItem est super rapide et faire le travail comme aucune autre opération.

on peut faire valoir que la création de tableaux supplémentaires va ajouter des coûts à votre solution globale... Eh bien, avec GSI vous êtes essentiellement dupliquer votre table (en cas où vous projetez tous les champs) et en ajoutant ce coût supplémentaire pour tous les enregistrements ~2k, étant eux récemment mis à jour ou non...

cela semble contre-intuitif de créer des tables comme celle-ci, mais c'est en fait une bonne pratique lorsqu'il s'agit de traiter des données de séries chronologiques (à partir de la Documentation de DynamoDB D'AWS):

[...] les applications peuvent montrer un modèle d'accès inégal entre tous les éléments dans le tableau où les dernières données client est plus pertinentes et votre application pourrait accéder aux derniers éléments plus fréquemment et au fil du temps ces articles sont moins accessibles, éventuellement les articles plus anciens sont rarement accessible. Si c'est un modèle d'accès, vous pouvez le prendre en considération lors de la conception de votre schéma de table. Plutôt stocker tous les éléments dans une seule table, vous pouvez utiliser plusieurs tables pour stocker ces éléments. Par exemple, vous pouvez créer des tables pour stocker données mensuelles ou hebdomadaires. Pour la table de stockage des données de la dernière mois ou semaine, où le taux d'accès aux données est élevé, demander plus le débit et pour les tables de stockage de données plus anciennes, vous pouvez composer le le débit et économiser les ressources.

vous pouvez économiser sur les ressources en stockant des éléments "chauds" dans une table avec des réglages de débit plus élevés, et des articles "froids" dans une autre table avec réglages de débit plus bas. Vous pouvez supprimer de vieux éléments en supprimant simplement table. Vous pouvez éventuellement sauvegarder ces tables à d'autres options telles que Amazon Simple service de stockage (Amazon S3). La suppression d'un table entière est beaucoup plus efficace que de supprimer des articles un par un, qui, essentiellement, double l'écriture de débit que vous ne comme de nombreuses opérations de suppression de placer les opérations.

Source: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GuidelinesForTables.html

j'espère que ça aidera. Égard.

23
répondu bsd 2016-04-08 04:19:55

bien que la réponse de D. Shawley m'ait aidé à me diriger dans la bonne direction, elle a omis deux considérations pour un GSI:

  1. la gamme hash+doit être unique, mais day+timestamp (son approche recommandée) ne serait pas nécessairement unique.
  2. En utilisant seulement le jour que le hachage, j'aurais besoin d'utiliser un grand nombre de requêtes pour obtenir les résultats pour chaque jour depuis la dernière date d'actualisation (qui pourraient être des mois ou des années).

en tant que tel, voici l'approche que j'ai adoptée:

  • a créé un indice secondaire Global (GSI) avec la clé de hachage YearMonth (e.g., 201508 ) et la plage id
  • interrogez le GSI plusieurs fois, une interrogation pour chaque mois depuis la dernière date de rafraîchissement. Les requêtes sont également filtrées avec lastModifiedAt > [given timestamp] .
7
répondu James Skidmore 2016-03-22 03:09:26

vous pouvez utiliser la partie" jour " de l'horodatage comme le hachage et utiliser l'horodatage complet comme la gamme.

3
répondu D.Shawley 2016-03-12 21:03:40