Comment stocker 3 millions d'enregistrements dans un format de valeur clé?

10

Nous devons stocker des informations de base sur 3 millions de produits. Actuellement, l'information est un fichier CSV de 180 Mo qui est mis à jour tous les trimestres.

Il y aura environ 30 000 requêtes par jour, mais les requêtes ne sont qu'un simple magasin de valeurs clés très simple. Il nous suffit de rechercher l'ID du produit et d'afficher le reste des informations (qui seraient toutes dans un seul enregistrement).

C'est pour le Web, donc des performances rapides sont essentielles.

Devrions-nous utiliser MySQL, même si nous n'avons vraiment pas besoin d'une base de données relationnelle? Faut-il simplement générer 3 millions de fichiers html statiques chaque trimestre? Faut-il stocker un CSV d'une ligne pour chaque produit sur quelque chose comme Amazon S3 ou Rackspace Cloud Files? Quelle est la meilleure façon de procéder?

Phil
la source

Réponses:

16

Parce que MySQL est si largement pris en charge et que c'est vraiment une chose assez banale à faire, je suggère d'y aller. À moins que le serveur n'ait au moins quelques Go de mémoire, je suggère de rester avec MySQL plutôt que d'utiliser un système en mémoire.

Une fois que vous commencez à mettre vos données dans une base de données, que ce soit MySQL ou autre, vous constaterez très probablement que vous en trouverez plus d'utilisations. Pour l'instant, vous ne parlez que de paires de valeurs clés, mais le reste des données relatives à vos produits doit être stocké quelque part. Si ce n'est pas dans une base de données, je ne peux pas imaginer que le stockage de données soit très efficace.

Quoi que vous fassiez, ne créez pas ces trois millions de fichiers. Nous avons vu ici un certain nombre de questions résultant déjà des problèmes créés par de nombreux fichiers.

John Gardeniers
la source
13

Vous pouvez utiliser un type de base de données NoSQL dédié, optimisé pour ce type de tâches. Jettes un coup d'oeil à:

  • Redis - Redis est un magasin de valeurs-clés avancé et open source. Il est souvent appelé serveur de structure de données car les clés peuvent contenir des chaînes, des hachages, des listes, des ensembles et des ensembles triés.
  • MemcacheDB - MemcacheDB est un système de stockage de valeurs-clés distribué conçu pour persistant.
  • d'autres (une de ces listes peut être trouvée ici: http://nosql-database.org/ )

Bien sûr, vous pouvez utiliser MySQL ou toute autre base de données relationnelle, mais des solutions spécialement conçues pour des données de type valeur-clé censées être meilleures (sinon à quoi bon les concevoir en premier lieu, sauf éventuellement le fait qu'elles seront beaucoup plus petites (en termes de RAM et HDD)).

LazyOne
la source
Nous pourrions utiliser Redis, mais pensez-vous que cela fonctionnerait sur un P4 avec 2 Go de RAM?
Phil
@Phil Considérant que votre fichier CSV est d'environ 180 Mo - ça devrait aller. Bien que nous l'ayons utilisé dans un projet (une seule fois jusqu'à présent) avec environ 200 000 enregistrements et le serveur avait 8 Go de RAM, il est donc difficile pour moi de comparer.
LazyOne
6

Et maintenant pour quelque chose de complètement différent:

Donné:

  • 180 Mo / produits 3M = 62 octets / produit en moyenne.
  • 30000 requêtes par jour = 0,34 requêtes par seconde
  • Mise à jour trimestrielle = données essentiellement statiques

Solution hors des sentiers battus:

Vider chaque produit en tant qu'enregistrement de ressource TXT et le stocker dans le DNS, par exemple:

$origin products.example.com.

product_1_name IN TXT "product 1 description"
product_2_name IN TXT "product 2 description"
...
product_3000000_name IN TXT "product 3000000 description"

Avantages:

  • extrêmement fiable et fiable (vous en dépendez déjà tous les jours)
  • peut être construit sur à peu près n'importe quelle plate-forme
  • à peu près toutes les langues prennent en charge les requêtes DNS sous une forme ou une autre
  • les serveurs open source et commerciaux prennent en charge différents types de bases de données backend
  • peut être répliqué de manière triviale (il suffit de spécifier plusieurs serveurs de noms)
  • gère les mises à jour atomiques, même lorsqu'elles sont répliquées sur une douzaine de serveurs
  • peut être signé par cryptographie pour garantir l'intégrité des données
  • peut gérer des ordres de grandeur de taux de requêtes par seconde plus élevés (10 000 requêtes par seconde sont facilement traitées avec du matériel de base)

Raisons pour lesquelles cela pourrait être une mauvaise idée:

  • vous devez rechercher les données (DNS est une recherche purement clé / valeur)
  • vous devez masquer les données (le DNS n'a aucune confidentialité)
Theobroma Cacao
la source
1
Si je pouvais donner un point bonus pour l'originalité, cela obtiendrait mon vote. Cependant, je ne dirais pas que le DNS est fiable, car sur un réseau domestique typique, cela semble magique si cela fonctionne et une malédiction si ce n'est pas le cas.
Martin Vilcans
1
Je suis intrigué. En fait, j'aime vraiment cette idée, mais pour moi, j'irais avec quelque chose d'un peu plus essayé / testé comme CouchDB
Tom O'Connor
Tu regardais du Monty Python?
Mark Henderson
Vraisemblablement, ce serait au sein d'un réseau d'entreprise. La fiabilité du DNS devient un problème lorsque les paquets doivent affronter la nature sauvage d'Internet. Étant donné que, par défaut, DNS utilise UDP, vous devez vous fier à la politique de retransmission du résolveur DNS si un paquet est abandonné. Au sein d'un réseau d'entreprise, les chances d'obtenir une perte de paquets suffisamment importante sont (probablement) négligeables. Et vous pouvez toujours forcer DNS à utiliser TCP (quoique à un niveau de performances, jugé non significatif dans ce cas). Et je vous garantis, le DNS obtient plus de recherches que toutes les installations CouchDB combinées :-).
Theobroma Cacao
Le capitaine Hindsight ici. Un mot: blockchain.
datashaman
4

MySQL avec MyISAM et quelques bons index semblent parfaits pour cela. Il y a bien sûr beaucoup d'autres options, mais MySQL est très largement (sinon universellement) pris en charge sur tout hébergeur commercial. Selon la vitesse dont vous avez besoin, memcached peut également être intéressant à regarder , mais sans connaître la taille de chaque paire clé / valeur, le stockage de 3 millions d'entre eux en mémoire peut être une idée encore pire qu'un fichier CSV de 180 Mo (oh attendez, c'est un fichier CSV de 180 Mo, nous savons donc leur taille. Ce doivent être de très petites paires, donc memcached pourrait être encore mieux).

Vous ne voulez pas 3 millions de fichiers HTML statiques, cela endommagera gravement votre système de fichiers. Un CSV sur une ligne, même sur S3, va avoir le même problème. Personne ne veut 3 millions de fichiers dans un dossier.

Mark Henderson
la source
Ce sont de très petites paires ... ce sont des données très basiques comme le prix, la date de fabrication, le numéro d'entrepôt, etc. Moins de 10 colonnes. Vous pensez donc que MySQL est la voie à suivre, vraiment? Le serveur sur lequel il va fonctionner est un P4 avec 2 Go de RAM - je pense que ça devrait aller?
Phil
@Phil - So you think MySQL is the way to go, really?- non, pas vraiment, mais c'est très flexible et comme je l'ai mentionné, pris en charge presque universellement. Cependant, LazyOne a publié quelques bonnes alternatives ci-dessus. Je ne me souvenais pas du terme NoSQL, mais il flottait quelque part dans mon cerveau
Mark Henderson
4

Vous pouvez utiliser la base de données Berkeley qui fait exactement ce genre de chose, même si elle n'a pas été à la mode depuis l'aube de Perl5. Berkeley ne prend en charge que les paires de valeurs clés, et vous liez la base de données entière à un hachage et y accédez en tant que telle.

L'utilisation de Berkeley est bien détaillée dans la plupart des anciennes références Perl sur votre étagère ou essayez le Perldoc pour le module BerkeleyDB CPAN . J'évite généralement d'utiliser Berkeley DB (bien que mon employeur ait beaucoup de code ancien dans lequel il joue en évidence et que certaines des bases de données soient aussi grandes que la vôtre), car ce n'est pas amusant lorsque vos données deviennent plus complexes.

brainbuz
la source
2
BDB est une ancienne école mais très efficace et appropriée à cette situation.
womble
Méfiez-vous de la licence de Berkely DB en.wikipedia.org/wiki/Sleepycat_license, elle nécessite que TOUT le code source soit disponible, pas seulement la partie DB.
WolfmanJM
4

Vous avez signalé votre question comme amazon S3.

Je voudrais attirer votre attention sur l'un de leurs autres produits connexes appelé Amazon SimpleDB.
Il semble que le modèle de données SimpleDB conviendrait bien à votre type d'application.

Ce n'est pas un plugin pour cela, mais vaut la peine d'être étudié, surtout si vous prévoyez d'utiliser les services cloud d'Amazon.

Le modèle de données SDB ressemble à une feuille de calcul.

Voir ici pour plus d'informations à ce sujet: http://aws.amazon.com/simpledb/ Et le modèle de données: http://docs.amazonwebservices.com/AmazonSimpleDB/latest/DeveloperGuide/

Mat
la source
SimpleDB coûte cher. C'est douloureux, dans de nombreux cas.
Tom O'Connor
1

Même si 180 Mo de données peuvent être facilement gérés par n'importe quelle base de données relationnelle, je recommande fortement MongoDB ( http://www.mongodb.org/) au-dessus de MySQL, Redis, MemcacheDB et d'autres magasins de valeurs-clés ou bases de données relationnelles plus simples. La raison en est que pour ce type de problème, MongoDB est le système le plus rapide et le plus expressif à utiliser, permettant des mises à jour dynamiques ultra rapides sans restrictions de schéma, de sorte que vos documents peuvent avoir différents formats si vous le souhaitez. J'étais à une présentation de guardian.co.uk l'autre jour et ils ont pris la décision politique d'interdire toutes les bases de données relationnelles et d'utiliser MongoDB exclusivement pour servir leurs nouvelles. Vous pouvez avoir une idée de la vitesse de leur site Web et de celui qui est en ligne depuis 1995 (le plus ancien journal en ligne du Royaume-Uni). Ils ont également traversé toutes sortes de goulots d'étranglement dans le passé en raison de bases de données relationnelles. Pour 180 Mo, MongoDB va tout servir depuis la mémoire, donc les temps de chargement en sous-ms seront probablement le cas.

snez
la source
0

Il y aura environ 30 000 requêtes par jour, mais les requêtes ne sont qu'un simple magasin de valeurs clés très simple. Il nous suffit de rechercher l'ID du produit et d'afficher le reste des informations (qui seraient toutes dans un seul enregistrement).

Vous avez dit que vos requêtes ne sont que de simples recherches de clés, avec la recherche binaire, vous avez besoin de 21 itérations dans le pire des cas, avec les clés hachées, vos requêtes sont encore plus rapides. Trois millions d'enregistrements sont petits tant que vous évitez les jointures (ou d'autres opérations de type produit cartésien) et les recherches linéaires.

J'ose dire que presque tout irait bien. Votre charge est de 30000 requêtes / jour signifie que (en supposant que votre charge est constante tout au long de la journée) vous avez une seule requête toutes les 20 secondes; Ce n'est pas si mal.

Je recommanderais d'abord de mettre en œuvre la technologie que vous connaissez le mieux, puis de mesurer s'il s'agit vraiment du goulot d'étranglement du système.

Lie Ryan
la source
0

La meilleure façon de procéder dépend vraiment de la qualité et de la nature de vos données et requêtes. Pour commencer, 180 Mo de données dans une seule table pour les produits ne sont pas un problème, quelle que soit la façon dont vous le regardez. Et 30 000 requêtes par jour posent encore moins de problèmes. Avec une base de données correctement configurée, n'importe quel ancien bureau peut gérer cette charge.

D'autres ont déjà souligné vos deux options principales, MySQL ou une base de données noSQL.

Si vous disposez d'un certain nombre d'attributs pour chaque produit (fabricant, prix, numéro d'entrepôt, etc.), la meilleure option consiste à avoir des colonnes pour ces attributs et à convertir vos paires clé / valeur en format de tableau plat, avec un ID de produit comme clé primaire pour cette table. Cela fonctionnera très bien même si certaines colonnes ne sont utilisées que par la moitié des lignes, car pour la plupart des produits, vous n'aurez qu'à exécuter 1 requête pour récupérer tous leurs attributs. ce sont des données sur les produits, je suppose qu'il est fort probable que ce soit la structure de vos données.

Si les attributs varient considérablement en termes de présence et de type de données, il est préférable d'utiliser une base de données noSQL, qui gère ce scénario plus efficacement que les bases de données SQL traditionnelles.

En ce qui concerne les performances: j'ai précédemment travaillé pour une société de commerce électronique, où pendant longtemps le site Web a été fourni avec des données provenant d'un serveur MySQL. Ce serveur avait 2 Go de RAM, la base de données au total était d'env. Avec une taille de 5 Go et une charge maximale, le serveur a traité plusieurs milliers de requêtes par seconde. Oui, nous avions fait beaucoup d'optimisation des requêtes, mais c'est certainement faisable.

Wolfgangsz
la source