Vorsichtsmaßnahme: Es kann unten zu Ungenauigkeiten kommen. Ich habe viel über dieses Zeug gelernt, also nimm es mit einer Prise Salz. Dies ist ziemlich lang, aber Sie können einfach die Parameter lesen, mit denen wir gespielt haben, und dann zum Abschluss übergehen.
Es gibt eine Reihe von Ebenen, auf denen Sie sich über die Schreibleistung von SQLite Gedanken machen können:
Wir haben uns die fett hervorgehobenen angesehen. Die besonderen Parameter waren
- Schreibcache der Festplatte. Moderne Festplatten verfügen über einen RAM-Cache, der zum Optimieren der Schreibvorgänge für die sich drehende Festplatte verwendet wird. Wenn diese Option aktiviert ist, können Daten in Blöcke außerhalb der Reihenfolge geschrieben werden. Wenn also ein Absturz auftritt, können Sie eine teilweise geschriebene Datei erhalten. Überprüfen Sie die Einstellung mit hdparm -W / dev / ... und stellen Sie sie mit hdparm -W1 / dev / ... ein (um sie einzuschalten, und -W0, um sie auszuschalten).
- Barriere = (0 | 1). Viele Online-Kommentare sagen: "Wenn Sie mit Barriere = 0 ausführen, ist das Cache-Speichern für Schreibvorgänge nicht aktiviert." Eine Diskussion der Barrieren finden Sie unter http://lwn.net/Articles/283161/.
- data = (Journal | bestellt | zurückschreiben). Eine Beschreibung dieser Optionen finden Sie unter http://www.linuxtopia.org/HowToGuides/ext3JournalingFilesystem.html .
- commit = N. Weist ext3 an, alle N Sekunden alle Daten und Metadaten zu synchronisieren (Standard 5).
- SQLite Pragma synchron = ON | AUS. Wenn diese Option aktiviert ist, stellt SQLite sicher, dass eine Transaktion auf die Festplatte geschrieben wird, bevor Sie fortfahren. Wenn Sie diese Option deaktivieren, sind die anderen Einstellungen weitgehend irrelevant.
- SQLite Pragma cache_size. Steuert, wie viel Speicher SQLite für den speicherinternen Cache verwendet. Ich habe zwei Größen ausprobiert: eine, bei der die gesamte DB in den Cache passt, und eine, bei der der Cache die Hälfte der maximalen DB-Größe hat.
Weitere Informationen zu den ext3-Optionen finden Sie in der ext3-Dokumentation .
Ich habe Leistungstests für eine Reihe von Kombinationen dieser Parameter durchgeführt. Die ID ist eine Szenarionummer, auf die unten Bezug genommen wird.
Ich habe zunächst mit der Standardkonfiguration auf meinem Computer als Szenario 1 ausgeführt. Szenario 2 ist meines Erachtens das "sicherste" und habe dann verschiedene Kombinationen ausprobiert, sofern dies angemessen / erforderlich ist. Dies ist wahrscheinlich am einfachsten mit der Karte zu verstehen, die ich letztendlich verwendet habe:
Ich habe ein Testskript geschrieben, das viele Transaktionen mit Einfügungen, Aktualisierungen und Löschungen ausführte, und zwar alle in Tabellen, die entweder nur INTEGER, nur TEXT (mit ID-Spalte) oder gemischt enthalten. Ich habe dies mehrmals für jede der obigen Konfigurationen ausgeführt:
Die beiden untersten Szenarien sind # 6 und # 17, bei denen "Pragma synchron = aus" ist, was nicht überrascht, dass sie die schnellsten waren. Die nächsten drei Gruppen sind # 7, # 11 und # 19. Diese drei sind in der obigen "Konfigurationsübersicht" blau hervorgehoben. Grundsätzlich besteht die Konfiguration aus einem Schreibcache auf der Festplatte, einer Barriere = 0 und einer Datenmenge, die sich von 'journal' unterscheidet. Das Ändern des Commits zwischen 5 Sekunden (# 7) und 60 Sekunden (# 11) scheint wenig zu bewirken. Bei diesen Tests schien es keinen großen Unterschied zwischen data = orders und data = writeback zu geben, was mich überraschte.
Der gemischte Update- Test ist der mittlere Peak. Es gibt eine Reihe von Szenarien, die bei diesem Test deutlich langsamer sind. Dies sind alles diejenigen mit data = journal . Ansonsten gibt es nicht viel zwischen den anderen Szenarien.
Ich hatte einen anderen Timing-Test, der eine heterogenere Mischung aus Einfügungen, Aktualisierungen und Löschungen für die verschiedenen Typenkombinationen durchführte. Diese haben viel länger gedauert, weshalb ich sie nicht in die obige Handlung aufgenommen habe:
Hier können Sie sehen, dass die Rückschreibkonfiguration (Nr. 19) etwas langsamer ist als die bestellten (Nr. 7 und Nr. 11). Ich habe erwartet, dass das Zurückschreiben etwas schneller sein wird, aber vielleicht hängt es von Ihren Schreibmustern ab, oder vielleicht habe ich auf ext3 einfach noch nicht genug gelesen :-)
Die verschiedenen Szenarien waren in gewisser Weise repräsentativ für die von unserer Anwendung ausgeführten Vorgänge. Nachdem wir eine Auswahlliste von Szenarien ausgewählt hatten, führten wir Timing-Tests mit einigen unserer automatisierten Testsuiten durch. Sie stimmten mit den obigen Ergebnissen überein.
Fazit
- Der Commit- Parameter schien kaum einen Unterschied zu machen, also verlassen wir ihn bei 5s.
- Wir werden den Cache für Festplattenschreibvorgänge aktivieren, Barriere = 0 und Daten = geordnet . Ich las einige Dinge online, die meinten, dies sei ein schlechtes Setup, und andere, die meinten, dies sollte in vielen Situationen der Standard sein. Ich denke, das Wichtigste ist, dass Sie eine fundierte Entscheidung treffen und wissen, welche Kompromisse Sie eingehen.
- Wir werden das synchrone Pragma in SQLite nicht verwenden.
- SQLite einstellen Pragma cache_size so festlegen, dass die Datenbank in den Arbeitsspeicher passt, wird die Leistung bei einigen Vorgängen wie erwartet verbessert.
- Die obige Konfiguration bedeutet, dass wir etwas mehr Risiko eingehen. Wir werden die SQLite-Backup-API verwenden um die Gefahr eines Festplattenausfalls bei einem teilweisen Schreibvorgang zu minimieren: alle N Minuten wird ein Snapshot erstellt, und das letzte M wird beibehalten. Ich habe diese API während der Ausführung von Leistungstests getestet, und wir sind zuversichtlich, diesen Weg einzuschlagen.
- Wenn wir noch mehr wollten, könnten wir uns das Durchatmen mit dem Kernel ansehen, aber wir haben die Dinge genug verbessert, ohne dorthin zu gehen.
Vielen Dank an @Huygens für verschiedene Tipps und Hinweise.