In meinem Netzwerk verwende ich einen Fileserver, der auf Windows Home Server aufsetzt und als zentraler Datenspeicher für Dokumente, Musik, Fotos, TV-Aufnahmen und diverses anderes dient. Um den Stromverbrauch des Servers zu reduzieren verwende ich das WHS-AddIn Lights-Out. Dieses schickt den Server schlafen, sobald keine anderen Rechner im Netzwerk mehr laufen und weckt ihn automatisch auf, sobald ein Rechner eingeschaltet wird. Das bedeutet eine ordentliche Einsparung im Vergleich zu einem rund um die Uhr laufenden Server.
Allerdings greife ich ja nun nicht ständig auf Daten auf dem Server zu, auch wenn einer der anderen Rechner im Netzwerk läuft. Der Server läuft also immer noch häufig unnötig. Ein Umstand, der mich schon länger stört und für den ich vor einiger Zeit eine Lösung suchte, konnte (bisher) aber keine Lösung finden, die über das hinausgeht, was bereits Lights-Out bietet.
Aber ich bin auf andere Weise fündig geworden: Zu der Zeit entdeckte ich Dokan. Dokan ist eines von zwei mir bekannten Usermode-Filesystemen für Windows (das andere ist das Callback File System von Eldos – Dokan hat den entscheidenden Vorteil Open-Source und kostenlos zu sein). Damit lassen sich recht einfach eigene, virtuelle Laufwerke programmieren.
Damit entstand die Idee zum OnDemandServer (ODS): Der Fileserver wird automatisch geweckt, wenn von einem Client aus auf eine Datei zugegriffen werden soll und nach dem Zugriff wieder in den Standby versetzt.
Das Prinzip ist einfach: Der ODS-Client erzeugt ein virtuelles Laufwerk, das entweder direkt einen Netzwerk-Pfad spiegelt, oder aber Unterverzeichnisse enthält, die dann jeweils unterschiedliche Netzwerkpfade spiegeln. Die grundlegende Implementierung folgt dem mit Dokan mitgelieferten Mirror-Beispiel, das einfach einen beliebigen Pfad als virtuelles Laufwerk spiegelt, was auch problemlos mit Netzwerkpfaden funktioniert. Sobald auf einen der gespiegelten Pfade zugegriffen wird, wird der (entsprechende) Server per WakeOnLAN geweckt, wenn er nicht bereits aktiv ist. Der Client wartet dann auf ein Signal des Servers, dass dieser bereits ist und die Daten stehen zur Verfügung, d.h. sämtliche Datei-Zugriffe werden auf den zugehörigen Netzwerkpfad umgeleitet. Nach einer vordefinierter Zeitspanne nach dem letzten Zugriff wird dann ein Sleep-Befehl an den Server gesendet.
Der ODS-Server ist noch einfacher: Wird der Rechner aus dem Standby aufgeweckt, dann sendet er einen UDP-Broadcast auf einem vordefinierten Port. Dieser wird von den Clients empfangen, die daraufhin eine Kontrollverbindung per TCP zum Server aufbauen, über die regelmäßig „Ja-Ich-Bin-Noch-Da“ Pings geschickt werden. Solange die Kontrollverbindung aktiv ist, werden alle Dateizugriffe direkt umgeleitet. Bricht die Kontrollverbindung ab, muss der Server erst erneut geweckt werden. Sendet ein Client über die Kontrollverbindung ein Sleep-Befehl, dann wird der Server in den Standby versetzt, wenn kein anderer Client mehr aktiv ist.
Ich hatte es damals immerhin geschafft, einen Prototypen nach diesem Prinzip in Delphi zu schreiben, der auch halbwegs vernünftig funktionierte. Dann fehlten mir Zeit und Muße weiter daran zu arbeiten und das ganze rund zu machen. Aber das Prinzip ist definitiv umsetzbar. Wenn ich die alten Projektdaten noch finde, werde ich sie demnächst hier hochladen.
Ideen für den weiteren Ausbau hatte ich auch diverse, beispielsweise das Cachen von Daten: Beim Abspielen einer TV-Aufnahme kann diese auf dem Client gecached werden, damit der Server nicht während der gesamten Abspielzeit laufen muss. Ab einer bestimmten Dateigröße würde der Lese-Zugriff (auch das Schreiben auf dem Cache zu erlauben würde das ganze sehr komplex machen) nicht direkt auf den Netzwerkpfad gemappt, sondern über ein Cache-Objekt geleitet, das die Datei auf den Client kopiert und auf den kopierten Daten arbeitet. So kann der Server schneller wieder in den Schlaf geschickt werden. Im Fall eines Films schon nach ein paar Minuten, statt nach zwei Stunden. Dazu war der Plan Dokan objektorientiert in Delphi umzusetzen, um dann für Dateizugriffe eine Klasse TDokanFile zu verwenden, mit zwei Ableitungen TDokanFile_DirectMapping und TDokanFile_Cached. Dazu bin ich damals allerdings nicht mehr gekommen.
Beim Caching wäre selbstverständlich noch einiges mehr zu berücksichtigen, als da wäre: Mehrfache Zugriffe auf die gleiche Datei. Eine halbwegs intelligente Cache-Verwaltung (wann was löschen, etc.). Reagieren auf Server-seitige Dateiänderungen während des Zugriffs.
Um das Dokan-Projekt ist es leider in letzter Zeit sehr still geworden. Die letzte Version, mit der ich gearbeitet hatte, war Version 0.5irgendwas. Aktuell ist die Version 0.6 vom 12.1.2011. Allerdings gibt es inzwischen einen Dokan-Fork auf Github mit der Versionsnummer 0.6.1, aber er ist im Gegensatz zu Dokan nicht vorcompiliert erhältlich: https://github.com/BenjaminKim/dokanx