Wie speichere ich 3 Millionen Datensätze im Schlüsselwertformat?

10

Wir müssen grundlegende Informationen über 3 Millionen Produkte speichern. Derzeit handelt es sich um eine 180-MB-CSV, die vierteljährlich aktualisiert wird.

Es werden ungefähr 30.000 Abfragen pro Tag durchgeführt, aber die Abfragen sind nur ein sehr einfacher Schlüsselwertspeicher. Wir müssen nur die Produkt-ID nachschlagen und den Rest der Informationen anzeigen (die alle in einem Datensatz enthalten wären).

Dies gilt für das Web, daher ist eine schnelle Leistung von entscheidender Bedeutung.

Sollten wir MySQL verwenden, obwohl wir wirklich keine relationale Datenbank benötigen? Sollten wir nur 3 Millionen statische HTML-Dateien pro Quartal generieren? Sollten wir für jedes Produkt eine einzeilige CSV in Amazon S3- oder Rackspace Cloud-Dateien speichern? Was ist der beste Weg, dies zu tun?

Phil
quelle

Antworten:

16

Da MySQL so weit verbreitet ist und dies wirklich eine ziemlich triviale Sache ist, würde ich vorschlagen, damit zu arbeiten. Sofern der Server nicht über mindestens einige GB Arbeitsspeicher verfügt, würde ich empfehlen, bei MySQL zu bleiben, anstatt ein In-Memory-System zu verwenden.

Sobald Sie anfangen, Ihre Daten in eine Datenbank zu stellen, egal ob es sich um MySQL oder etwas anderes handelt, werden Sie höchstwahrscheinlich feststellen, dass Sie mehr Verwendungsmöglichkeiten dafür finden werden. Im Moment sprechen Sie nur über Schlüsselwertpaare, aber der Rest der Daten zu Ihren Produkten muss irgendwo gespeichert werden. Wenn das nicht in einer Datenbank ist, kann ich mir nicht vorstellen, dass die Datenspeicherung sehr effizient ist.

Erstellen Sie auf keinen Fall diese drei Millionen Dateien. Wir haben hier bereits eine Reihe von Fragen gesehen, die sich aus den Problemen ergeben, die so viele Dateien verursachen.

John Gardeniers
quelle
13

Sie können einen dedizierten NoSQL-Schlüsseltyp verwenden, der für diese Art von Aufgaben optimiert ist . Schauen Sie sich an:

  • Redis - Redis ist ein Open Source-Speicher für erweiterte Schlüsselwerte. Es wird häufig als Datenstruktur-Server bezeichnet, da Schlüssel Zeichenfolgen, Hashes, Listen, Mengen und sortierte Mengen enthalten können.
  • MemcacheDB - MemcacheDB ist ein verteiltes Schlüsselwertspeichersystem, das für die dauerhafte Speicherung ausgelegt ist.
  • andere (eine solche Liste finden Sie hier: http://nosql-database.org/ )

Natürlich können Sie MySQL oder eine andere relationale Datenbank verwenden, aber Lösungen, die speziell für Daten mit Schlüsselwerten entwickelt wurden, sollten besser sein (andernfalls sollten Sie sie zuerst entwerfen, außer möglicherweise aufgrund der Tatsache, dass sie viel kleiner sind (in Bezug auf RAM und HDD) Lösung).

LazyOne
quelle
Wir könnten Redis verwenden, aber glauben Sie, dass dies auf einem P4 mit 2 GB RAM funktionieren würde?
Phil
@Phil Wenn man bedenkt, dass Ihre CSV-Datei ungefähr 180 MB groß ist - sollte in Ordnung sein. Obwohl wir es in einem Projekt (bisher nur einmal) mit etwa 200.000 Datensätzen verwendet haben und der Server 8 GB RAM hatte, ist es für mich schwierig zu vergleichen.
LazyOne
6

Und jetzt etwas ganz anderes:

Gegeben:

  • 180 MB / 3 MB Produkte = durchschnittlich 62 Byte / Produkt.
  • 30.000 Anfragen pro Tag = 0,34 Anfragen pro Sekunde
  • Vierteljährlich aktualisiert = im Wesentlichen statische Daten

Außerhalb der Box Lösung:

Speichern Sie jedes Produkt als TXT-Ressourceneintrag und speichern Sie es im DNS, z.

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

Leistungen:

  • extrem zuverlässig und vertrauenswürdig (Sie sind bereits jeden Tag darauf angewiesen)
  • kann auf so ziemlich jeder Plattform aufgebaut werden
  • Nahezu jede Sprache unterstützt DNS-Abfragen in der einen oder anderen Form
  • Open Source- und kommerzielle Server unterstützen verschiedene Arten von Backend-Datenbanken
  • kann trivial repliziert werden (geben Sie einfach mehrere Nameserver an)
  • verarbeitet atomare Updates, selbst wenn sie auf einem Dutzend Servern repliziert werden
  • kann kryptografisch signiert werden, um die Datenintegrität sicherzustellen
  • kann um Größenordnungen höhere Abfrageraten pro Sekunde verarbeiten (10.000 Abfragen pro Sekunde können problemlos mit Standardhardware verarbeitet werden)

Gründe, warum dies eine schlechte Idee sein könnte:

  • Sie müssen die Daten durchsuchen (DNS ist eine reine Schlüssel- / Wertsuche).
  • Sie müssen die Daten ausblenden (DNS hat keine Vertraulichkeit)
Theobroma Cacao
quelle
1
Wenn ich einen Bonuspunkt für Originalität geben könnte, würde dies meine Stimme bekommen. Ich würde jedoch nicht sagen, dass DNS überhaupt zuverlässig ist, da es in einem typischen Heimnetzwerk wie Magie erscheint, wenn es funktioniert, und wie ein Fluch, wenn es nicht funktioniert.
Martin Vilcans
1
Ich bin fasziniert. Ich mag diese Idee wirklich sehr, aber für mich würde ich mich für etwas Bewährtes wie CouchDB entscheiden
Tom O'Connor
Hast du Monty Python gesehen?
Mark Henderson
Vermutlich wäre dies innerhalb eines Unternehmensnetzwerks. Die DNS-Zuverlässigkeit wird zu einem Problem, wenn Pakete der Wildnis des Internets trotzen müssen. Da DNS standardmäßig UDP verwendet, müssen Sie sich auf die Neuübertragungsrichtlinie des DNS-Resolvers verlassen, wenn ein Paket verworfen wird. Innerhalb eines Unternehmensnetzwerks sind die Chancen, dass Sie einen ausreichend hohen Paketverlust erhalten, (wahrscheinlich) vernachlässigbar. Und Sie können DNS jederzeit zwingen, TCP zu verwenden (wenn auch mit einem Leistungseinbruch, der in diesem Fall als nicht signifikant angesehen wird). Und ich garantiere, der DNS bekommt mehr Lookups als alle CouchDB-Installationen zusammen :-).
Theobroma Cacao
Captain Hindsight hier. Ein Wort: Blockchain.
Datashaman
4

MySQL mit MyISAM und einigen guten Indizes klingt dafür perfekt. Natürlich gibt es viele andere Optionen, aber MySQL wird auf jedem kommerziellen Webhost sehr (wenn nicht universell) unterstützt. Abhängig von der Geschwindigkeit, die Sie benötigen, lohnt es sich möglicherweise auch , sich memcached anzusehen. Ohne die Größe jedes Schlüssel / Wert-Paares zu kennen, ist das Speichern von 3 Millionen davon im Speicher möglicherweise eine noch schlechtere Idee als eine 180-MB-CSV-Datei (oh, warte, das ist es eine 180-MB-CSV-Datei, damit wir wissen, wie groß sie sind. Es müssen ziemlich kleine Paare sein, damit Memcached noch besser sein kann.

Sie möchten keine 3 Millionen statischen HTML-Dateien, da dies Ihr Dateisystem stark schädigt. Eine einzeilige CSV wird auch unter S3 das gleiche Problem haben. Niemand möchte 3 Millionen Dateien in einem Ordner.

Mark Henderson
quelle
Es sind ziemlich kleine Paare ... es sind sehr grundlegende Daten wie Preis, Herstellungsdatum, Lagernummer usw. Weniger als 10 Spalten. Sie denken also, MySQL ist wirklich der richtige Weg? Der Server, auf dem es laufen wird, ist ein P4 mit 2 GB RAM - ich denke, das sollte in Ordnung sein?
Phil
@Phil - So you think MySQL is the way to go, really?- nein, nicht wirklich, aber es ist sehr flexibel und wird, wie gesagt , fast universell unterstützt. LazyOne hat jedoch oben einige gute Alternativen veröffentlicht. Ich konnte mich nicht an den Begriff NoSQL erinnern, aber er schwebte irgendwo in meinem Gehirn herum
Mark Henderson
4

Sie können die Berkeley-Datenbank verwenden, die genau so etwas tut, auch wenn sie seit Beginn von Perl5 nicht mehr angesagt war. Berkeley unterstützt nur Schlüsselwertpaare, und Sie binden die gesamte Datenbank an einen Hash und greifen als solcher darauf zu.

Die Verwendung von Berkeley ist in vielen älteren Perl-Referenzen, die sich in Ihrem Regal befinden, oder im Perldoc für das BerkeleyDB-CPAN-Modul ausführlich beschrieben . Ich vermeide generell die Verwendung von Berkeley DB (obwohl mein Arbeitgeber viel alten Code hat, in dem er eine herausragende Rolle spielt, und einige der DBs so groß sind wie Ihre), weil es keinen Spaß macht, wenn Ihre Daten komplexer werden.

brainbuz
quelle
2
BDB ist eine alte Schule, aber sehr effektiv und für diese Situation geeignet.
womble
Beachten Sie die Lizenz für Berkely DB en.wikipedia.org/wiki/Sleepycat_license. Es ist erforderlich, dass ALLER Quellcode verfügbar gemacht wird, nicht nur der DB-Teil.
WolfmanJM
4

Sie haben Ihre Frage als Amazon S3 gekennzeichnet.

Ich möchte Ihre Aufmerksamkeit auf eines der anderen verwandten Produkte namens Amazon SimpleDB lenken.
Es klingt so, als würde das SimpleDB-Datenmodell gut zu Ihrer Art von Anwendung passen.

Dies ist kein Plug-in dafür, aber es lohnt sich, einen Blick darauf zu werfen, insbesondere wenn Sie die Amazon Cloud-Dienste nutzen möchten.

Das SDB-Datenmodell ähnelt einer Tabelle.

Weitere Informationen finden Sie hier: http://aws.amazon.com/simpledb/ Und das Datenmodell: http://docs.amazonwebservices.com/AmazonSimpleDB/latest/DeveloperGuide/

Matt
quelle
SimpleDB ist teuer. In vielen Fällen schmerzhaft.
Tom O'Connor
1

Obwohl 180 MB Daten von jeder relationalen Datenbank problemlos verarbeitet werden können, würde ich MongoDB ( http://www.mongodb.org/) wärmstens empfehlen.) über MySQL, Redis, MemcacheDB und anderen einfacheren Schlüsselwertspeichern oder relationalen Datenbanken. Der Grund dafür ist, dass MongoDB für diese Art von Problem das schnellste und ausdrucksstärkste System ist und superschnelle dynamische Updates ohne Schemaeinschränkungen ermöglicht, sodass Ihre Dokumente unterschiedliche Formate haben können, wenn Sie dies möchten. Ich war neulich bei einer Präsentation von guardian.co.uk und sie haben eine politische Entscheidung getroffen, alle relationalen Datenbanken zu verbieten und MongoDB ausschließlich für die Bereitstellung ihrer Nachrichten zu verwenden. Sie können ein Gefühl dafür bekommen, wie schnell ihre Website ist und welche seit 1995 online ist (die älteste Online-Zeitung in Großbritannien). Sie haben in der Vergangenheit auch alle möglichen Engpässe aufgrund relationaler Datenbanken durchlaufen. Für 180 MB wird MongoDB alles aus dem In-Memory-Bereich bereitstellen, sodass Ladezeiten von weniger als ms wahrscheinlich der Fall sind.

snez
quelle
0

Es werden ungefähr 30.000 Abfragen pro Tag durchgeführt, aber die Abfragen sind nur ein sehr einfacher Schlüsselwertspeicher. Wir müssen nur die Produkt-ID nachschlagen und den Rest der Informationen anzeigen (die alle in einem Datensatz enthalten wären).

Sie sagten, dass Ihre Abfragen nur einfache Schlüsselsuchen sind. Bei der binären Suche benötigen Sie im schlimmsten Fall 21 Iterationen. Bei gehashten Schlüsseln sind Ihre Abfragen sogar noch schneller. Drei Millionen Datensätze sind klein , solange Sie Verknüpfungen (oder andere kartesische Produktoperationen) und lineare Suchen vermeiden.

Ich würde sagen, dass so ziemlich alles gut gehen würde. Ihre Last beträgt 30000 Abfragen pro Tag. Dies bedeutet, dass Sie (vorausgesetzt, Ihre Last ist den ganzen Tag über konstant) alle 20 Sekunden eine einzige Abfrage haben. Das ist gar nicht so schlecht.

Ich würde empfehlen, zuerst die Technologie zu implementieren, mit der Sie am besten vertraut sind, und dann zu messen, ob dies wirklich der Engpass des Systems ist.

Lie Ryan
quelle
0

Der beste Weg, dies zu tun, hängt wirklich von der Qualität und Art Ihrer Daten und Abfragen ab. Für den Anfang sind 180 MB Daten in einer einzigen Tabelle für Produkte kein Problem, egal wie Sie es betrachten. Und 30.000 Anfragen pro Tag sind noch weniger ein Problem. Mit einer ordnungsgemäß konfigurierten Datenbank kann jeder alte Desktop diese Last verarbeiten.

Andere haben bereits auf Ihre beiden Hauptoptionen hingewiesen, MySQL oder eine noSQL-Datenbank.

Wenn Sie eine bestimmte Anzahl von Attributen haben, die für jedes einzelne Produkt vorhanden sind (wie Hersteller, Preis, Lagernummer usw.), ist es am besten, Spalten für diese Attribute zu haben und Ihre Schlüssel / Wert-Paare in ein flaches Tabellenformat zu konvertieren. mit einer Produkt-ID als Primärschlüssel für diese Tabelle. Dies funktioniert auch dann sehr gut, wenn einige Spalten nur von der Hälfte der Zeilen verwendet werden, da Sie für die meisten Produkte nur eine Abfrage ausführen müssen, um alle ihre Attribute abzurufen Dies sind Daten über Produkte. Ich würde vermuten, dass es sehr wahrscheinlich ist, dass dies die Struktur Ihrer Daten ist.

Wenn die Attribute in Bezug auf Präsenz und Datentyp stark variieren, ist es möglicherweise besser, eine noSQL-Datenbank zu verwenden, die dieses Szenario effizienter handhabt als herkömmliche SQL-Datenbanken.

In Bezug auf die Leistung: Ich habe zuvor für ein E-Commerce-Unternehmen gearbeitet, bei dem die Website lange Zeit mit Daten von einem MySQL-Server versorgt wurde. Dieser Server hatte 2 GB RAM, die Datenbank war insgesamt ca. Mit einer Größe von 5 GB und einer Spitzenlast behandelte der Server mehrere tausend Anfragen pro Sekunde. Ja, wir hatten viele Abfrageoptimierungen durchgeführt, aber dies ist definitiv machbar.

wolfgangsz
quelle