Frage Mysql: Arbeiten mit 192 Trillion Records ... (Ja, 192 Billionen)


Hier ist die Frage ...

Betrachtet man 192 Billionen Datensätze, was sollten meine Überlegungen sein?

Mein Hauptanliegen ist Geschwindigkeit.

Hier ist der Tisch ...

    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`)
    );

Hier sind die Fragen ...

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")

Hier sind einige Notizen ...

  • Die SELECTs werden viel häufiger durchgeführt als die INSERT. Gelegentlich möchte ich jedoch ein paar hundert Datensätze gleichzeitig hinzufügen.
  • Lastweise wird es für Stunden nichts geben, vielleicht ein paar tausend Anfragen auf einmal.
  • Denke nicht, dass ich mehr normalisieren kann (brauche die p-Werte in einer Kombination)
  • Die Datenbank als Ganzes ist sehr relational.
  • Dies wird der mit Abstand größte Tisch sein (der nächstgrößte ist etwa 900k)

UPDATE (08/11/2010)

Interessanterweise habe ich eine zweite Option bekommen ...

Statt 192 Billionen konnte ich speichern 2.6 * 10 ^ 16 (15 Nullen, also 26 Quadrillion) ...

Aber in dieser zweiten Option würde ich nur eine Bigint (18) als Index in einer Tabelle speichern müssen. Das ist es - nur die eine Spalte. Also würde ich nur nach der Existenz eines Wertes suchen. Gelegentlich Datensätze hinzufügen, nie löschen.

Das lässt mich denken, dass es eine bessere Lösung als mysql geben muss, um Zahlen einfach zu speichern ...

Angesichts dieser zweiten Option, sollte ich es nehmen oder bei der ersten bleiben ...

[bearbeiten] Habe gerade Neuigkeiten über einige Tests erhalten - 100 Millionen Zeilen mit diesem Setup geben die Abfrage in 0,0004 Sekunden zurück [/bearbeiten]


39
2017-08-08 14:15


Ursprung


Wie setzen Sie MySQL dafür ein? Könnten Sie davon überzeugt werden, zu einem anderen dbms zu wechseln, wenn jemand dafür solide Argumente vorlegt? - kaerast
Billionen wie in 10 ^ 12 oder wie in 10 ^ 18? - andol
Bei 192 Billionen Datensätzen sollten Sie über ein Budget verfügen, mit dem Sie Fragen an MySQL-Committer stellen können, nicht an einige Diskussionsforen. - Remus Rusanu
Mit einer so großen Datenbank (und natürlich einem anständigen Budget) warum nicht mit Orakel oder SQL-Serer-Lösung gehen, die nachweislich große DBs handhaben kann? - Jim B
Achten Sie darauf, uns auf dem Laufenden zu halten, wenn Sie dies umsetzen. Ich wäre sicherlich interessiert. Vielleicht möchten Sie es auch für schreiben highscalability.com - Tom O'Connor


Antworten:


pQd's Schätzung von 7PB scheint vernünftig, und das ist eine Menge Daten für ein RDBMS. Ich bin mir nicht sicher, ob ich je von jemandem gehört habe, der 7PB mit einem gemeinsam genutzten Plattensystem macht, geschweige denn MySQL. Das Abfragen dieses Datenvolumens mit einem beliebigen gemeinsam genutzten Festplattensystem wird unbrauchbar langsam sein. Die schnellste SAN-Hardware erreicht selbst bei großen Streaming-Abfragen eine Kapazität von 20 GB / s. Wenn Sie sich SAN-Hardware mit dieser Spezifikation leisten können, können Sie sich auf etwas Besseres als MySQL gefasst machen.

In der Tat, ich kämpfe um ein Szenario, wo Sie ein Budget für ein Disk-Subsystem dieser Spezifikation, aber nicht für eine bessere DBMS-Plattform haben könnte. Selbst mit 600-GB-Festplatten (das größte derzeit auf dem Markt erhältliche 15-KByte-Laufwerk) sind Sie für etwa 12.000 physische Festplattenlaufwerke bereit, um 7 PB zu speichern. SATA-Festplatten wären billiger (und mit 2 TB Festplatten würden Sie etwa 1/3 der Anzahl benötigen), aber ziemlich viel langsamer.

Ein SAN dieser Spezifikation von einem großen Anbieter wie EMC oder Hitachi würde viele Millionen Dollar kosten. Beim letzten Mal, als ich mit SAN-Geräten eines großen Anbieters gearbeitet habe, betrugen die Übertragungskosten für den Platz auf einem IBM DS8000 mehr als 10.000 £ / TB, ohne Berücksichtigung von Kapitalzuschüssen für die Controller.

Sie brauchen wirklich ein geteiltes Nichtsystem wie Teradata oder Netezza für so viele Daten. Das Erstellen einer MySQL-Datenbank funktioniert möglicherweise, aber ich würde eine speziell dafür entwickelte VLDB-Plattform empfehlen. Ein Shared-Nothing-System ermöglicht es Ihnen auch, eine viel billigere Direct-Attach-Disk auf den Knoten zu verwenden - werfen Sie einen Blick auf Suns X4550 (Thumper) -Plattform für eine Möglichkeit.

Sie müssen auch an Ihre Leistungsanforderungen denken.

  • Was ist eine akzeptable Laufzeit für eine Abfrage?
  • Wie oft werden Sie Ihren Datensatz abfragen?
  • Kann die Mehrheit der Abfragen mit einem Index gelöst werden (d. H. Werden sie einen kleinen Bruchteil - sagen wir: weniger als 1% - der Daten betrachten), oder müssen sie einen vollständigen Tabellenscan durchführen?
  • Wie schnell werden Daten in die Datenbank geladen?
  • Benötigen Ihre Abfragen aktuelle Daten oder können Sie mit einer regelmäßig aktualisierten Berichtstabelle leben?

Kurz gesagt, das stärkste Argument gegen MySQL ist, dass Sie Backflips ausführen würden, um eine akzeptable Abfrageleistung über 7 PB an Daten zu erhalten, wenn dies überhaupt möglich ist. Diese Menge an Daten versetzt Sie in ein Shared-Nothing-Territorium, in dem Sie etwas schnell abfragen können, und Sie werden wahrscheinlich von Anfang an eine Plattform benötigen, die für den Shared-Nothing-Betrieb entwickelt wurde. Die Festplatten alleine werden die Kosten einer vernünftigen DBMS-Plattform in den Schatten stellen.

Hinweis: Wenn Sie Ihre Betriebs- und Berichtsdatenbanken aufteilen, müssen Sie nicht unbedingt die gleiche DBMS-Plattform für beide verwenden. Schnelle Einfügungen und Sub-Sekunden-Berichte aus der gleichen 7PB-Tabelle werden zumindest eine technische Herausforderung sein.

Aufgrund Ihrer Kommentare, dass Sie bei der Berichterstellung mit einer gewissen Latenz rechnen können, sollten Sie separate Erfassungs- und Berichterstattungssysteme in Erwägung ziehen, und Sie müssen möglicherweise nicht alle 7 PB an Daten in Ihrem betrieblichen Erfassungssystem aufbewahren. Betrachten Sie eine operative Plattform wie Oracle (MySQL kann dies mit InnoDB tun) für die Datenerfassung (wieder werden die Kosten der Festplatten allein die Kosten des DBMS in den Schatten stellen, es sei denn, Sie haben eine Menge von Benutzern) und eine VLDB - Plattform wie Teradata,  Sybase IQ,  Roter Ziegelstein,  Netezza (Hinweis: proprietäre Hardware) oder Grüne Pflaume für die Berichterstattung


30
2017-08-08 16:05



@ConcernedOfTunbridgeW - sie können immer so gehen: blog.backblaze.com/2009/09/01/ ... - viel mehr Spaß als SAN, nur ~ 120-130 4U Boxen benötigt ... aber ich bin mir nicht sicher, ob 'das Geschäft' würde glücklich sein .... - pQd
Im Wesentlichen ein Sun Thumper mit einem Budget und wirklich ein Beispiel für eine Option für einen Knoten in einem Shared-Nothing-System. Ich bin mir sicher, dass ich auch andere Möglichkeiten gesehen habe, aber ich kann mir nicht vorstellen wo. Die Frage ist nicht so sehr welche Hardware, sondern welche Datenbankplattform. - ConcernedOfTunbridgeWells
Allerdings werden aufmerksame Beobachter feststellen, dass jede Art von Direct-Attach-basierter Box wie diese viel billiger ist als alles, was auf einem SAN basiert, was zumindest ein wichtiges Argument für etwas ist, das auf einer Shared-Nothing-Plattform arbeiten soll . - ConcernedOfTunbridgeWells
@ConcernedOfTunbridgeWells und Sie können alle diese Abfragen / Wartung und alles andere parallel auf mehreren [sonst Power hungry] Boxen ausführen. - pQd
@ConcernedOfTunbridgeWells - um Ihre Fragen zu beantworten ... Ich brauche ungefähr 500 Anfragen, um innerhalb von einer Sekunde zurückzukommen, wenn möglich. Ich werde das nur ein paar hundert Mal am Tag machen. Wenn eine Abfrage ausgeführt wird, muss die vollständige Tabelle jedoch überprüft werden. Auch die INSERTs haben eine niedrigere Priorität als die SELECTs, so dass sie nicht in der Nähe von Instant sein müssen. Ich kann ein paar Stunden warten, bis "neue" Daten in die Datenbank gelangen. - Sarah


Scherbe es. In dieser Größe mit einer großen Instanz ist ein Selbstmord - denken Sie über mögliche Backup-Wiederherstellungen, Tabellenplatz Korruption, Hinzufügen neuer Spalten oder andere "Haushalten" Prozesse - all diese sind unmöglich in angemessener Zeit in diesem Maßstab zu tun.

einfache Rückseite der Hüllkurvenberechnungen - Annahme von 32-Bit-Ganzzahlen für alle Spalten außer 64-Bit-ID; keine Indizes enthalten:

8 * 4B + 8B = 40B pro Zeile [und das ist sehr optimistisch]

192 Trillionen Reihen 40B gibt uns fast 7 PB

Vielleicht können Sie das Ganze überdenken, Informationen für eine schnelle Berichterstellung zusammenfassen und komprimierte Datensätze für bestimmte Zeitintervalle speichern, wenn sich jemand in tiefere Details vertiefen muss.

Fragen zu beantworten:

  • Was ist eine akzeptable Ausfallzeit für den Fall, dass das System abstürzt / neu gestartet wird?
  • Die verfügbare Ausfallzeit, wenn Sie eine Sicherung wiederherstellen oder den Server für geplante Wartungsarbeiten aus der Produktion nehmen müssen.
  • Wie oft und wo möchten Sie sichern?

zufällige Links - Geschwindigkeit der Einsätze:


16
2017-08-08 14:42



Ich stimme zu - 7PB ist ziemlich schwer. Ich würde es lieben, es zu überdenken und eine leichtere Lösung zu finden, aber ich muss die Existenz (oder Nicht-Existenz) einer bestimmten Kombination der p-Felder finden. Das Austeilen der Tische kam mir in den Sinn - es ist vernünftiger, aber dann heißt es nur, dass ich die Tabelle nacheinander anfrage. Wie viele Tische würden Sie aus Interesse hier aufteilen? - Sarah
@Sarah - ich empfehle nicht nur das Aufteilen in Tabellen, sondern auch Maschinen. Sie können Ihre Abfragen parallel ausführen, um Leistung zu erzielen [ich mache es in kleinerem Maßstab]. Was ist mit Dateisystembeschädigungen oder sogar Routineüberprüfungen nach dem Neustart des Servers? Ich bin nicht sicher, was meinst du damit, eine bestimmte Kombination zu finden ... vielleicht würde ein einfacher Schlüssel-Wert-Laden helfen? Tischgröße - nicht mehr als ein paar Dutzend GB; Daten auf einem einzelnen Server - nicht mehr als ein paar TB. ansehen stackoverflow.com/questions/654594 zu wissen, welche Kopfschmerzen in viel geringerem Umfang zu erwarten sind; Verwenden Sie innodb_file_per_table - pQd


Anruf Percona. Übergeben Sie nicht "Go". Sammle keine $ 200 ein.


8
2017-09-22 06:28





Es kann einen anderen Weg geben, als Billiarden von Zahlen zu speichern, wenn Sie nur sehen wollen, ob sie in der Menge sind. Bloom-Filter sind eine probabilistische Methode, indem sie auf mehrere Arten hashen. Falsche Positivwerte sind ebenfalls möglich, falsche Negative jedoch nicht. (So ​​könnte es heißen, dass die Zahl im Set ist - und falsch sein, aber es wird nicht sagen, dass es nicht da ist, wenn es wirklich war). Es gibt auch noch das Problem mit der großen Anzahl von zu speichernden Elementen, aber zumindest könnte es die Arbeitsdatenmenge etwas verringern.


2
2017-08-11 11:35



Klingt interessant, obwohl ich mit falschen Negativen leben könnte - aber nicht die falschen Positives :) - Sarah


Bearbeiten: Eigentlich, wenn es nur die Existenz oder nicht einer "Aufnahme" an der Stelle X in einem Bereich von ganzen Zahlen ist, könnten Sie den Datenspeicher beseitigen und nur die Bitmap verwenden ... So, 10 oder so Maschinen mit 100 TB Speicherplatz (Sie haben also 10 Kopien Ihrer Bitmap für Leistung und Backup) und wenn Sie 128 GB RAM pro Server haben, könnten Sie einen Blockgroupindex mit hoher Auflösung der obersten Ebene in den Speicher einbauen, um eine erste Überprüfung durchzuführen, bevor Sie die Platte für Bit X von 26 Quadrillion treffen .

Ich würde für Option # 2 gehen Wenn du nimmst:

375 Maschinen mit je 64 TB (32 2 TB Laufwerke) (realitätsnah 400 Maschinen für Ausfälle) dann ordnen Sie die Datensätze nur ZVOLs zu, die jeweils 2 TB groß sind. Speichern Sie dann auf einem oder mehreren Index-Servern in einem Judy-Array oder einem Critbit-Array oder nur einer einfachen Bitmap eine Zuordnung, ob Sie einen Datensatz zu diesem 1 von 26 Quadrillion-Standorten hinzugefügt haben. Der Index würde zwischen 50 und 100 TB liegen, und Sie könnten sogar einen Index der zweiten Ebene angeben, wenn Datensätze in einen bestimmten 64-KByte-Adressblock geschrieben würden, der in weniger als 64 GB RAM passen würde und eine schnelle Erstprüfung ermöglichen würde wenn eine bestimmte "Nachbarschaft" leer war oder nicht.

Um diesen Datensatz zu lesen, würden Sie zuerst prüfen, ob ein Datensatz gefunden wurde, indem Sie den Index betrachten. Wenn dies der Fall ist, dann gehe zu Maschine # (X) / ZOL # (Y) auf dieser Maschine / Aufzeichnungsstelle # (Z) innerhalb dieses 2 TB-Blobs, basierend auf der einfachen Indexberechnung. Die Suche nach einzelnen Datensätzen wäre extrem schnell und Sie könnten einige Teile des Datenspeichers in verschiedene dbs laden (während Sie den Datenspeicher für echte Arbeit verwenden) und Leistungstests durchführen, um festzustellen, ob sie Ihre gesamte Datenbank unterstützen können - oder nicht. Verwenden Sie einfach den Datenspeicher auf diese Weise.

Ein ZOL ist eine ZFS-Sache, die in anderen Dateisystemen als eine dünne Datei betrachtet werden könnte, so dass ähnliche Dinge gelten würden. Oder Sie können einfach auf eine bestimmte Byte-Nummer auf einer Festplatte indizieren, aber das wird schwierig, wenn die Festplatten unterschiedliche Größen haben, wenn Sie die Anzahl der pro Festplatte verwendeten Bytes nicht auf einer Ebene begrenzen, die für alle Festplatten funktioniert - dh 1,75 TB pro 2 TB-Festplatte . Oder erstellen Sie Metageräte mit fester Größe usw.


2
2017-08-18 17:40



Hallo Sarah - ich bin mir nicht sicher, ob du noch daran arbeitest, aber wenn du Hilfe brauchst, könnte ich meine Idee für dich auf einer 100TB-Maschine entwickeln und wäre bereit, in einem großen US-Rechenzentrum zu hosten und den gesamten Produktions-Cluster zu managen 400-500 Maschinen nach Bedarf. BTW, hast du jemals bei CNET in SF gearbeitet?


Abgesehen von der Optimierung Ihrer DB-Parameter wie verrückt (verwenden Sie mysqltuner zu helfen) zu versuchen und halten Sie Ihre SELECTs so viel wie möglich zwischengespeichert, eine Sache, die Sie untersuchen können, ist START TRANSACTION / CoMMIT (InnoDB vorausgesetzt) ​​beim Einfügen Ihrer paar hundert Datensätze, um zu vermeiden reihenweise sperren Sie den Overhead und bringen die Einfügemarke um einen großen Faktor nach unten. Ich würde auch die Tabelle als MyISAM und InnoDB erstellen und Tests darauf durchführen, um zu sehen, welche wirklich schneller ist, wenn Sie das Caching verschärft haben - es ist nicht immer so, dass MyISAM schneller für Lesevorgänge ist - überprüfen Sie dies:

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

Während Ihrer Tests sollte die Anzahl der gleichzeitigen Threads auch nach oben und unten variiert werden, bis Sie den optimalen Platz für den RAM finden, den Sie sich auf dem Server leisten können, um die Caches zu optimieren. Sie können feststellen, dass, obwohl Sie mehr Threads durch die Mathematik unterstützen können, die DB selbst möglicherweise schlechter läuft, wenn die Thread-Anzahl zu hoch wird.

Wenn Sie MyISAM und / oder InnoDB file-per-table verwenden, können Sie auch einen anderen Mountpoint für / var / lib / mysql für den Dateisystem-Mount erstellen, der auf eine kleinere Blockgröße abgestimmt ist und die fs-type-Parameter optimiert - dh ext3 / ext4 / resiserfs Sie könnten data = writeback für das Journal verwenden und die Aktualisierung der Zugriffszeiten auf das Dateisystem für E / A-Geschwindigkeit deaktivieren.


1
2017-08-08 14:47



Gutes Zeug - danke dafür :) - Sarah
Myisam scheint aufgrund von Transaktionsanforderungen nicht in Frage zu kommen. - pQd


Für die zweite Option, wie viele Zahlen werden wahrscheinlich tatsächlich platziert werden?

Wenn es nur eins in tausend oder 10K, 100K usw. gibt, könnte das Speichern von Bereichen von verwendeten (oder unbenutzten) Nummern Billionen von Einträgen speichern. zB: speichern ('frei', 0,100000), ('genommen', 100000,100003), ('frei', 100004,584234) - Zeilen nach Bedarf in zwei oder drei Zeilen aufteilen und auf die erste Nummer indizieren, Suche nach x <= {Nadel}, um zu sehen, ob der Bereich, der die gesuchte Nummer enthält, genommen wurde oder frei ist.

Sie benötigen möglicherweise nicht beide Status. Speichern Sie einfach den Status, der am wenigsten wahrscheinlich ist.


0
2017-12-27 20:34