Mysql: Travailler avec 192 trillions de disques… (oui, 192 trillions)

39

Voici la question ...

Sur 192 milliards de disques, quelles devraient être mes considérations?

Ma principale préoccupation est la vitesse.

Voici la table ...

    CREATE TABLE `ref` (
  `id` INTEGER(13) AUTO_INCREMENT DEFAULT NOT NULL,
  `rel_id` INTEGER(13) NOT NULL,
  `p1` INTEGER(13) NOT NULL,
  `p2` INTEGER(13) DEFAULT NULL,
  `p3` INTEGER(13) DEFAULT NULL,
  `s` INTEGER(13) NOT NULL,
  `p4` INTEGER(13) DEFAULT NULL,
  `p5` INTEGER(13) DEFAULT NULL,
  `p6` INTEGER(13) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY (`s`),
  KEY (`rel_id`),
  KEY (`p3`),
  KEY (`p4`)
    );

Voici les questions ...

SELECT id, s FROM ref WHERE red_id="$rel_id" AND p3="$p3" AND p4="$p4"

SELECT rel_id, p1, p2, p3, p4, p5, p6 FROM ref WHERE id="$id"

INSERT INTO rel (rel_id, p1, p2, p3, s, p4, p5, p6)
VALUES ("$rel_id", "$p1", "$p2", "$p3", "$s", "$p4", "$p5", "$p6")

Voici quelques notes ...

  • Le SELECT sera fait beaucoup plus souvent que le INSERT. Cependant, je souhaite parfois ajouter quelques centaines d'enregistrements à la fois.
  • Sur le plan de la charge, il n'y aura rien pendant des heures, puis peut-être quelques milliers de requêtes en même temps.
  • Je ne pense pas que je puisse plus normaliser (besoin des valeurs p dans une combinaison)
  • La base de données dans son ensemble est très relationnelle.
  • Ce sera de loin la plus grande table (la plus grande suivante est d’environ 900k)

MISE À JOUR (08/11/2010)

Fait intéressant, on m'a donné une deuxième option ...

Au lieu de 192 000 milliards, je pourrais stocker 2,6 * 10 ^ 16 (15 zéros, soit 26 Quadrillions) ...

Mais dans cette seconde option, je n'aurais besoin que de stocker un bigint (18) comme index dans une table. C'est ça - juste la colonne. Donc, je voudrais juste vérifier l'existence d'une valeur. Ajout occasionnel d'enregistrements sans jamais les supprimer.

Cela me fait donc penser qu'il doit exister une meilleure solution que mysql pour simplement stocker des numéros ...

Compte tenu de cette deuxième option, devrais-je prendre ou coller avec le premier ...

[edit] Je viens d'apprendre que des tests ont été effectués - 100 millions de lignes avec cette configuration renvoient la requête en 0.0004 secondes [/ edit]

Sarah
la source
7
Dans quelle mesure utilisez-vous MySQL pour cela? Pourriez-vous être convaincu de passer à un autre dbms si quelqu'un fournit des arguments solides pour le faire?
WheresAlice
3
Milliards comme dans 10 ^ 12 ou comme dans 10 ^ 18?
andol
15
Avec 192 milliards d’enregistrements, vous devez disposer d’un budget vous permettant de poser des questions aux utilisateurs de MySQL, et non à certains forums de discussion.
Remus Rusanu
5
Avec une base de données aussi grande (et évidemment avec un budget décent), pourquoi ne pas utiliser la solution de sereur oracle ou sql dont il a été prouvé qu’elle gérait facilement les bases de données volumineuses?
Jim B
5
Assurez-vous de nous tenir informés lorsque vous implémentez ceci. Je serais certainement intéressé. Vous pourriez aussi vouloir l'écrire pour highscalability.com
Tom O'Connor

Réponses:

30

L'estimation de 7PB par pQd semble raisonnable, et c'est beaucoup de données pour un SGBDR. Je ne suis pas sûr d'avoir jamais entendu parler de quelqu'un faisant 7PB avec un système de disque partagé, sans parler de MySQL. L'interrogation de ce volume de données sur un système de disque partagé va être exceptionnellement lente. Le matériel SAN le plus rapide atteint 20 Go / s, même lorsqu'il est réglé pour les requêtes de diffusion volumineuses. Si vous pouvez vous permettre un matériel SAN de cette spécification, vous pouvez suggérer d'utiliser quelque chose de mieux adapté au travail que MySQL.

En fait, je peine à concevoir un scénario dans lequel vous pourriez avoir un budget pour un sous-système de disque de cette spécification, mais pas pour une meilleure plate-forme de SGBD. Même en utilisant des disques de 600 Go (le plus grand lecteur «entreprise» de 15 Ko actuellement sur le marché), vous avez besoin d'environ 12 000 disques physiques pour stocker 7 Po. Les disques SATA seraient moins chers (et avec un disque de 2 To, il vous faudrait environ 1/3 du nombre), mais un peu plus lentement.

Un SAN de cette spécification d'un fournisseur majeur comme EMC ou Hitachi coûterait plusieurs millions de dollars. La dernière fois que j'ai travaillé avec un équipement SAN auprès d'un fournisseur important, le coût de transfert d'espace sur un IBM DS8000 dépassait 10 000 £ / To, sans aucune déduction pour amortissement pour les contrôleurs.

Vous avez vraiment besoin d'un système de partage rien comme Teradata ou Netezza pour autant de données. Éclater une base de données MySQL peut fonctionner, mais je recommanderais une plate-forme VLDB spécialement conçue. Un système sans partage vous permet également d'utiliser un disque à connexion directe beaucoup moins cher sur les nœuds - jetez un œil à la plate-forme X4550 (thumper) de Sun pour une possibilité.

Vous devez également penser à vos exigences de performance.

  • Qu'est-ce qu'une durée d'exécution acceptable pour une requête?
  • À quelle fréquence allez-vous interroger votre jeu de données?
  • La majorité des requêtes peuvent-elles être résolues à l'aide d'un index (c'est-à-dire vont-elles examiner une petite fraction - disons: moins de 1% - des données) ou doivent-elles effectuer une analyse complète de la table?
  • À quelle vitesse les données vont-elles être chargées dans la base de données?
  • Vos requêtes ont-elles besoin de données à jour ou pourriez-vous utiliser un tableau de rapport actualisé périodiquement?

En résumé, l'argument le plus fort contre MySQL est que vous feriez des backflips pour obtenir des performances de requête décentes de plus de 7 Po de données, si cela est possible. Ce volume de données vous place vraiment dans un territoire sans partage pour créer quelque chose qui l'interrogera raisonnablement rapidement, et vous aurez probablement besoin d'une plate-forme conçue dès le départ pour une opération sans partage. Les disques seuls vont permettre d’économiser le coût de toute plate-forme de SGBD raisonnable.

Remarque: Si vous divisez vos bases de données opérationnelles et de reporting, vous ne devez pas nécessairement utiliser la même plate-forme SGBD pour les deux. Obtenir des insertions rapides et des rapports inférieurs à la seconde à partir de la même table 7PB constituera à tout le moins un défi technique.

Compte tenu de vos commentaires selon lesquels vous pouvez vivre avec une certaine latence dans les rapports, vous pouvez envisager de séparer les systèmes de capture et de génération de rapports, et vous n'avez peut-être pas besoin de conserver les 7 Po de données dans votre système de capture opérationnelle. Considérez une plate-forme opérationnelle telle qu'Oracle (MySQL peut le faire avec InnoDB) pour la capture de données (là encore, le coût des disques sera supérieur au coût du SGBD sauf si vous avez beaucoup d'utilisateurs) et une plate-forme VLDB telle que Teradata, Sybase IQ, RedBrick, Netezza (remarque: matériel propriétaire) ou Greenplum pour la création de rapports

Préoccupé parTonbridgeWells
la source
1
@ConcernedOfTunbridgeW - ils peuvent toujours suivre cette voie: blog.backblaze.com/2009/09/01/… - beaucoup plus amusant que SAN, il ne manque que ~ 120-130 4U de boîtes ... mais je ne suis pas sûr si business 'serait heureux ....
pQd
Il s’agit essentiellement d’un Sun Thumper sur un budget et d’un exemple d’option pour un nœud dans un système sans partage. Je suis sûr que j'ai aussi vu d'autres options pour cela, mais je ne peux pas penser à où. La question n'est pas tant de savoir quel matériel mais quelle plate-forme de base de données.
ConcernedOfTunbridgeWells
Cependant, les observateurs avertis noteront que toute sorte de boîte basée sur l'attachement direct est beaucoup, beaucoup moins chère par TB que tout ce qui est basé sur un SAN, ce qui est au moins un argument important en faveur de quelque chose conçu pour fonctionner sur une plate-forme sans partage. .
ConcernedOfTunbridgeWells Le
@ConcernedOfTunbridgeWells et vous pouvez exécuter toutes ces requêtes / maintenance et tout le reste en parallèle sur plusieurs boîtes [sinon gourmandes en énergie].
pQd
1
@ConcernedOfTunbridgeWells - pour répondre à vos questions ... Il me faut environ 500 requêtes pour revenir sous une seconde, si possible. Je ne le ferai que quelques centaines de fois par jour. Cependant, lorsqu'une requête est exécutée, la table complète doit être analysée. De plus, les actions INSERT ont une priorité plus basse que celles de la touche SELECT, elles n'ont donc pas besoin d'être instantanées. Je peux attendre quelques heures pour que les "nouvelles" données entrent dans la base de données.
Sarah
16

le partager. Un suicide de cette taille est une grande instance (pensez aux restaurations de sauvegarde possibles, aux corruptions de l’espace table, à l’ajout de nouvelles colonnes ou à tout autre processus de «gestion interne») - tout cela est impossible à réaliser dans un délai raisonnable à cette échelle.

calculs simples à partir de l'enveloppe - en supposant des entiers 32 bits pour toutes les colonnes sauf 64 bits id; aucun indice inclus:

8 * 4B + 8B = 40B par ligne [et c'est très optimiste]

192 milliards de rangs 40B chacun nous donne presque 7 PB

Peut-être pouvez-vous repenser le tout, résumer les informations pour générer rapidement des rapports et stocker des enregistrements compressés pour des intervalles de temps donnés lorsque quelqu'un doit approfondir des détails plus approfondis.

questions à répondre:

  • Quels sont les temps d'arrêt acceptables en cas de panne du système / de redémarrage?
  • les temps d'arrêt accessibles lorsque vous devez restaurer une sauvegarde ou extraire un serveur de la production pour une maintenance planifiée.
  • à quelle fréquence et où souhaitez-vous effectuer une sauvegarde?

liens aléatoires - vitesse des insertions:

pQd
la source
Je suis d'accord - 7PB est assez lourd. J'adorerais le repenser et trouver une solution plus légère, mais je dois trouver l'existence (ou la non-existence) d'une combinaison particulière des champs p. Diviser les tables m'a traversé l'esprit - c'est plus sensé, mais cela signifie simplement que j'ai la requête à tour de rôle. Par intérêt, combien de tables recommanderiez-vous de scinder ici?
Sarah
5
@ Sarah - Je recommanderais non seulement de scinder les tables mais aussi les machines. vous pouvez exécuter vos requêtes en parallèle pour obtenir des performances [je le fais à plus petite échelle]. Qu'en est-il des corruptions du système de fichiers ou même de la vérification de routine après le redémarrage du serveur? Je ne suis pas sûr de ce que vous entendez par trouver une combinaison particulière ... peut-être qu'un simple magasin à valeur / clé aiderait? taille de la table - pas plus de quelques dizaines de Go; données sur un seul serveur - pas plus de quelques To. Regardez stackoverflow.com/questions/654594 pour savoir à quel mal de tête s'attendre à une échelle beaucoup plus petite; utilisez innodb_file_per_table
pQd
8

Appelle Percona . Ne passez pas "Go". Ne pas collecter 200 $.

JustinShoffstall
la source
2

Il peut y avoir un autre moyen, plutôt que de stocker des quadrillions de nombres si tout ce que vous voulez faire est de voir s’ils sont dans l’ensemble. Les filtres de Bloom sont une méthode probabiliste, basée sur le hachage de multiples façons. De plus, les faux positifs sont possibles, mais les faux négatifs ne le sont pas. (Donc, on pourrait dire que le nombre est dans le jeu - et se tromper, mais il ne dira pas qu'il n'est pas là, s'il l'était vraiment). Il reste également le problème du grand nombre d'éléments à stocker, mais au moins, cela pourrait réduire quelque peu la taille de la base de données de travail.

Alister Bulman
la source
Cela semble intéressant, bien que je puisse vivre avec de faux négatifs - mais pas avec des faux positifs :)
Sarah
2

Edit: En fait, s’il s’agit simplement de l’existence ou non d’un "enregistrement" à l’emplacement X dans une plage d’entiers, vous pouvez éliminer le datastore et simplement utiliser le bitmap ... Donc, environ 10 machines avec 100 To d’espace disque (si vous avez 10 copies de votre bitmap pour les performances et la sauvegarde) et si vous utilisiez 128 Go de RAM par serveur, vous pourriez insérer un index de groupe de blocs de haute résolution à haute résolution en mémoire pour effectuer une première vérification avant de lancer le disque pour le bit X de 26 Quadrillion .

Je choisirais l'option n ° 2 si vous prenez:

375 machines avec 64 To (32 disques de 2 To) chacune (de manière réaliste 400 machines en cas de pannes) puis mappez simplement les enregistrements sur des ZVOL de 2 To chacun. Ensuite, sur un ou plusieurs serveurs d'index, stockez dans un tableau Judy ou dans un tableau critbit ou simplement en bitmap, un mappage de si vous avez ajouté un enregistrement à l'un des 26 emplacements Quadrillion. L'indice se situerait entre 50 et 100 To et vous pourriez même avoir un index de second niveau indiquant si des enregistrements étaient écrits dans un certain bloc d'adresses de 64 Ko pouvant contenir moins de 64 Go de RAM et fournir un niveau de contrôle initial rapide. si un certain "quartier" était vide ou non.

Ensuite, pour lire cet enregistrement, vous devez d’abord vérifier s’il existe un enregistrement à rechercher en consultant l’index. Si tel est le cas, accédez à la machine # (X) / ZOL # (Y) de cette machine / emplacement d'enregistrement # (Z) au sein de ce blob de 2 To sur la base du calcul d'index simple. La recherche d’un enregistrement est extrêmement rapide et vous pouvez tester le chargement de certaines parties du magasin de données dans différentes bases de données (pendant que vous utilisez le magasin de données pour un vrai travail) et tester les performances pour voir s’ils sont capables de prendre en charge votre base de données complète - ou non, utilisez simplement le magasin de données de cette façon.

Un ZOL est une chose ZFS qui pourrait être considérée comme un fichier fragmenté dans d'autres systèmes de fichiers, des choses similaires s'appliqueraient. Vous pouvez également indexer un certain nombre d'octets sur un disque, mais cela devient délicat si les disques ont des tailles différentes si vous ne plafonnez pas le nombre d'octets utilisés par disque à un niveau qui fonctionne pour tous les disques, à savoir 1,75 To par disque de 2 To. . Ou créez des méta-périphériques de taille fixe, etc.


la source
Bonjour Sarah - Je ne sais pas si vous travaillez encore sur ce projet, mais si vous aviez besoin d’aide, je pourrais créer un prototype de mon idée pour vous sur une machine de 100 To. 400-500 machines selon les besoins. BTW, avez-vous déjà travaillé chez CNET à SF?
1

En plus de régler vos paramètres de base de données comme un fou (utilisez mysqltuner pour vous aider) à essayer de garder vos SELECT en mémoire cache autant que possible, il est possible d’examiner START TRANSACTION / CoMMIT (en supposant InnoDB) lors de l’insertion de vos quelques centaines de rangée par rangée, ce qui vous permet de réduire considérablement votre temps d'insertion. Je créerais également la table en tant que MyISAM et InnoDB et lancerais des tests dessus pour voir ce qui est vraiment plus rapide une fois que la mise en cache est renforcée - ce n'est pas toujours que MyISAM sera plus rapide pour les lectures - consultez ceci:

http://www.mysqlperformanceblog.com/2007/01/08/innodb-vs-myisam-vs-falcon-benchmarks-part-1/

Au cours de vos tests, le nombre de threads simultanés doit également être augmenté et diminué jusqu'à ce que vous trouviez le meilleur compromis pour la quantité de mémoire vive que vous pouvez vous permettre sur le serveur de dédier au réglage des caches. vous constaterez peut-être que, même si vous pouvez prendre en charge davantage de threads en termes mathématiques, la base de données elle-même risque d’empirer si le nombre de threads est trop élevé.

De même, si vous utilisez MyISAM et / ou InnoDB fichier par table, vous pouvez envisager de créer un point de montage de système de fichiers différent pour / var / lib / mysql réglé sur une taille de bloc plus petite et les paramètres de type fs, c.-à-d. Ext3 / ext4 / resiserfs vous pouvez utiliser data = writeback pour le journal et désactiver la mise à jour des temps d'accès sur le système de fichiers pour la vitesse d'E / S.

Troyengel
la source
1
myisam semble être hors de question en raison des exigences de transaction.
pqd
0

Pour la deuxième option, combien de numéros sont susceptibles d’être placés?

S'il y aura seulement un sur 1000, ou 10 000, 100 000, etc., le stockage de plages de nombres utilisés (ou non utilisés) pourrait économiser des milliards d'entrées. par exemple: stocker ('free', 0,100000), ('prendre', 100000,100003), ('free', 100004,584234) - fractionner des lignes en deux ou trois lignes si nécessaire, et indexer sur le premier nombre, rechercher x <= {aiguille} pour voir si la plage contenant le numéro recherché est prise ou libre.

Vous n’avez peut-être même pas besoin des deux statuts. Enregistrez simplement le statut le moins probable.

Alister Bulman
la source