AUTOR Moritz Strübe : MATHEMA Engineering

Hier erfahren Sie wie was es mit dem tmpfs auf sich hat und wie wir es verwenden können, um die Schnelligkeit des Buildservers zu verbessern und die SSD zu schonen.

 

 

TL;DR;

Die Anleitung ist für Docker. Andernfalls muss man den Pfad entsprechend anpassen.

tmpfs   /containerfs tmpfs   rw,noatime,size=380G,nr_inodes=0 0 0

 

Was ist tmpfs?

tmpfs ist ein Dateisystem, das im RAM liegt. Damit ist es sehr viel schneller als jede Festplatte. Hat aber auch den Nachteil, dass bei einem Absturz alles weg ist. Das ist uns bei einem Buildserver egal. Immerhin sollte der sich bei Bedarf alles ziehen, was er zum Bauen braucht.

Das besondere an tmpfs, gegenüber ramfs, ist, dass Daten, auf die länger nicht mehr zugegriffen wurde, vom Speicher auf die Festplatte kopiert werden. So ist es auch möglich ein Dateisystem anzulegen, dass sehr viel größer ist als der verfügbare RAM. Das auslagern auf die Platte übernimmt jedoch nicht tmpfs sondern das Betriebssystem.

 

Ist das trotz Datei-Caching schneller?

Linux hat ein recht ausgeklügeltes Caching, dass sich darum kümmert die Zugriffe auf die Festplatte auf ein Minimum zu reduzieren. Wird eine Datei geschlossen, wird diese jedoch standardmäßig immer mit dem Dateisystem synchronisiert. Das bedeutet, dass der Compiler sich erst beendet, wenn die Festplatte zurückmeldet, dass sie die Datei geschrieben hat. Und während einem Bauprozess werden normalerweise sehr viele Dateien geschrieben. Es gibt zwar die libeatmydata die das fsync, also das syncrhonisieren der Daten auf die Platte beim Schließen der Datei weglässt, aber andere unerwartete Nebeneffekte haben kann.

 

Swap sollte auf eine SSD!

Was man bei diesem Ansatz auf jeden Fall haben will, ist eine SDD. Während die Dateien in einem Dateisystem im Normalfall an einer Stelle liegen (Stichwort: Fragmentierung), ist dies beim Tmpfs nicht der Fall. Das liegt schon daran, dass das Betriebssystem und nicht tmpfs entscheidet, was auf die Platte geschrieben wird. So kann es leicht passieren das eine Datei über die Platte verteilt wird. Wird auf diese Zugegriffen, muss sie erst wieder in den Speicher geladen werden. Das nicht-lineare Lesen kann bei den guten alten Platten mit Leseköpfen durchaus länger dauern. Bei der SSD merkt man das auch, aber es ist bei weitem nicht so schlimm. Aber sein wir mal ehrlich: Bauen wollen wir auf rotierenden Platten eh nicht mehr.

 

tmpfs schont die SSD

Ein weiterer Vorteil von tmpfs ist, dass die SSD geschont wird. Während des Bauens entstehen sehr viele temporäre Dateien, die am Ende wieder gelöscht werden. Im Idealfall werden diese erst gar nicht auf die Platte geschrieben. Eine SSD die am Ende ihrer Lebenszeit war, war auch die Motivation, sich tmpfs mal genauer anzuschauen.

Wie viel tatsächlich geschrieben wird hängt natürlich von der Größe des RAMs und den Jobs ab. Ist der RAM groß genug, so dass die Dateien nicht auf die Platte geschrieben werden müssen, ist die I/O-Last zur Platte praktisch vernachlässigbar. Wenn man aber lauter verschiedene Jobs baut, müssen die Dateien dann doch irgendwann auf die Platte geschrieben werden, um wieder Platz im RAM zu schaffen. Wenn man am Ende der Jobs ein clean macht, hat man doch wieder was gewonnen.

Schöner wäre es natürlich, wenn sich die CI um das Aufräumen kümmern würde, aber die räumt meist vor dem nächsten Job auf, damit man fehlgeschlagene Jobs im Zweifel besser analysieren kann.

 

Gibt es auch Nachteile?

Ja, aber die spielen bei einem Buildserver praktisch keine Rolle. Neben dem Datenverlust beim Neustart gibt es ein paar Nachteile, die man auf einem normalen System eher nicht mag.

Einer davon ist, dass wenn ein Programm plötzlich mehr Speicher benötigt, das System eventuell erstmal steht und Daten auf die Platte schreiben muss, bevor dieser zur Verfügung steht. Ohne tmpfs steht hierfür der Datei-Lese-Cache zur Verfügung, der einfach verworfen werden kann - die Daten können ja später von der Platte neu geladen werden.

Ein weiteres "Problem" ist, dass bei tmpfs die Daten, aber nicht die Verwaltungsstrukturen, auf die Platte auslagert werden. Deshalb sind standardmäßig auch die nr_inodes begrenzt. Ein böswilliger Angreifer kann, indem er lauter leere Dateien anlegt, den kompletten Arbeitsspeicher aufbrauchen. Im Zweifel sollte man einen Blick auf cat /proc/meminfo | grep Unevictable haben (siehe nächster Absatz). Auf unseren Buildservern ist bisher nicht relevant geworden.

 

Tuning

Zwei Optionen haben wir gesetzt. Die eine ist noatime. Wie viel das wirklich bringt ist schwer zu sagen. Aber es gibt ein paar Quellen, die sagen, dass es einen messbaren Performance-Gewinn bringt. Schaden tut es auf jeden Fall nicht.

Auch haben wir nr_inodes auf 0 gesetzt, weil uns die tatsächlich ausgegangen sind. Hier muss man wahrscheinlich ein wenig experimentieren und auch ein Auge auf cat /proc/meminfo | grep Unevictable haben. Dies zeigt die Größe des Speichers an, der, z.B. wegen tmpfs, nicht auf die Festplatte ausgelagert werden kann.

Es gibt noch die Option huge, mit der man "Huge Pages" aktivieren kann. Normalerweise ist der Arbeitsspeicher in 4K-Blöcke eingeteilt. Bei Huge Pages sind 2MB. Das reduziert den Verwaltungsaufwand. Ob das was bringt, ist schwer zu sagen, zumal man dazu mehr über die Arbeitsweise von tmpfs wissen müsste: Werden für alle Dateien jetzt 4MB alloziert oder werden im Zweifel mehrere Dateien auf einer Seite gespeichert? Leider ließ sich hier auf die Schnelle keine gute Quelle finden. Und um umfangreiche Messungen zu machen oder mich in den Code einarbeiten, war mir das Thema doch nicht wichtig genug. Sachdienliche Hinweise sind aber willkommen.

Ansonsten bieten Linux unter /proc/sys/vm eine Vielzahl an Konfigurationsoptionen. So kann man zum Beispiel mehr Daten prophylaktisch auf die Platte schreiben für den Fall, dass eine Anwendung plötzlich doch deutlich mehr RAM benötigt.

 

Fazit

Bis jetzt hatte die Umstellung auf tmpfs auf unseren Buildservern einen deutlichen Performancegewinn, eine Entlastung unserer SSD und keine feststellbaren Nachteile zur Folge. Voraussetzung ist natürlich ausreichend RAM für die Aufgabe, aber das sollte bei den aktuellen RAM-Preisen kein Problem sein.

 

 

Über den Autor

Moritz "Morty" Strübe arbeitet als Embedded-Software-Entwickler bei MATHEMA. Am liebsten entwickelt er Bare-Metal-Software in C++. Daneben beschäftigt er sich unter anderem mit den Themen Software-Architektur und DevOps im Embedded-Umfeld.