web-dev-qa-db-fra.com

Stockage d'images évolutif

Je conçois actuellement une architecture pour une application Web qui devrait également fournir une sorte de stockage d'images. Les utilisateurs pourront télécharger des photos comme l'une des principales caractéristiques du service. La visualisation de ces images sera également l'un des principaux usages (via le Web).

Cependant, je ne sais pas comment réaliser un tel composant de stockage d'images évolutif dans mon application. J'ai déjà pensé à différentes solutions mais en raison d'expériences manquantes, j'ai hâte d'entendre vos suggestions. Outre les images, les métadonnées doivent également être enregistrées. Voici mes premières réflexions:

  1. Utilisez un système de fichiers (distribué) comme HDFS et préparez des serveurs Web dédiés en tant que "clients de système de fichiers" afin de sauvegarder les images téléchargées et les demandes de service. Les métadonnées d'image sont enregistrées dans une base de données supplémentaire, y compris les informations de chemin de fichier pour chaque image.

  2. Utilisez un système orienté BigTable comme HBase au-dessus de HDFS et enregistrez des images et des métadonnées ensemble. Encore une fois, les serveurs Web relient les téléchargements et les demandes d'images.

  3. Utilisez une base de données complètement sans schéma comme CouchDB pour stocker à la fois des images et des métadonnées. En outre, utilisez la base de données elle-même pour le téléchargement et la livraison à l'aide de l'API RESTful basée sur HTTP. (Question supplémentaire: CouchDB enregistre les blobs via Base64. Peut-il cependant renvoyer des données sous forme d'image/jpeg, etc.)?

53
b_erb

Nous utilisons CouchDB pour cela, enregistrant les images en tant que "pièce jointe". Mais après un an, les fichiers de la base de données CouchDB de plusieurs dizaines de Go se sont avérés être un casse-tête. Par exemple, la réplication CouchDB a toujours des problèmes si vous l'utilisez avec des documents de très grande taille.

Nous venons donc de réécrire notre logiciel pour utiliser CouchDB pour les informations sur l'image et Amazon S3 pour le stockage réel de l'image. Le code est disponible sur http://github.com/hudora/huImages

Vous souhaiterez peut-être configurer un service de stockage compatible Amazon S3 sur site pour votre projet. Cela vous permet de rester flexible et de laisser l'option Amazon sans avoir besoin de services externes pour l'instant. Walruss semble devenir le clone S3 le plus populaire et évolutif.

Je vous invite également à vous pencher sur la conception de Livejournal avec leurs excellentes offres Open Source MogileFS et Perlbal . Cette combinaison est probablement la configuration de diffusion d'images la plus célèbre.

Aussi Flickr Architecture peut être une source d'inspiration, bien qu'ils n'offrent pas de logiciel Open Source au public, comme Livejournal.

43
max

"Question supplémentaire: CouchDB enregistre les blobs via Base64."

CouchDB n'enregistre pas les blobs en Base64, ils sont stockés en binaire direct. Lors de la récupération d'un document JSON avec ?attachments=true nous convertissons le binaire sur disque en Base64 afin de l'ajouter en toute sécurité à JSON mais c'est juste une chose au niveau de la présentation.

Voir Pièces jointes autonomes .

CouchDB sert des pièces jointes avec le type de contenu avec lequel elles sont stockées, il est possible, en fait commun, de serveur de pièces jointes HTML, CSS et GIF/PNG/JPEG directement aux navigateurs.

Les pièces jointes peuvent être diffusées en continu et, dans CouchDB 1.1, même prendre en charge l'en-tête Range (pour le streaming multimédia et/ou la reprise d'un téléchargement interrompu).

14
Robert Newson

Utilisez Seaweed-FS (anciennement appelé Weed-FS), une implémentation du papier de meule de foin de Facebook.

Seaweed-FS est très flexible et réduit à l'essentiel. Il a été créé pour stocker des milliards d'images et les servir rapidement.

8
chrislusf

Peut-être jetez un oeil à la description de Facebook hayStack

Aiguille dans une botte de foin: stockage efficace de milliards de photos

3
Leen Toelen

Nous utilisons MogileFS. Nous sommes de petits utilisateurs avec moins de 8 To et quelque 50 millions de fichiers. Nous sommes passés du stockage dans Amazon S3 il y a quelques années pour mieux contrôler les noms de fichiers et les performances.

Ce n'est pas le plus joli logiciel, mais il est très "testé sur le terrain" et, fondamentalement, tous les utilisateurs l'utilisent de la même manière que vous.

3
Ask Bjørn Hansen

Avez-vous envisagé Amazon Web Services? S3 est un stockage de fichiers basé sur le Web et SimpleDB est un magasin de clés -> d'attributs. Les deux sont performants et hautement évolutifs. C'est plus cher que de maintenir vos propres serveurs et configurations (en supposant que vous allez le faire vous-même et ne pas embaucher de personnes), mais vous êtes opérationnel beaucoup plus rapidement.

Edit: je reprends cela - c'est plus cher à long terme à des volumes élevés, mais pour un faible volume, il bat le coût initial d'achat de matériel.

S3: http://aws.Amazon.com/s3/ (vous pouvez stocker vos fichiers image ici, et pour des performances peut-être avoir un cache d'image sur votre serveur, ou pas)

SimpleDB: http://aws.Amazon.com/simpledb/ (les métadonnées peuvent aller ici: mappage de l'ID d'image avec les données que vous souhaitez stocker)

Edit 2: Je ne savais même pas à ce sujet, mais il existe un nouveau service Web appelé Amazon CloudFront ( http://aws.Amazon.com/cloudfront/ ). C'est pour la livraison rapide de contenu Web, et il s'intègre bien avec S3. Un peu comme Akamai pour vos images. Vous pouvez l'utiliser à la place du cache d'images.

3
danben

Dans le cadre de Cloudant, je ne veux pas pousser le produit .... mais BigCouch résout ce problème dans ma pile d'applications scientifiques (physique - rien à voir avec Cloudant, et certainement rien à voir avec le profit!). Il marie la simplicité de la conception CocuhDB avec le partage automatique et l'évolutivité qui manquent dans CouchDB à serveur unique. Je l'utilise généralement pour stocker un plus petit nombre de gros fichiers (multi-Go) et un grand nombre de petits fichiers (100 Mo ou moins). J'utilisais S3, mais les coûts d'obtention commencent en fait à s'additionner pour les petits fichiers auxquels on accède à plusieurs reprises.

2
Mike Miller

Ok, si toutes ces choses AWS ne vont pas fonctionner, voici quelques réflexions.

En ce qui concerne (3), si vous mettez des données binaires dans une base de données, les mêmes données vont sortir. Ce qui en fait un jpeg, c'est le format des données, pas ce que la base de données pense qu'il s'agit. Ce qui fait que le client (navigateur Web) pense que c'est un JPEG est lorsque vous définissez le Content-type en-tête à image/jpeg. Vous pouvez également le définir sur autre chose (non recommandé) comme du texte et c'est ainsi que le navigateur essaiera de l'interpréter.

Pour le stockage sur disque, j'aime CouchDB pour sa simplicité, mais HDFS fonctionnerait certainement. Voici un lien vers un article sur la diffusion de contenu d'image de CouchDB: http://japhr.blogspot.com/2009/04/render-couchdb-images-via-sinatra.html

Edit: voici un lien vers une discussion utile sur la mise en cache des images dans memcached vs les servir à partir du disque sous linux/Apache.

1
danben

J'ai expérimenté certaines des fonctionnalités de _update disponibles pour les serveurs de vue CouchDB dans mon Python.

Une chose vraiment cool que j'ai faite était une fonction de mise à jour pour les téléchargements d'images afin que je puisse utiliser PIL pour créer des miniatures et d'autres images associées et les attacher au document lorsqu'elles sont poussées vers CouchDB.

Cela peut être utile si vous avez besoin d'une manipulation d'image et que vous souhaitez réduire la quantité de code et d'infrastructure dont vous avez besoin.

1
mikeal

J'ai écrit un magasin d'images au-dessus de cassandra. Nous avons beaucoup et écrit et les lectures aléatoires en lecture/écriture sont faibles. Pour un rapport de lecture/écriture élevé, je vous suggère mongodb (GridFs).

1
baklarz2048