2017-09-27 1 views
-1

Je veux d'abord donner un petit aperçu de ce que j'essaie de résoudre. Mon service récupère fréquemment des messages de diverses sources telles qu'Instagram, Twitter, etc. et je veux stocker les messages dans un grand fichier JSON sur S3. Le nom de fichier serait quelque chose comme: {slideshowId}_feed.jsonMise à jour fréquente d'un gros fichier JSON sur Amazon S3 et conflit d'écriture potentiel

Mon site Web affichera les articles dans un diaporama, et le diaporama interrogera simplement le fichier S3 toutes les minutes pour obtenir les dernières données. Il peut même interroger un autre fichier tel que {slideshowId}_meta.json qui a horodatage à partir du moment où le fichier volumineux a été modifié afin d'économiser de la bande passante.

La raison pour laquelle je veux conserver les messages dans un seul fichier JSON est principalement d'économiser des coûts. Je pourrais avoir chaque source comme son propre fichier, par ex. {slideshowId}_twitter.json, {slideshowId}_instagram.json, etc., mais le diaporama devrait envoyer une requête GET à chaque source toutes les minutes, augmentant ainsi le coût. Nous parlons de milliers de diaporamas fonctionnant en même temps, donc le coût doit bien évoluer.


Maintenant, revenons à la question. Il peut y avoir plus d'une instance du service en cours d'exécution qui vérifie Instagram et d'autres sources pour de nouveaux messages, en fonction de combien j'ai besoin de redimensionner. Le problème avec cela est le risque d'un service écrasant le fichier S3 alors qu'un autre pourrait déjà écrire sur le fichier S3. Chaque service qui doit enregistrer des publications dans le fichier JSON doit d'abord OBTENIR le fichier, le traiter et vérifier que les nouveaux messages ne sont pas dupliqués dans le fichier JSON, puis stocker les messages nouveaux ou mis à jour.


  1. que je pourrais avoir chaque service écrire les données à une file d'attente comme le simple service de file d'attente (SQS) et avoir un travailleur qui prend soin d'écrire les messages dans le fichier S3? J'ai pensé à utiliser AWS Kinesis, mais il traite seulement les données à partir des sources et les renvoie vers S3. J'ai besoin de traiter ce qui a été écrit dans le grand fichier JSON pour faire de la comptabilité.

  2. j'ai eu une idée d'utiliser DynamoDB pour stocker les messages (essentiellement à faire la tenue de livres), et alors je aurais tout simplement la requête de service toutes les données nécessaires pour un diaporama unique de DynamoDB et le stocker à S3. De cette façon, les services enverraient simplement les messages à DynamoDB.

Il doit y avoir une façon intelligente de résoudre ce problème.

+0

Je ne comprends pas pourquoi vous voulez utiliser s3. Pourquoi copiez-vous un fichier sur s3 et ensuite sur s3 sur votre site Web? Pourquoi ne pas créer dynamiquement le fichier à partir d'une base de données et utiliser la mise en cache locale? Juste semble un design bizarre, je ne vois pas ce que s3 ajoute – Vorsprung

+1

si vous insistez pour avoir un gros fichier structuré sur S3 à tout moment, alors votre meilleur pari pour la mise à jour est d'exiger des instances de votre service pour acquérir une écriture verrouiller avant de mettre à jour le fichier. Si vous êtes ouvert à des suggestions sur l'ensemble de l'architecture, il pourrait y avoir une meilleure conception pour résoudre votre problème. – grepe

+0

@Vorsprung C'est à peu près la stratégie que j'ai aujourd'hui, mais mon problème est que j'ai plus de 50 millions de requêtes par mois piquer mon API pour les données. L'API a un bon mécanisme de cache mais je manque aussi de connexions, donc j'ai besoin d'étendre l'API et d'augmenter le coût de mon infrastructure de façon exponentielle. La méthode S3 mettrait la charge sur Amazon et diminuerait considérablement le coût (0,004 $ pour 10 000 requêtes). Cela supprimerait également la dépendance à mon API. – raRaRa

Répondre

0

Voici ce que je ferais:

enter image description here

  • Le flux Kinesis aurait besoin d'avoir une capacité suffisante pour gérer tous vos écritures de producteurs d'aliments pour animaux. Pour environ 25/mois, vous pouvez faire 2000 écritures par seconde.
  • Lambda serait simplement déclenché dès qu'il y a assez de nouveaux éléments dans votre flux. Vous pouvez configurer le déclencheur pour qu'il attende 1000 nouveaux éléments, puis exécutez Lambda pour lire tous les nouveaux éléments du flux, les traiter et les écrire dans REDIS (ElastiCache). Votre facture pour cela devrait être bien inférieure à 10/mois.
  • La sélection de clé intelligente prend en charge les éléments en double. Vous pouvez également définir les éléments pour expirer si nécessaire. En fonction de votre description, vos articles doivent absolument être stockés dans la mémoire et vous pouvez ajouter des instances si vous avez besoin de plus de capacité de lecture et/ou de fiabilité. L'exécution de deux instances REDIS avec suffisamment de mémoire pour gérer vos données coûterait environ 26/mois.
  • Votre service utiliserait REDIS au lieu de S3, de sorte que vous paieriez uniquement pour le transfert de données et seulement si votre service n'est pas sur AWS (< 10/mois?).
+0

Donc, disons que quelqu'un met le diaporama dans un iframe sur un site Web très populaire où il y a 10 000 utilisateurs simultanés. Tous envoient-ils la demande directement au cluster Redis? Comment voulez-vous nourrir les utilisateurs les messages? – raRaRa

+0

hmmm ... peut-être que j'ai mal compris la question alors. Je pensais que c'était la partie que vous aviez déjà compris et je suggérais juste de remplacer le S3 par REDIS pour votre infrastructure existante, mais vous vouliez utiliser S3 comme système de distribution. alors par tous les moyens - exécutez juste quelque chose qui lira les résultats de REDIS et écrirez-le à S3 (alors vous ne devriez pas avoir besoin du verrou). – grepe

0

Ok pour votre cas d'utilisation

  • il y a beaucoup d'utilisateurs pour un seul grand fichier s3
  • le fichier est mis à jour souvent
  • le chemin du fichier (idéalement) doit être cohérent pour le rendre plus facile à obtenir et cache
  • le fichier s3 est généré par un processus sur un EC2 et mis à jour une fois par minute

Si le taux GET est inférieur à 800 par seconde, AWS en est satisfait. Si ce n'est pas le cas, vous devrez leur parler et peut-être trouver un autre moyen. Voir http://docs.aws.amazon.com/AmazonS3/latest/dev/request-rate-perf-considerations.html

Les mises à jour de fichiers seront atomiques donc il n'y a aucun problème avec verrouillage, etc. Voir http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html On peut supposer que si un utilisateur demande « pendant » une mise à jour, ils verront l'ancienne version. Ce comportement est transparent pour les deux parties

Les mises à jour de fichier sont "par la suite" cohérentes. Comme vous voulez garder l'URL pareil, vous allez mettre à jour le même chemin d'objet dans s3.

Si vous travaillez dans plusieurs régions, le temps requis pour devenir cohérent peut poser problème. Pour la même région, il semble prendre quelques secondes. AWS ne semble pas très ouvert à ce sujet, il est donc préférable de le tester pour votre cas d'utilisation. Comme votre fichier est petit et les mises à jour sont par 60 secondes, j'imagine que ce serait bien. Vous devrez peut-être supposer dans votre description de l'API que les mises à jour ont lieu plus de 60 secondes pour en tenir compte

Comme ec2 et s3 s'exécutent sur différentes parties de l'infrastructure AWS (ec2 dans un VPC et s3 derrière un public https) Vous paierez les frais de transfert de ec2 à s3

J'imagine que vous allez servir le fichier s3 via la fonction s3 "faire semblant d'être un site web". Vous devrez le configurer aussi, mais c'est trivial

+0

Veuillez noter que le service exécuté sur EC2 sera asynchrone. Disons que ça va chercher 200 posts sur Twitter, et Twitter ne vous donne que 50 posts à la fois. Mon service effectuera donc 4 appels asynchrones sur Twitter. Il n'y a aucune garantie sur quelle requête finira en premier. Le problème ici est que deux demandes peuvent finir à peu près en même temps. La première requête récupère le fichier S3 et ajoute les messages La deuxième requête fait de même La première demande écrit les modifications La deuxième demande écrit les modifications Ici, la deuxième requête écrase les modifications de la première requête. – raRaRa

+0

Non. Gardez vos données canoniques sur l'hôte en train de faire le fetch de twitter. Quand il est mis à jour, videz-le en s3. Ne ramenez jamais le s3 sur l'ec2 en cours d'exécution du scanner twitter. Toujours écrire, jamais lire. La copie s3 est uniquement utilisée pour les lectures des utilisateurs – Vorsprung

+0

Mais comment éviter les données dupliquées, par ex. deux réponses de Twitter pourraient inclure le même message. (C'est pourquoi j'ai besoin de tenue de livres). À moins bien sûr que le côté client gère cela. Donc, vous auriez essentiellement chaque minute le service EC2 chercher tous les messages de Twitter? C'est là que la limite de débit API pourrait causer un gros problème pour moi (surtout sur Instagram, 5000 par heure ou 83 par minute). Je pourrais également avoir à faire des demandes supplémentaires pour obtenir les commentaires de poste, la référence à la vidéo haute résolution, etc. Ainsi, je pourrais facilement manquer d'appels rapidement. – raRaRa