Jump to content

Architecture d'une grosse base de données


Recommended Posts

Bonjour à tous :)

Voilà, je suis amené à enregistrer un très grand nombre d'informations dans une base de données : de l'ordre des 500000 nouveaux enregistrements par jour (amené à augmenter mais pas exponentiellement, peut-être à doubler/tripler dans les prochains mois).

Une donnée enregistrée ne sera que très improbablement modifiée, mais sera lue régulièrement.

Un enregistrement correspond à une ligne dans une table contenant 4 clefs étrangères (INT7) et trois autres champs INT10.

Ma question est donc : à votre avis, quelle genre de structure serait idéale pour stocker ce genre d'informations (clustering avec plusieurs mini serveurs, ...) ? Je n'ai aucune expérience en d'aussi gros volumes de données et suis donc "un peu" perdu, jusqu'ici je n'avais l'habitude que d'utiliser un simple serveur mysql pour chaque projet.

Merci par avance pour toute aide éventuelle :)

Link to post
Share on other sites

A mon avis il va falloir envisager autre chose que mysql, même si ces dernières années de gros progrès ont été faits mysql reste loin derrière de vrai base relationnelle comme postgres par exemple. Les index pourront être mieux optimisés, et donc la recherche en sera facilité

Suivant le type d'index si sera peut être optimum de partitionner la base

Ensuite

Link to post
Share on other sites

La première question c'est de savoir ce que tu fais de ces données (quels types de requêtes, à quelle fréquence), et si les données doivent être conservées ad vitam ou si tu dois progressivement supprimer les données les plus anciennes (ce qui donne déjà une idée de la taille maximale de la base). Ca va dicter les index, les partitionnements possibles/désirables, et les ressources que ça consomme (en I/O en particulier).

Les types des champs, tu ferais mieux de les compter en bits (int/bigint etc.) plutôt qu'en chiffres. 10 chiffres ça peut faire 32 bits (si 4 milliards suffisent) ou 64 (s'il t'en faut plus, ce serait donc un bigint plutôt qu'un int). D'un coup ça peut changer du simple au double la taille de ta table.

Jacques.

Link to post
Share on other sites

Merci pour vos réponses :)

Pour ce qui est de la conservation des données, oui, en l'état actuel les données sont indéfiniment conservées. Je dois voir s'il n'est pas possible de ne conserver que des données intermédiaires (genre de valeurs moyennes) pour les plus anciennes, mais je n'ai pas trop d'espoir de ce côté là...

Les requêtes sont simples : sélection d'un ensemble de valeurs en fonction de deux des INTs (bornes min et max), calcul de moyenne, du min et du max.

La fréquence de lecture n'est pas encore bien définie, mais devrait tourner autour de la 50aine de requêtes/seconde uniquement.

L'écriture se fait en continu (pas de pic, pas spécialement de temps mort non plus, donc à 500k requêtes on est à une moyenne d'un peu moins de 6 par seconde), mais la nature du site m'autorise à faire un gros import tous les minutes par exemple plutôt que plusieurs valeurs uniques par seconde...

Bref, la charge de calcul n'est pas extraordinaire, seul le volume de données l'est réellement.

Pour la taille de champs, 32 bits suffisent.

Merci en tous cas pour le retour :)

Link to post
Share on other sites

Il existe des bases des données spécialisés dans les calculs mais qui sont à la ramasse dès qu'il s'agit de faire des requêtes compliquées.

Par exemple:


/>http://infinidb.org/
/>http://www.infobright.com/

J'utilise la première en production sur une table qui grossi d'environ 400k de lignes par jour pour un total de 177 Millions de lignes et 11.7 Go et ... elle s'en sort plutôt bien.

Avec MySQL, on ne pouvait plus rien faire car des requêtes super simples prenaient beaucoup trop de temps (sans jointure, uniquement des filtres sur des dates/entiers/enums avec des groupements).

Le gros soucis avec MySQL, c'est que sur les grosses tables, la base de données s'y perd avec les index ... et MySQL sans index n'aime pas les full scan à gogo.

Trop d'index dans une base de données MySQL plombent complètement les performances de cette dernière.

Link to post
Share on other sites

Ah, je ne savais pas que ce genre de bases existait mais ça a l'air de correspondre assez bien à ce que je cherche. Merci :)

Je vais regarder aussi du côté de Cassandra...

Le tout étant évidemment de trouver un système qui marche à l'instant I mais qui soit aussi extensible car un grand nombre de données sont appelées à être ajoutées !!!

Link to post
Share on other sites

Pour ce qui est de la conservation des données, oui, en l'état actuel les données sont indéfiniment conservées. Je dois voir s'il n'est pas possible de ne conserver que des données intermédiaires (genre de valeurs moyennes) pour les plus anciennes, mais je n'ai pas trop d'espoir de ce côté là...

Les requêtes sont simples : sélection d'un ensemble de valeurs en fonction de deux des INTs (bornes min et max), calcul de moyenne, du min et du max.

La fréquence de lecture n'est pas encore bien définie, mais devrait tourner autour de la 50aine de requêtes/seconde uniquement.

Ben ça dépend beaucoup de tes bornes... Si ça aboutit à récupérer quelques lignes ça ne devrait pas poser de problème, mais si tu dois récupérer des dizaines/centaines de milliers de lignes, ça risque de faire mal. Et si tu as des bornes sur deux des colonnes (par opposition à une valeur fixe sur une colonne + une étendue sur une autre), ça risque de rendre l'utilisation d'index quasiment impossible, donc tu finis en full scans en permanence, il n'y a pas de miracle. Le partitionnement peut alors aider, mais ça dépend beaucoup de tes requêtes exactes (si tu peux utiliser des bornes sur n'importe quelle combinaison de deux colonnes sur 4, t'es mal barré).

L'écriture se fait en continu (pas de pic, pas spécialement de temps mort non plus, donc à 500k requêtes on est à une moyenne d'un peu moins de 6 par seconde), mais la nature du site m'autorise à faire un gros import tous les minutes par exemple plutôt que plusieurs valeurs uniques par seconde...

Avec postgresql le fait de limiter le nombre de transactions (en regroupant ces imports dans une transaction) peut te faire gagner pas mal en perfs, je ne sais pas ce que ça donne avec mysql. Et tu ne peux pas stocker des valeurs agrégées? Genre min, max, total, nb?

Bref, la charge de calcul n'est pas extraordinaire, seul le volume de données l'est réellement.

Ben le volume peut dicter la charge comme expliqué plus haut. Faire une requête qui fait un select d'une ligne avec un index ce n'est pas la même chose que des full scans d'une table de plusieurs centaines de Go, là tu vas avoir beaucoup de mal à faire 50 requêtes/seconde!

Jacques.

Link to post
Share on other sites

Pour ce qui est de mes bornes, ce sont deux champs bien définis qui marquent la période de validité d'une valeur : valeur valable entre le cycle x et le cycle y. Dans l'idée on peut voir ça comme des dates mais une itération de l'algorithme se déroulant en un temps assez long, je dois fonctionner par numéro d'itération plutôt (afin de retrouver les valeurs par itération, chose évidemment impossible par date). La seconde borne est donc forcément supérieure à la première.

Je vais voir pour ce qui est des performances en regroupant les transactions, mais le fait d'utiliser postgre n'est pas un problème étant donné qu'il est facilement utilisable avec PHP (l'interface sera un site web PHP) :)

Je peux aussi dans une certaine mesure stocker des valeurs agrégées, en fait pour tout cycle terminé (de base 8 cycles par jour, l'idéal serait à l'avenir de l'augmenter à 12 ou plus, mais là ça dépendra de la puissance de calcul qu'on pourra donner au programme... ^^'), mais mes opérations de moyenne, min et max se faisant sur de petits ensembles (à peu près 4 en moyenne), je devrais rajouter 75% d'enregistrements en plus (25% par opération). Évidemment point de vue calcul c'est assez intéressant, mais point de vue stockage ça alourdi encore les données.

Je ne sais pas si je suis assez clair, en tous cas merci pour ces indications :)

Link to post
Share on other sites

Je débarque un peu tard, mais de mon coté je n'ai aucun soucis à stocker ce genre de chose avec du MySQL, dès lors qu'on utilise InnoDB/XtraDB et non le MyISAM. Après comme l'explique jcaron il peut y avoir beaucoup d'autres facteurs derrière, qui feront que ça tournera plus ou moins bien, mais dans l'ensemble je n'ai vraiment rien à reprocher à MySQL sur du "gros volumes" (base de 40Go sur une machine ne disposant que de 12Go de mémoire).

Link to post
Share on other sites
  • 3 weeks later...

Je n'ai pas reçu de notification à cette discussion .. donc je reprends avec un peu de retard.

C'est surtout l'histoire des bornes qui fait ramer MySql et à ce moment là comme il a été dit, les index ne servent plus à rien.

Sur notre table de 185 Millions de ligne (17Go), chaque ligne contient une date. Si je fais des recherches sur un interval de 1-2 semaines (et avec 3-4 filtres sur des entiers en plus et un group by), j'ai des meilleurs performance avec MySQL, si j'étends la même recherche sur 6 mois, infiniDB sera 30 fois plus rapide que MySQL.

Maintenant, il faut dire que ma table est consolidé et donc quand je fais mes requêtes je ne fais aucune jointure dessus. Enfin ceci dit je suis pas DBA, infiniDB nous a été recommandé par un consultant de mySQL.

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...