Es ist ein bisschen wie eine Überschrift, aber die folgenden drei Tipps sind tatsächlich praktischer. Der Inhalt stammt aus einem Beitrag von Colin Howe, Vizepräsident von Conversocial, in der Londoner MongoDB-Benutzergruppe.
Anwendung: Die folgenden Punkte sind nicht universell anwendbar, abhängig von Ihren eigenen Anwendungsszenarien und Dateneigenschaften.
Wir wissen, dass MongoDB eine Dokumentendatenbank ist und jeder ihrer Datensätze ein Dokument im JSON-Format ist. Beispielsweise wird wie im folgenden Beispiel jeden Tag ein statistisches Datenelement generiert:
{ metric: "content_count", client: 5, value: 51, date: ISODate("2012-04- 01 13:00 ") }
{ metric: "content_count", client: 5, value: 49, date: ISODate("2012-04-02 13:00") }
Und wenn eine Kombination verwendet wird: Wenn es sich um ein großes Dokument handelt, können Sie alle Daten eines Monats wie folgt in einem Datensatz speichern:
{ metric: "content_count", client: 5, monatlich: "2012-04" , 1: 51, 2 : 49, ... }
Mit den beiden oben genannten Methoden gespeichert, wurden insgesamt etwa 7 GB Daten im Voraus gespeichert (das Gerät verfügt nur über 1,7 GB Speicher) und die Test lesen Sie ein Jahr lang Informationen. Der Unterschied in der Leseleistung zwischen den beiden Offensichtlich:
Erster Typ: 1,6 Sekunden
Zweiter Typ: 0,3 Sekunden
Also, was ist das Problem?
Der eigentliche Grund ist, dass der kombinierte Speicher beim Lesen von Daten weniger Dokumente lesen kann. Wenn das Dokument nicht vollständig im Speicher gespeichert werden kann, werden die Kosten hauptsächlich für die Festplattensuche aufgewendet. Beim Abrufen von Daten für ein Jahr müssen bei der ersten Speichermethode mehr Dokumente gelesen werden, sodass auch die Anzahl der Festplattensuchen höher ist . Also langsamer.
Tatsächlich nutzt foursquare, ein bekannter Benutzer von MongoDB, diese Methode häufig, um die Leseleistung zu verbessern. Siehe dies
Wir wissen, dass MongoDB wie herkömmliche Datenbanken B-Bäume als Indexdatenstrukturen verwendet. Bei baumförmigen Indizes ist der vom Index verschwendete Speicher umso geringer, je konzentrierter der Speicher des Index ist, der zum Speichern heißer Daten verwendet wird. Wir vergleichen also die folgenden zwei Indexstrukturen:
db.metrics.ensureIndex({ metric: 1, client: 1, date: 1})
und
db. metrics.ensureIndex({ date: 1, metric: 1, client: 1 })
verwendet diese beiden unterschiedlichen Strukturen, und der Unterschied in der Einfügeleistung ist ebenfalls offensichtlich.
Bei Verwendung der ersten Struktur kann die Einfügegeschwindigkeit grundsätzlich bei 10 k/s gehalten werden, wenn das Datenvolumen unter 20 Millionen liegt. Wenn das Datenvolumen wieder zunimmt, sinkt die Einfügungsgeschwindigkeit langsam auf 2,5 k/s. s. Wenn die Datenmenge zunimmt, kann die Leistung sogar noch geringer sein.
Bei Verwendung der zweiten Struktur kann die Einfügegeschwindigkeit grundsätzlich stabil bei 10k/s liegen.
Der Grund dafür ist, dass die zweite Struktur das Datumsfeld an erster Stelle im Index platziert, sodass beim Erstellen des Index, wenn neue Daten den Index aktualisieren, dieser nicht in der Mitte, sondern nur am Ende aktualisiert wird den Index. Nehmen Sie Änderungen vor. Zu früh eingefügte Indizes erfordern bei nachfolgenden Einfügevorgängen kaum Änderungen. Im ersten Fall erfolgt die Indexaktualisierung häufig in der Mitte der Baumstruktur, da sich das Datumsfeld nicht im Vordergrund befindet, was zu häufigen umfangreichen Änderungen in der Indexstruktur führt.
Dasselbe wie Punkt 1. Dieser Punkt basiert auch auf der Tatsache, dass die Hauptbetriebszeit herkömmlicher mechanischer Festplatten für Festplattensuchvorgänge aufgewendet wird.
Wenn wir beispielsweise das Beispiel in Punkt 1 nehmen, fügen wir beim Einfügen von Daten den gesamten für die diesjährigen Daten erforderlichen Platz auf einmal ein. Dadurch wird sichergestellt, dass sich unsere Daten für 12 Monate im Jahr in einem Datensatz befinden und sequentiell auf der Festplatte gespeichert werden. Beim Lesen benötigen wir dann möglicherweise nur einen sequentiellen Lesevorgang auf der Festplatte, um die Daten im Vergleich dazu zu lesen Bei den letzten 12 Lesevorgängen erfolgt die Festplattensuche nur einmal.
db.metrics.insert([
{ metric: 'content_count', client: 3, date: '2012-01', 0: 0, 1: 0, 2: 0, ... }
{ .................................., Datum: '2012 -02', ... })
{ .................................. ... , Datum: '2012-03', ... })
{ .......................... ... ....., Datum: '2012-04', ... })
{ ..................... .... ..........., Datum: '2012-05', ... })
{ .............. ....... ............., Datum: '2012-06', ... })
{ ......... ... ...................., Datum: '2012-07', ... })
{ ..... .... ........................., Datum: '2012-08', ... })
{ .... ........................, Datum: '2012-09', ... })
{ . ............................, Datum: '2012-10', ... })
{ . ................................., Datum: '2012-11', .. })
{ ................................., Datum: '2012 -12', ... })
])
Ergebnis:
Wenn die Methode des reservierten Speicherplatzes nicht verwendet wird, dauert das Lesen der Aufzeichnungen eines Jahres 62 ms
Wenn Sie verwenden reservierter Speicherplatz, es dauert nur 6,6 ms, um die Aufzeichnungen eines Jahres zu lesen
Das obige ist der detaillierte Inhalt vonLösung für das MongoDB-Festplatten-IO-Problem. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!