web-dev-qa-db-fra.com

Quelle est la meilleure approche pour gérer les téléchargements de fichiers volumineux dans une application Rails?

Je suis intéressé à comprendre les différentes approches pour gérer les téléchargements de fichiers volumineux dans une application Rails, 2-5 Go).

Je comprends que pour transférer un fichier de cette taille, il devra être décomposé en parties plus petites, j'ai fait quelques recherches et voici ce que j'ai jusqu'à présent.

  • La configuration côté serveur sera nécessaire pour accepter les grandes demandes POST et probablement une machine 64 bits pour gérer tout ce qui dépasse 4 Go .
  • AWS prend en charge téléchargement en plusieurs parties.
  • HTML5 FileSystemAPI a un programme de téléchargement persistant qui télécharge le fichier en morceaux.
  • Une bibliothèque pour Bitorrent bien que cela nécessite un client de transmission qui n'est pas idéal

Est-ce que toutes ces méthodes peuvent être reprises comme FTP, la raison pour laquelle je ne veux pas utiliser FTP est que je veux garder dans l'application web si c'est possible? J'ai utilisé carrierwave et Paperclip mais je suis à la recherche de quelque chose qui pourra être repris car le téléchargement d'un fichier 5 Go pourrait prendre un certain temps!

Parmi ces approches que j'ai énumérées, je voudrais comprendre ce qui a bien fonctionné et s'il y a d'autres approches qui pourraient me manquer? Pas de plugins si possible, préfère ne pas utiliser Java Applets ou Flash. Une autre préoccupation est que ces solutions conservent le fichier en mémoire lors du téléchargement, c'est aussi une contrainte que je préfère éviter si possible.

39
cih

J'ai traité ce problème sur plusieurs sites, en utilisant quelques-unes des techniques que vous avez illustrées ci-dessus et quelques-unes que vous n'avez pas. La bonne nouvelle est qu'il est en fait assez réaliste d'autoriser des téléchargements massifs.

Cela dépend en grande partie de ce que vous prévoyez réellement de faire avec le fichier après l'avoir téléchargé ... Plus vous avez de travail à faire sur le fichier, plus vous allez le vouloir près de votre serveur. Si vous avez besoin de faire un traitement immédiat sur le téléchargement, vous voudrez probablement faire une pure solution Rails. Si vous n'avez pas besoin de faire de traitement, ou si ce n'est pas critique, vous peut commencer à envisager des solutions "hybrides" ...

Croyez-le ou non, j'ai eu de la chance en utilisant mod_porter . Mod_porter fait qu'Apache fait un tas de travail que votre application ferait normalement. Cela permet de ne pas bloquer un fil et un tas de mémoire pendant le téléchargement. Il en résulte un fichier local à votre application, pour un traitement facile. Si vous faites attention à la façon dont vous traitez les fichiers téléchargés (flux de réflexion), vous pouvez faire en sorte que l'ensemble du processus utilise très peu de mémoire, même pour ce qui serait traditionnellement des opérations assez coûteuses. Cette approche nécessite très peu de configuration réelle de votre application pour fonctionner et aucune modification réelle de votre code, mais elle nécessite un environnement particulier (serveur Apache), ainsi que la possibilité de le configurer.

J'ai également eu de la chance en utilisant jQuery-File-Upload , qui prend en charge de bonnes choses comme les téléchargements fragmentés et pouvant être repris. Sans quelque chose comme mod_porter, cela peut encore bloquer tout un thread d'exécution pendant le téléchargement, mais cela devrait être décent en mémoire, si cela est fait correctement. Il en résulte également un fichier "fermé" et, par conséquent, facile à traiter. Cette approche nécessitera des ajustements à votre couche de vue à mettre en œuvre et ne fonctionnera pas dans tous les navigateurs.

Vous avez mentionné FTP et bittorrent comme options possibles. Ces options ne sont pas aussi mauvaises que vous ne le pensez, car vous pouvez toujours obtenir les fichiers assez près du serveur. Ils ne s'excluent même pas mutuellement, ce qui est agréable, car (comme vous l'avez souligné), ils nécessitent un client supplémentaire qui peut ou non être présent sur la machine de téléchargement. La façon dont cela fonctionne est, fondamentalement, que vous définissez une zone de vidage qui sera visible par votre application. Ensuite, si vous devez effectuer un traitement, vous exécutez un travail cron (ou autre) pour surveiller cet emplacement pour les téléchargements et déclencher la méthode de traitement de vos serveurs. Cela ne vous donne pas la réponse immédiate que les méthodes ci-dessus peuvent fournir, mais vous pouvez définir un intervalle suffisamment petit pour être assez proche. Le seul véritable avantage de cette méthode est que les protocoles utilisés sont mieux adaptés au transfert de fichiers volumineux, les exigences supplémentaires du client et le processus fragmenté l'emportent généralement sur les avantages de cela, selon mon expérience.

Si vous n'avez besoin d'aucun traitement, le mieux est peut-être de vous rendre directement en S3 avec eux. Cette solution tombe à la seconde où vous avez réellement besoin de faire quoi que ce soit avec les fichiers autres que les serveur en tant qu'actifs statiques ....

Je n'ai aucune expérience de l'utilisation de HTML5 FileSystemAPI dans une application Rails, donc je ne peux pas parler de ce point, bien qu'il semble que cela limiterait considérablement les clients que vous pouvez prendre en charge.

Malheureusement, il n'y a pas de véritable solution miracle - toutes ces options doivent être mises en balance avec votre environnement dans le contexte de ce que vous essayez d'accomplir. Vous ne pourrez peut-être pas configurer votre serveur Web ou écrire de façon permanente sur votre système de fichiers local, par exemple. Pour ce que ça vaut, je pense que jQuery-File-Upload est probablement votre meilleur pari dans la plupart des environnements, car il ne nécessite vraiment que la modification de votre application, vous pouvez donc déplacer une implémentation vers un autre environnement plus facilement.

34
Brad Werth

Ce projet est un nouveau protocole sur HTTP pour prendre en charge le téléchargement de reprise pour les fichiers volumineux. Il contourne Rails en fournissant son propre serveur.

http://tus.io/

4
Bmxer

http://www.jedi.be/blog/2009/04/10/Rails-and-large-large-file-uploads-looking-at-the-alternatives/ a quelques bonnes comparaisons de les options, y compris en dehors de Rails.

Veuillez le parcourir, cela a été utile dans mon cas

Un autre site où aller est également: - http://bclennox.com/extremely-large-file-uploads-with-nginx-passenger-Rails-and-jquery

Veuillez me faire savoir si tout cela ne fonctionne pas

3
Catmandu

Je pense que Brad Werth a trouvé la réponse

une seule approche pourrait être téléchargée directement sur S3 (et même si vous avez besoin d'un retraitement après avoir pu théoriquement utiliser aws lambda pour notifier votre application ... mais pour être honnête, je suppose que je suis ici, je suis sur le point de résoudre le même problème moi-même, je développerai cela plus tard)

http://aws.Amazon.com/articles/1434

si vous utilisez carrierwave

1
equivalent8

Je contournerais le serveur Rails et publierais vos gros fichiers (divisés en morceaux) directement depuis le navigateur vers Amazon Simple Storage . Jetez un œil à cela - post sur le fractionnement de fichiers avec JavaScript. Je suis un peu curieux de savoir comment cette configuration serait performante et j'ai envie de bricoler avec cette configuration ce week-end.

1
eabraham