10
votes

Téléchargement de lots d'énormes ensembles d'images sur le stockage d'Azure Blob

J'ai environ 110 000 images de formats divers (JPG, PNG et GIF) et tailles (2-40KB) stockées localement sur mon disque dur. J'ai besoin de les télécharger sur le stockage d'Azure Blob. Tout en faisant cela, je dois définir des métadonnées et du contenu du blob, mais sinon c'est un téléchargement en vrac droit.

Je suis actuellement en train d'utiliser ce qui suit pour gérer le téléchargement d'une image à la fois (parallèlement à 5-10 tâches simultanées ). xxx

Je me demandais s'il y avait une autre technique que je pouvais utiliser pour gérer le téléchargement, pour le rendre aussi rapide que possible. Ce particulier Le projet implique l'importation de nombreuses données d'un système à un autre et pour des raisons pour les clients, il doit arriver aussi rapidement que possible.


5 commentaires

La réponse évidente est de trouver une connexion plus rapide (téléchargée). Vous pouvez effectuer une mise à niveau temporaire de votre connexion, ou peut-être essayer d'emprunter ou de louer du temps (par exemple, via Cragislist, groupe professionnel local, etc.).


J'ai une ligne de 50 Mo de haut en bas. La question que j'ai est la quantité de temps qu'elle prend pour le téléchargementfromstream () à revenir, et je rencontre des problèmes de collecte de déchets assez étranges avec les objets de blob Azure si j'essaie d'exécuter plus de 10 tâches en parallèle.


Je sais que Rackspace vous permet de vivre à eux et de le mettre sur leur nuage. Microsoft a-t-il quelque chose de similaire?


Les États membres proposent un service similaire; azure.microsoft.com/fr-gB/documentation / Articles / ...


Une chose que j'ai faite pour optimiser un très grand téléchargement en vrac consistait à tout mettre sur un VHD, téléchargez-la, joindre à une machine virtuelle dans le même datacenter, puis exécutez l'outil de téléchargement de là. Juste une autre chose en plus des autres optimisations.


6 Réponses :


0
votes

Vous pouvez toujours essayer les méthodes asynchrones de téléchargement.

public override IAsyncResult BeginUploadFromStream (
Stream source,
AsyncCallback callback,
Object state


3 commentaires

Essayé cela. Cela fonctionne, mais a des problèmes de performance graves. Pour une raison quelconque, exécuter des téléchargements BLOB dans des threads parallèles mange une tonne de processeur et fonctionne plutôt lentement au-delà d'environ 5 threads. Voir ma réponse pour les détails sur mon approche éventuelle.


Un autre suivi ... Avez-vous essayé d'éteindre l'algorithme NAGLE? J'ai totalement espacé cela plus tôt :) blogs.msdn.com/b/windowsazurestorage/archive/2010/06/25/...


Wow, ça a l'air fou. Je n'ai pas le temps d'employer cela pour cette solution (c'est l'un de ceux-ci »doit être rapide mais ne sera jamais exécuté une fois dans l'histoire de tous les" projets), mais je l'ai marqué pour les importations futures i "ll va faire. Merci mec!



1
votes

Comme les fichiers que vous téléchargez sont assez petits, je pense que le code que vous avez écrit est probablement aussi efficace que possible. Basé sur votre commentaire, il semble que vous ayez essayé d'exécuter ces téléchargements en parallèle, ce qui était vraiment la seule suggestion de code que j'avais.

Je soupçonne que pour obtenir le plus grand débit consistera à trouver le bon nombre de threads pour votre matériel, votre connexion et votre taille de fichier. Vous pouvez essayer d'utiliser Analyseur de débit Azure < / a> pour trouver cet équilibre plus facile.

Le groupe d'informatique extrême de Microsoft a également points de repère et suggestions sur l'amélioration Débit . Il est axé sur le débit des rôles de travailleurs déployés sur Azure, mais cela vous donnera une idée du meilleur que vous puissiez espérer.


1 commentaires

J'ai fini par courir un tas d'instances séparées du téléchargeur, concentrée sur différents ensembles d'images (10 000 à la fois). Merci pour les indicateurs cependant, j'ai évoqué votre réponse quand même :).



7
votes

D'accord, voici ce que je faisais. Je bricolé autour de l'exécution BeginUploadFromStream (), puis BeginSetMetadata (), puis BeginSetProperties () dans une chaîne asynchrone, en parallèle sur 5-10 fils (une combinaison de ElvisLive et de suggestions de knightpfhor). Cela a fonctionné, mais quoi que ce soit plus de 5 fils avait terribles performances, en prenant plus de 20 secondes pour chaque thread (travail sur une page d'images dix à la fois) pour terminer.

Donc, pour résumer les différences de performance:

  • Asynchrone: 5 fils, chaque exécution d'une chaîne asynchrone, chaque travail sur dix images à la fois (paginée, pour des raisons statistiques):. ~ 15,8 secondes (par fil)
  • synchrone: 1 fil, dix images à la fois (paginée pour des raisons statistiques): ~ 3.4 secondes

    D'accord, c'est assez intéressant. Un blobs exemple de téléchargement des 5x effectué de manière synchrone mieux que chaque fil dans l'autre approche. Ainsi, même courir le meilleur équilibre async 5 filets de fils essentiellement les mêmes performances .

    Alors, je peaufiné mon fichier d'image importer pour séparer les images dans des dossiers contenant 10.000 images chacun. Ensuite, je Process.Start () pour lancer une instance de mon blob Uploader pour chaque dossier. Je 170.000 images à travailler dans ce lot, de sorte que des moyens 17 instances du Uploader. Lors de l'exécution de tous ceux sur mon ordinateur portable, la performance dans tous les nivelé à ~ 4.3 secondes par jeu .

    Longue histoire courte, au lieu d'essayer d'obtenir le filetage fonctionne de manière optimale, je lance juste un blob Uploader instance pour 10.000 images, le tout sur une machine en même temps. boost de performance totale?

    • Async tentatives. 14-16 heures , en fonction du temps d'exécution moyen lors de l'exécution pendant une heure ou deux
    • synchrone avec 17 cas distincts:. ~ 1 heure, 5 minutes

0 commentaires

3
votes

Vous devez définitivement télécharger en parallèle dans plusieurs flux (c.-à-d. Publier plusieurs fichiers simultanément), mais avant de faire une expérience montrant (à tort) qu'il n'y a pas d'avantage, assurez-vous d'augmenter réellement la valeur de ServicePointManager.defaultConnectionLimit :

Le nombre maximum de connexions simultanées autorisées par un point de service objet. La valeur par défaut est 2.

Avec une valeur par défaut de 2, vous pouvez avoir au plus deux demandes HTTP exceptionnelles contre n'importe quelle destination.


3 commentaires

... Je n'étais pas au courant de ce réglage. Fascinant que je n'ai jamais mentionné une mention de celui-ci près de l'un des trucs de stockage de blob async que j'ai lu. J'ai déjà exécuté ma solution et n'avez pas le temps d'essayer celui-ci, mais je vais certainement garder à l'esprit à l'avenir. C'était probablement le goulot d'étranglement principal. /rage.


MSDN.MicRosoft.com/EN-US/ Bibliothèque / 7F54ZA5% 28V = vs.100% 29.aspx . La valeur par défaut de 2 est de «conforme» avec les spécifications HTTP / 1.1, mais cela manque généralement le point que tout serveur valant son sel est réellement derrière un équilibreur de charge net et que vous cibliez des centaines de centaines de «serveurs» avec une seule URL. (Certainement le cas avec le stockage de blob Azure)


Réglage de cette manière affecte toutes les connexions HTTP pour l'assemblage ... Vous pouvez définir le gestionnaire de points de service uniquement pour la connexion de votre traitement.



1
votes

Vous voudrez peut-être augmenter la parallopérationCount comme indiqué ci-dessous. Je n'ai pas vérifié le dernier SDK, mais dans 1.3, la limite était de 64. Ne pas définir cette valeur a abouti à des opérations simultanées plus faibles. xxx


0 commentaires

1
votes

Si la méthode parallèle prend 5 fois plus pour télécharger que la série, alors vous

  • avoir une bande passante terrible
  • avoir un ordinateur très lent
  • faire quelque chose de mal

    Mon utilisation de la ligne de commande obtient un coup de pouce assez boost lors de l'exécution en parallèle, même si je n'utilise pas de flux de mémoire ni d'autres trucs Nifty, je générerai simplement une gamme de cordes des noms de fichiers, puis téléchargez-les avec Parallèle.foreach .

    En outre, les Propriétés.ContentType Call vous permet de retirer un peu. Personnellement, je ne les utilise jamais et je suppose qu'ils ne devraient même pas avoir d'importance, à moins que vous ne souhaitiez les voir dans le navigateur via des URL directes.


0 commentaires