Archiv für den Monat: März 2013

TFT-Bildschirm flimmert nach Schachbrett-Testmuster

Für meine Master-Arbeit muss ich mit einer Kamera einen (TFT-)Bildschirm abfilmen. Um zu bestimmen, wie lange es dauert, bis sich ein anzuzeigendes Bild auf dem Bildschirm „stabilisiert“ hat, habe ich ein kleines Testvideo erzeugt, das ein Schachbrettmuster darstellt. Die Felder des Schachbretts ändern in jedem Frame ihre Farbe von Weiß zu Schwarz bzw. umgekehrt, und das 60-mal pro Sekunde.

Ich dachte zuerst, dass meine Augen mich täuschen, als ich auch nach Beenden des Testvideos noch ein Flimmern auf dem Bildschirm sehen konnte. Tatsächlich oszillieren die Pixel, auf denen zuvor das Schachbrettmuster zu sehen war, jetzt bereits seit einer halben Stunde weiter! Besonders vor grauem Hintergrund kann man das Schachbrettmuster auch jetzt noch sehr gut erkennen. Ein- und Ausschalten des Bildschirms (auch am Netzschalter und durch Herausziehen des Stromkabels) hat nichts gebracht — die Pixel flimmern immer noch fröhlich weiter!

Es ist mir ein Rätsel, und ich hoffe, dass es irgendwann wieder aufhört zu flimmern …

Server-Backups im laufenden Betrieb mit LVM und ionice

LVM-Snapshots für konsistente Backups im laufenden Betrieb

Wie ich schon einmal erzählt habe, läuft mein Webserver als (bislang einzige) virtuelle Maschine auf meinem dedizierten Server. Die virtuelle Festplatte ist dabei in einem 200 GiB großen Logical Volume untergebracht. Logical Volumes werden mit dem Logical Volume Manager (LVM) erzeugt und sind sozusagen die moderne Version von Partitionen.

Ein Feature von LVM finde ich dabei besonders beeindruckend und extrem hilfreich, nämlich das Anfertigen von Snapshots von Logical Volumes. Ein Snapshot ist eine Momentaufnahme des kompletten Inhalts eines Logical Volumes. Einen Snapshot anzufertigen ist eine Angelegenheit von maximal ein paar Sekunden, es muss dabei nämlich nichts kopiert werden. Erst wenn im Original-Volume ein Datenblock geschrieben wird, muss dessen vorheriger Inhalt gesichert werden, damit er für den Snapshot noch verfügbar ist. Solch ein Verfahren nennt sich Copy-On-Write. Beim Erzeugen des Snapshots muss man bereits angeben, wie viele Daten sich höchstens ändern dürfen, während der Snapshot existiert.

Das Snapshot-Feature ist wie geschaffen für regelmäßige Backups eines Servers im laufenden Betrieb. Hierbei ist es nämlich wichtig, dass man den Inhalt sämtlicher Dateien quasi gleichzeitig sichert. Kopiert man einfach nur alle Dateien nacheinander, dann kommt es zwangsläufig zu Inkonsistenzen, wenn sich während des Backups etwas verändert (und das lässt sich kaum vermeiden, wenn der Server während des Backups benutzbar bleiben soll).

Also geht man wie folgt vor:

  1. Warten, bis alle Cronjobs abgeschlossen sind, denn wir möchten diese nicht unterbrechen. Danach am besten auch den Cron-Daemon anhalten.
  2. Apache und MySQL anhalten, um einen konsistenten Zustand der Datenbanken zu gewährleisten, ggf. noch weitere Dienste.
  3. Mittels lvcreate --snapshot einen Snapshot des Logical Volumes anfertigen, das man sichern möchte. Dabei muss man auch die Größe des Snapshots angeben, also wie viele Daten sich während seiner Existenz ändern dürfen. Ein oft empfohlener Wert ist 10% bis 20% der Größe des Logical Volumes, aber das hängt natürlich von der konkreten Situation ab.
  4. Jetzt, da der Snapshot erzeugt ist, können sämtliche Dienste wieder gestartet werden (Cron, MySQL, Apache, …). Die Downtime des Servers ist somit auf wenige Sekunden begrenzt.
  5. Nun kann der Snapshot „in Ruhe“ irgendwohin gesichert werden, z. B. via FTP. Ich bin dabei, meine eigene Backup-Lösung zu entwickeln, mit der die komplette virtuelle Festplatte blockweise gesichert wird (nicht auf der Ebene des Dateisystems, denn da gibt es immer Schwierigkeiten mit Besitzern, Rechten, Hardlinks, Softlinks usw.). Mehr dazu in einem späteren Beitrag.
  6. Sobald die Sicherung abgeschlossen ist, entfernt man den Snapshot wieder mit lvremove.

Mit nice und ionice die Reaktionszeit des Servers während des Backups verbessern

Das Sichern eines Snapshots beansprucht die Festplatte des Servers stark. Wenn man nicht aufpasst, reagieren Webseiten und andere Anwendungen, die auf dem Server laufen, während des Backups extrem langsam und träge.

Was viele nicht wissen: Unter Linux kann man nicht nur die CPU-Priorität von Prozessen ändern (mit nice), sondern auch ihre I/O-Priorität. Das funktioniert mit dem Befehl ionice, zu dem man diesen netten Artikel finden kann. nice und ionice lassen sich auch kombinieren. Somit kann man dafür sorgen, dass ein laufendes Backup die übrigen Prozesse weder in Sachen CPU noch in Sachen Festplatte zu sehr ausbremst.

Folgender Befehl startet das Skript backup.sh mit minimaler CPU- und I/O-Priorität:

nice -n 19 ionice -c 3 ./backup.sh

Nachtrag: Nach meinen ersten Erfahrungen kommt es auch bei der Verwendung der niedrigsten I/O-Priorität teilweise zu großen Beeinträchtigungen des Serverbetriebs. Abhilfe kann das Tool pv schaffen, mit dem man u. a. den Durchsatz einer UNIX-Pipe begrenzen kann. Somit kann man beispielsweise ein laufendes Backup auf eine Leserate von höchstens 60 MiB pro Sekunde drosseln. Eure Besucher werden es euch danken!

Noch ein Nachtrag: ZFS mit seinen ZVOLs ist nun meiner Meinung nach gegenüber LVM zu bevorzugen. ZFS bietet ebenfalls die Möglichkeit der Anfertigung von Snapshots, darüber hinaus wird die Integrität der Daten jedoch mit Prüfsummen sichergestellt. ZFS ersetzt auch MD (Software-RAID).

Node.js-Modul „ffi“ zum Laufen bringen

Mit frisch installiertem node.js und Paketmanager npm hatte ich gerade einen seltsamen Fehler, als ich das Paket ffi installieren und benutzen wollte (mit diesem Paket kann man native Funktionen aus node.js heraus aufrufen):

> require("ffi")
Error: Could not locate the bindings file. Tried:
 → /home/david/node_modules/ffi/node_modules/ref/build/binding.node
 → /home/david/node_modules/ffi/node_modules/ref/build/Debug/binding.node
 → /home/david/node_modules/ffi/node_modules/ref/build/Release/binding.node
 → /home/david/node_modules/ffi/node_modules/ref/out/Debug/binding.node
 → /home/david/node_modules/ffi/node_modules/ref/Debug/binding.node
 → /home/david/node_modules/ffi/node_modules/ref/out/Release/binding.node
 → /home/david/node_modules/ffi/node_modules/ref/Release/binding.node
 → /home/david/node_modules/ffi/node_modules/ref/build/default/binding.node
 → /home/david/node_modules/ffi/node_modules/ref/compiled/0.6.12/linux/x64/binding.node
    at bindings (/home/david/node_modules/ffi/node_modules/bindings/bindings.js:88:9)
    at Object. (/home/david/node_modules/ffi/node_modules/ref/lib/ref.js:5:47)
    at Module._compile (module.js:441:26)
    at Object..js (module.js:459:10)
    at Module.load (module.js:348:32)
    at Function._load (module.js:308:12)
    at Module.require (module.js:354:17)
    at require (module.js:370:17)
    at Object. (/home/david/node_modules/ffi/lib/ffi.js:6:11)
    at Module._compile (module.js:441:26)

Aha, es fehlt also irgendeine komische „Bindings-Datei“. Um den Fehler zu beheben, braucht man das Paket node-gyp, das einfach mit npm install -g node-gyp global installiert werden kann.

Nun muss man das Tool node-gyp an zwei verschiedenen Stellen aufrufen, damit diese Bindings-Datei erzeugt wird, nämlich einmal im Verzeichnis ffi selbst und einmal in ffi/node_modules/ref:

david@webserver:~# cd node_modules/ffi/
david@webserver:~/node_modules/ffi# node-gyp rebuild
[...]
david@webserver:~/node_modules/ffi# cd node_modules/ref/
david@webserver:~/node_modules/ffi/node_modules/ref# node-gyp rebuild
[...]

Anschließend sollte das ffi-Modul korrekt geladen werden können.

Libvirt vergisst Memory Unit

Gestern Nacht habe ich viele Stunden mit einem im Nachhinein ziemlich dämlichen Problem verbracht. Meine virtuelle Maschine wollte nach einem Neustart nicht mehr booten, GRUB erzählte zunächst etwas von „Error 15: File not found“ und später nach meinen vergeblichen Reparaturversuchen dann „Error 28: Selected item cannot fit into memory„.

Zum Glück hat mich diese zweite Fehlermeldung auf die richtige Fährte gebracht. Die virtuelle Maschine hatte plötzlich nur noch 16 KiB(!) RAM, und da ist es ja kein Wunder, dass sie nicht booten mochte. Sofort habe ich mir die XML-Definition der virtuellen Maschine anzeigen lassen und las dann Folgendes:

<domain type='kvm'>
 <name>webserver</name>
 <memory>16</memory>
 <currentMemory>16</currentMemory>

Es gab also tatsächlich nur 16 KiB RAM für die virtuelle Maschine. Wie konnte das passieren? Ganz einfach: Laut libvirt-Handbuch kann man im memory-Element ein Attribut namens unit benutzen, um die Einheit der im Element angegebenen Zahl festzulegen. Standardmäßig sind es KiB. Ich hatte Folgendes eingetragen, um der VM bis zu 16 GiB Speicher zu geben:

<domain type='kvm'>
 <name>webserver</name>
 <memory unit='GiB'>16</memory>
 <currentMemory unit='GiB'>16</currentMemory>

Und nun der böse Fehler, aber nicht meinerseits: Beim Speichern der XML-Definition vergisst libvirt das unit-Attribut, so dass am Ende einfach nur noch die Zahl 16 ohne Einheit übrig bleibt, die dann beim nächsten Starten der VM als 16 KiB interpretiert wird. Nun benutze ich 16777216 (KiB), was meinen 16 GiB entspricht, und es gibt keine Probleme mehr.

Ziemlich ärgerlich! Aber immerhin habe ich bei meinen gar nicht notwendig gewesenen Reparaturversuchen etwas über GRUB gelernt und auch zum ersten Mal mit einem VNC-Client auf meine VM zugegriffen, was sehr hilfreich ist, da man ihr damit beim Booten zuschauen kann (ich habe TightVNC benutzt und fand es gut). Ohne VNC-Client hätte ich die Fehlermeldung beim Booten nicht sehen können und wäre noch ratloser gewesen …

Neue Seite auf neuem Server!

Neuer Server: von Host Europe zu Hetzner

Viele Jahre lang bin ich Kunde bei Host Europe gewesen, wo ich einen virtuellen Server für meine Webseiten gemietet hatte. Ein virtueller Server ist für den Einstieg wirklich empfehlenswert, da man im Prinzip nicht begrenzt darin ist, was man damit anstellt, außerdem übernimmt der Hoster das Anfertigen regelmäßiger Backups und kümmert sich um die Hardware.

Ein virtueller Server hat aber auch Nachteile. Erstens muss man sich einen realen Server mit mehreren Kunden teilen. Wie viele das sind, kann man nicht pauschal sagen und hängt sicherlich auch davon ab, wie viel man zu zahlen bereit ist (tendenziell: je teurer, desto weniger virtuelle Server pro realem Server). Die einzelnen virtuellen Server sind zwar voneinander abgeschottet (es wäre ja auch schlimm, wenn nicht!), aber sie beeinflussen sich trotzdem gegenseitig, da sie sich alle dieselbe reale Hardware teilen müssen. Je nach dem, was die „virtuellen Nachbarn“ gerade so zu tun haben, kann dann die Leistung des eigenen Servers schnell in den Keller gehen. Das größte Problem war bei mir die Festplatte, also die Geschwindigkeit von Lese- und Schreibzugriffen.

Nach einiger Überlegung bin ich nun Kunde bei Hetzner und habe mir dort einen dedizierten Server gemietet. Das ist also ein realer Server, der irgendwo in einem Rechenzentrum in einer großen Halle in einem großen Schrank steckt, und dessen Herz nur für mich schlägt. Er kostet nicht viel mehr als mein alter virtueller Server, bietet aber deutlich mehr! Der Neue trägt einen Intel Core i7 2600 in sich (4 Kerne mit bis zu 3.8 GHz) und ist mit 16 GiB RAM ausgestattet, was viermal mehr ist als mein virtueller Server. Mit zwei Festplatten à 3 TB in einem RAID 1-Verbund steht mir nun geradezu lächerlich viel Speicherplatz zur Verfügung, den ich garantiert nie im Leben auch nur annähernd sinnvoll nutzen kann. 100 GB Backup-Platz über FTP gibt’s auch noch dazu. Als Betriebssystem habe ich Ubuntu 12.04 LTS gewählt, da ich mit Ubuntu bereits einige Erfahrungen habe.

Eines gefällt mir an virtuellen Servern sehr gut, man kann sie nämlich extrem leicht sichern und Sicherungen wiederherstellen. Darum läuft der Webserver mit allen Webseiten als virtuelle Maschine auf meinem dedizierten Server. Für die Virtualisierung benutze ich KVM. Nach einigem Tuning erreicht der virtuelle Server fast 100% der Leistung des realen Servers, was CPU, Festplatte und Netzwerk angeht. Für die regelmäßige Komplettsicherung des virtuellen Servers habe ich mir ein nettes Konzept ausgedacht. Die Festplatte des virtuellen Servers ist ein Logical Volume. Wenn ich eine Sicherung anfertigen möchte, halte ich kurz alle datenkritischen Dienste an (Apache, MySQL), erzeuge dann einen Snapshot des Volumes und setze die Dienste wieder fort. Der Snapshot repräsentiert den kompletten Inhalt der virtuellen Festplatte zu einem bestimmten Zeitpunkt und kann nun, während der virtuelle Server fröhlich weiter läuft, im Hintergrund gesichert werden. Die Sicherung findet nicht auf Dateiebene statt, sondern die komplette virtuelle Festplatte wird als ein einziger langer binärer Datenblock gehandhabt. Um inkrementelle Backups zu ermöglichen, werde ich das Volume in kleinere Datenblöcke aufteilen (z.B. 64 MiB). Es müssen nur die Blöcke gesichert werden, die sich seit dem letzten Backup geändert haben. Das kann man mit einer Prüfsumme feststellen. Zusätzlich werden alle Blöcke noch komprimiert werden.

Neue Website: von Contao zu WordPress

Bei jedem Serverwechsel stellt sich die Frage, ob man eine bestehende Website unverändert übernimmt, sie verschrottet oder komplett neu erstellt. Ich tue von allem etwas. Meine private Seite (diese hier!) habe ich mit WordPress neu aufgesetzt. Die alte Seite benutzte ein CMS namens Contao, das früher TYPOlight hieß, und dort hat es mich immer einiges an Überwindung gekostet, etwas Neues hinzuzufügen. Ich hoffe, dass das mit WordPress anders wird und ich öfters einmal bloggen werde. Die Inhalte der Webseite werde ich größtenteils übernehmen.