web-dev-qa-db-fra.com

MongoDB vs Redis vs. Cassandra pour une solution de stockage en ligne temporaire à écriture rapide

Je crée un système qui suit et vérifie les impressions d'annonces et les clics. Cela signifie qu'il y a beaucoup de commandes d'insertion (environ 90/seconde en moyenne, avec un pic à 250) et certaines opérations de lecture, mais l'accent est mis sur les performances et le rend extrêmement rapide.

Le système est actuellement sur MongoDB, mais j'ai été initié à Cassandra et Redis depuis lors. Serait-ce une bonne idée d'aller à l'une de ces deux solutions, plutôt que de rester sur MongoDB? Pourquoi ou pourquoi pas?

Je vous remercie

39
Mark Bao

Pour une solution de récolte comme celle-ci, je recommanderais une approche en plusieurs étapes. Redis est bon en communication en temps réel. Redis est conçu comme un magasin de clés/valeurs en mémoire et hérite de certains avantages très intéressants d'être une base de données en mémoire: O(1) liste des opérations. Tant qu'il y a RAM à utiliser sur un serveur, Redis ne ralentira pas en poussant à la fin de vos listes, ce qui est bien lorsque vous devez insérer des éléments à un rythme aussi extrême. Malheureusement, Redis ne peut pas fonctionner avec des ensembles de données supérieurs à la quantité de RAM que vous avez (seulement écrit sur le disque, la lecture est pour redémarrer le serveur ou en cas de un crash système) et la mise à l'échelle doit être effectuée par vous et votre application. (Un moyen courant consiste à répartir les clés sur de nombreux serveurs, ce qui est implémenté par certains pilotes Redis, en particulier ceux pour Ruby on Rails.) Redis prend également en charge le simple message de publication/abonnement, qui peut être utile parfois ainsi que.

Dans ce scénario, Redis est "la première étape". Pour chaque type d'événement spécifique, vous créez une liste dans Redis avec un nom unique; par exemple, nous avons "page consultée" et "lien cliqué". Par souci de simplicité, nous voulons nous assurer que les données de chaque liste sont de la même structure; le lien cliqué peut avoir un jeton utilisateur, un nom de lien et une URL, tandis que la page consultée ne peut avoir que le jeton utilisateur et l'URL. Votre première préoccupation est simplement de savoir le fait que cela s'est produit et quelles que soient les données absolument nécessaires dont vous avez besoin sont poussées.

Ensuite, nous avons quelques travailleurs de traitement simples qui prennent cette information insérée frénétiquement des mains de Redis, en lui demandant de retirer un élément de la fin de la liste et de le remettre. Le travailleur peut effectuer les ajustements/déduplication/recherches d'ID nécessaires pour classer correctement les données et les transmettre à un site de stockage plus permanent. Lancez autant de ces travailleurs que nécessaire pour maintenir la charge mémoire de Redis supportable. Vous pouvez écrire les travailleurs dans tout ce que vous souhaitez (Node.js, C #, Java, ...) tant qu'il dispose d'un pilote Redis (la plupart des langages Web le font maintenant) et un pour votre stockage souhaité (SQL, Mongo, etc. )

MongoDB est bon en stockage de documents. Contrairement à Redis, il est capable de gérer des bases de données plus grandes que RAM et il prend en charge le partage/la réplication de lui-même. Un avantage de MongoDB sur les options basées sur SQL est que vous n'avez pas besoin d'avoir un schéma prédéterminé, vous êtes libre de changer la façon dont les données sont stockées comme vous le souhaitez à tout moment.

Je suggérerais cependant Redis ou Mongo pour la phase "de la première étape" de la conservation des données pour le traitement et utiliser une configuration SQL traditionnelle (Postgres ou MSSQL, peut-être) pour stocker les données post-traitées. Le suivi du comportement des clients me semble être des données relationnelles, car vous voudrez peut-être aller "Montrez-moi tous ceux qui consultent cette page" ou "Combien de pages cette personne a-t-elle consultées ce jour-là" ou "Quel jour a eu le plus de téléspectateurs au total? ". Il peut y avoir des jointures ou des requêtes encore plus complexes à des fins analytiques, et les solutions SQL matures peuvent effectuer une grande partie de ce filtrage pour vous; NoSQL (Mongo ou Redis en particulier) ne peut pas effectuer de jointures ou de requêtes complexes sur différents ensembles de données.

28
Skrylar

Je travaille actuellement pour une très grande régie publicitaire et nous écrivons dans des fichiers plats :)

Personnellement, je suis un fan de Mongo, mais franchement, Redis et Cassandra sont peu susceptibles de fonctionner mieux ou moins bien. Je veux dire, tout ce que vous faites est de jeter des trucs en mémoire puis de vider sur le disque en arrière-plan (Mongo et Redis le font).

Si vous recherchez une vitesse fulgurante, l'autre option consiste à conserver plusieurs impressions dans la mémoire locale, puis à les vider le disque toutes les minutes environ. Bien sûr, c'est essentiellement ce que Mongo et Redis font pour vous. Pas une vraie raison impérieuse de déménager.

21
Gates VP

Les trois solutions (quatre si vous comptez des fichiers plats) vous donneront des écritures extrêmement rapides. Les solutions non relationnelles (nosql) vous offriront également une tolérance aux pannes réglable aux fins de la reprise après sinistre.

En termes d'échelle, notre environnement de test, avec seulement trois nœuds MongoDB, peut gérer 2 à 3 000 transactions mixtes par seconde. À 8 nœuds, nous pouvons gérer des transactions mixtes de 12 000 à 15 000 par seconde. Cassandra peut évoluer encore plus haut. 250 lectures n'est (ou devrait être) aucun problème.

La question la plus importante est: que voulez-vous faire avec ces données? Rapports opérationnels? Analyse des séries chronologiques? Analyse de modèle ad hoc? rapports en temps réel?

MongoDB est une bonne option si vous souhaitez pouvoir effectuer une analyse ad hoc basée sur plusieurs attributs au sein d'une collection. Vous pouvez mettre jusqu'à 40 index sur une collection, bien que les index soient stockés en mémoire, alors faites attention à la taille. Mais le résultat est une solution analytique flexible.

Cassandra est un magasin de valeurs-clés. Vous définissez une colonne statique ou un ensemble de colonnes qui agira comme votre index principal dès le départ. Toutes les requêtes s'exécutent sur Cassandra doit être réglé sur cet index. Vous pouvez en mettre un secondaire, mais c'est à peu près aussi loin que possible. Vous pouvez, bien sûr, utiliser MapReduce pour scanner le magasin pour l'attribution non clé, mais ce sera juste cela: une analyse en série à travers le magasin. Cassandra n'a pas non plus la notion d'opérations "like" ou regex sur les nœuds du serveur. Si vous voulez trouver tous les clients dont le prénom commence par "Alex", vous devrez parcourir toute la collection, extraire le prénom pour chaque entrée et l'exécuter à travers une expression régulière côté client.

Je ne connais pas suffisamment Redis pour en parler intelligemment. Désolé.

Si vous évaluez des plates-formes non relationnelles, vous pouvez également envisager CouchDB et Riak.

J'espère que cela t'aides.

12
Data Monk

Je viens de trouver ceci: http://blog.axant.it/archives/236

Citant la partie la plus intéressante:

Ce deuxième graphique concerne Redis RPUSH vs Mongo $ Push vs Mongo insert, et je trouve ce graphique très intéressant. Jusqu'à 5000 entrées mongodb $ Push est plus rapide même par rapport à Redis RPUSH, puis il devient incroyablement lent, probablement le type de tableau mongodb a un temps d'insertion linéaire et donc il devient de plus en plus lent. mongodb peut gagner un peu de performances en exposant un type de liste d'insertion à temps constant, mais même avec le type de tableau de temps linéaire (qui peut garantir une recherche à temps constant), il a ses applications pour de petits ensembles de données.

Je suppose que tout dépend au moins du type de données et du volume. Le meilleur conseil serait probablement de comparer votre ensemble de données typique et de vous voir.

9
drdaeman

Selon le Benchmarking Top NoSQL Databases ( télécharger ici ) je recommande Cassandra. enter image description here

6
Phat H. VU

Si vous avez le choix (et que vous devez vous éloigner des flat fies), j'irais avec Redis. Son incroyablement rapide, gérera confortablement la charge dont vous parlez, mais plus important encore, vous n'aurez pas à gérer le code de rinçage/IO. Je comprends que son assez simple mais moins de code à gérer est mieux que plus.

Vous obtiendrez également des options de mise à l'échelle horizontale avec Redis que vous ne pouvez pas obtenir avec la mise en cache basée sur des fichiers.

3
Ben Hughes

Le problème avec les insertions dans les bases de données est qu'elles nécessitent généralement l'écriture dans un bloc aléatoire sur le disque pour chaque insertion. Ce que vous voulez, c'est quelque chose qui n'écrit sur le disque que toutes les 10 insertions environ, idéalement sur des blocs séquentiels.

Les fichiers plats sont bons. Des statistiques récapitulatives (par exemple, le nombre total de visites par page) peuvent être obtenues à partir de fichiers plats de manière évolutive en utilisant des algorithmes de type carte-réduction de fusion-tri. Ce n'est pas trop difficile de rouler le vôtre.

SQLite prend désormais en charge la journalisation de l'écriture anticipée, qui peut également fournir des performances adéquates.

2
Paul Harrison

Je peux obtenir environ 30 000 insertions/s avec MongoDB sur un simple Dell à 350 $. Si vous n'avez besoin que d'environ 2k inserts/sec, je m'en tiendrai à MongoDB et le partagerai pour l'évolutivité. Peut-être aussi envisager de faire quelque chose avec Node.js ou quelque chose de similaire pour rendre les choses plus asynchrones.

2
EhevuTov