Hochverfügbarkeit ist eine der Hauptanforderungen von
ernsthaften Geschäftsanwendungen und hochverfügbarer Speicher
ist eine Schlüsselkomponente in solchen Umgebungen. Highly
Available STorage, oder HASTHighly Available STorage, wurde von
Pawel Jakub Dawidek <pjd@FreeBSD.org>
als ein Framework entwickelt, welches die transparente
Speicherung der gleichen Daten über mehrere physikalisch getrennte
Maschinen ermöglicht, die über ein TCP/IP-Netzwerk verbunden
sind. HAST kann als ein netzbasiertes RAID1
(Spiegel) verstanden werden und ist dem DRBD®-Speichersystem der
GNU/Linux®-Plattform ähnlich. In Kombination mit anderen
Hochverfügbarkeitseigenschaften von FreeBSD
wie CARP, ermöglicht es
HAST, hochverfügbare Speichercluster zu bauen,
die in der Lage sind, Hardwareausfällen zu widerstehen.
Nachdem Sie diesen Abschnitt gelesen haben, werden Sie folgendes wissen:
Was HAST ist, wie es funktioniert und welche Eigenschaften es besitzt.
Wie man HAST auf FreeBSD aufsetzt und verwendet.
Wie man CARP und devd(8) kombiniert, um ein robustes Speichersystem zu bauen.
Bevor Sie diesen Abschnitt lesen, sollten Sie:
die Grundlagen von UNIX® und FreeBSD verstanden haben (Kapitel 4, Grundlagen des UNIX Betriebssystems).
wissen, wie man Netzwerkschnittstellen und andere Kernsysteme von FreeBSD konfiguriert (Kapitel 12, Konfiguration und Tuning).
ein gutes Verständnis der FreeBSD-Netzwerkfunktionalität besitzen (Teil IV, „Netzwerke“).
FreeBSD 8.1-RELEASE oder höher einsetzen.
Das HAST-Projekt wurde von der FreeBSD Foundation mit Unterstützung der OMCnet Internet Service GmbH und TransIP BV gesponsert.
Die Hauptmerkmale des HAST-Systems sind:
Es kann zur Maskierung von I/O-Fehlern auf lokalen Festplatten eingesetzt werden.
Dateisystem-unabhängig, was es erlaubt, jedes von FreeBSD unterstützte Dateisystem zu verwenden.
Effiziente und schnelle Resynchronisation: es werden nur die Blöcke synchronisiert, die während der Ausfallzeit eines Knotens geändert wurden.
Es kann in einer bereits bestehenden Umgebung eingesetzt werden, um zusätzliche Redundanz zu erreichen.
Zusammen mit CARP, Heartbeat, oder anderen Werkzeugen, ist es möglich, ein robustes und dauerhaftes Speichersystem zu bauen.
HAST stellt auf Block-Ebene eine synchrone
Replikation eines beliebigen Speichermediums auf mehreren Maschinen zur
Verfügung. Daher werden mindestens zwei Knoten (physikalische
Maschinen) benötigt: der primary
(auch bekannt als master
) Knoten, sowie der
secondary
(slave
) Knoten. Diese
beiden Maschinen zusammen werden als Cluster bezeichnet.
HAST ist momentan auf insgesamt zwei Knoten im Cluster beschränkt.
Da HAST in einer
primär-sekundär-Konfiguration funktioniert, ist immer nur ein
Knoten des Clusters zu jeder Zeit aktiv. Der
primäre
Knoten, auch
active
genannt, ist derjenige, der alle I/O-Anfragen
verarbeitet, die an die HAST-Schnittstelle gesendet
werden. Der secondary
-Knoten wird automatisch vom
primary
-Knoten aus synchronisiert.
Die physischen Komponenten des HAST-Systems sind:
lokale Platte (am Primärknoten)
Platte am entfernten Rechner (Sekundärknoten)
HAST arbeitet synchron auf Blockebene, was es
für Dateisysteme und Anwendungen transparent macht.
HAST stellt gewöhnliche GEOM-Provider im
Verzeichnis /dev/hast/
für
die Verwendung durch andere Werkzeuge oder Anwendungen zur
Verfügung, somit gibt es keinen Unterschied zwischen dem Einsatz
von durch HAST bereitgestellten Geräten und
herkömmlichen Platten, Partitionen, etc.
Jede Schreib-, Lösch- oder Entleerungsoperation wird an die lokale und über TCP/IP zu der entfernt liegenden Platte gesendet. Jede Leseoperation wird von der lokalen Platte durchgeführt, es sei denn, die lokale Platte ist nicht aktuell oder es tritt ein I/O-Fehler auf. In solchen Fällen wird die Leseoperation an den Sekundärknoten geschickt.
HAST versucht, eine schnelle Fehlerbereinigung zu gewährleisten. Aus diesem Grund ist es sehr wichtig, die Synchronisationszeit nach dem Ausfall eines Knotens zu reduzieren. Um eine schnelle Synchronisation zu ermöglichen, verwaltet HAST eine Bitmap von unsauberen Bereichen auf der Platte und synchronisiert nur diese während einer regulären Synchronisation (mit Ausnahme der initialen Synchronisation).
Es gibt viele Wege, diese Synchronisation zu behandeln. HAST implementiert mehrere Replikationsarten, um unterschiedliche Methoden der Synchronisation zu realisieren:
memsync: meldet Schreiboperationen als vollständig, wenn die lokale Schreiboperation beendet ist und der entfernt liegende Knoten die Ankunft der Daten bestätigt hat, jedoch bevor die Daten wirklich gespeichert wurden. Die Daten werden auf dem entfernt liegenden Knoten direkt nach dem Senden der Bestätigung gespeichert. Dieser Modus ist dafür gedacht, Latenzen zu verringern und zusätzlich eine gute Verlässlichkeit zu bieten. Der memsync-Replikationsmodus ist momentan noch nicht implementiert.
fullsync: meldet Schreiboperationen als vollständig, wenn die lokale Schreiboperation beendet ist und die entfernte Schreiboperation ebenfalls abgeschlossen wurde. Dies ist der sicherste und zugleich der langsamste Replikationsmodus. Er stellt den momentanen Standardmodus dar.
async: meldet Schreiboperationen als vollständig, wenn lokale Schreibvorgänge abgeschlossen wurden. Dies ist der schnellste und gefährlichste Replikationsmodus. Er sollte verwendet werden, wenn die Latenz zu einem entfernten Knoten bei einer Replikation zu hoch ist für andere Modi. Der async-Replikationsmodus ist zum gegenwärtigen Zeitpunkt nicht implementiert.
Momentan wird nur der fullsync-Replikationsmodus unterstützt.
HAST benötigt
GEOM_GATE
-Unterstützung, um korrekt zu
funktionieren. Der GENERIC
-Kernel enthält
jedoch GEOM_GATE
nicht von
vornherein, jedoch ist in der Standardinstallation von FreeBSD
geom_gate.ko
als ladbares Modul vorhanden.
Stellen Sie bei Systemen, bei denen nur das Allernötigste
vorhanden sein soll, sicher, dass dieses Modul zur Verfügung
steht. Als Alternative lässt sich die
GEOM_GATE
-Unterstützung direkt in den Kernel
statisch einbauen, indem Sie die folgende Zeile zu Ihrer
Kernelkonfigurationsdatei hinzufügen:
Das HAST-Framework besteht aus Sicht des Betriebssystems aus mehreren Bestandteilen:
Dem hastd(8)-Dienst, welcher für die Datensynchronisation verantwortlich ist,
Dem hastctl(8) Management-Werkzeug,
Der Konfigurationsdatei hast.conf(5).
Das folgende Beispiel beschreibt, wie man zwei Knoten als
master
-slave
/
primary
-secondary
mittels
HAST konfiguriert, um Daten zwischen diesen beiden
auszutauschen. Die Knoten werden als
mit der IP-Adresse
hasta
172.16.0.1
und
mit der IP-Adresse
hastb
172.16.0.2
bezeichnet. Beide Knoten
besitzen eine dedizierte Festplatte
/dev/
mit der
gleichen Grösse für den HAST-Betrieb.
Der HAST-Pool (manchmal auch Ressource
genannt, z.B. der GEOM-Provider in ad6
/dev/hast/
) wird als
bezeichnet.test
Die Konfiguration von HAST wird in der Datei
/etc/hast.conf
vorgenommen. Diese Datei sollte
auf beiden Knoten gleich sein. Die denkbar einfachste Konfiguration
ist folgende:
Schlagen Sie in der hast.conf(5)-Manualpage nach, wenn Sie an erweiterten Konfigurationsmöglichkeiten interessiert sind.
Es ist ebenfalls möglich, den Hostnamen in den
remote
-Anweisungen zu verwenden. Stellen Sie in
solchen Fällen sicher, dass diese Rechner auch aufgelöst
werden können, also in der Datei /etc/hosts
aufgeführt sind, oder alternativ im lokalen
DNS.
Da nun die Konfiguration auf beiden Rechnern vorhanden ist, sind Sie in der Lage, den HAST-Pool zu erstellen. Lassen Sie die folgenden Kommandos auf beiden Knoten ablaufen, um die initialen Metadaten auf die lokale Platte zu schreiben und starten Sie anschliessend den hastd(8)-Dienst:
#
hastctl create test
#
/etc/rc.d/hastd onestart
Es ist nicht möglich, GEOM-Provider mit einem bereits bestehenden Dateisystem zu verwenden (z.B. um einen bestehenden Speicher in einen von HAST verwalteten Pool zu konvertieren), weil diese Prozedur bestimmte Metadaten auf den Provider schreiben muss und dafür nicht genug freier Platz zur Verfügung stehen wird.
HAST ist nicht dafür verantwortlich, die Rolle
(primary
oder secondary
) für
den jeweiligen Knoten festzulegen. Die Rolle des Knotens muss vom
Administrator oder einer anderen Software wie
Heartbeat mittels des
hastctl(8)-Werkzeugs festgelegt werden. Auf dem primären
Knoten (
) geben Sie
nun den folgenden Befehl ein:hasta
#
hastctl role primary test
Geben Sie nun, ähnlich wie zuvor, das folgende Kommando auf
dem sekundären Knoten
(
) ein:hastb
#
hastctl role secondary test
Es kann passieren, dass beide Knoten nicht in der Lage sind,
miteinander zu kommunizieren und dadurch beide als primäre
Knoten konfiguriert sind; die Konsequenz daraus wird als
split-brain
bezeichnet. Um diese Situation zu
bereinigen, folgen Sie den Schritten, die in Abschnitt 19.18.5.2, „Auflösung des Split-brain-Zustands“ beschrieben sind.
Es ist möglich das Ergebnis des hastctl(8)-Werkzeugs auf jedem Knoten zu überprüfen:
#
hastctl status test
Der wichtigste Teil ist die status
-Textzeile der
Ausgabe, die auf jedem Knoten complete
lauten
sollte. Falls der Status als degraded
zurückgemeldet wird, ist etwas schief gegangen. Zu diesem
Zeitpunkt hat die Synchronisation zwischen den beiden Knoten bereits
begonnen. Die Synchronisation ist beendet, wenn das Kommando
hastctl status
meldet, dass die
dirty
-Bereiche 0 Bytes betragen.
Der letzte Schritt ist, ein Dateisystem auf dem
/dev/hast/
GEOM-Provider anzulegen und dieses ins System einzuhängen. Dies
muss auf dem test
primary
-Knoten durchgeführt werden
(da /dev/hast/
nur
auf dem test
primary
-Knoten erscheint). Dies kann ein
paar Minuten dauern, abhängig von der Grösse der
Festplatte:
#
newfs -U /dev/hast/test
#
mkdir /hast/test
#
mount /dev/hast/test /hast/test
Sobald das HAST-Framework richtig konfiguriert
wurde, besteht der letzte Schritt nun darin, sicherzustellen, dass
HAST während des Systemstarts automatisch
gestartet wird. Die folgende Zeile sollte zur Datei
/etc/rc.conf
hinzugefügt werden:
Das Ziel dieses Beispiels ist, ein robustes Speichersystem zu
bauen, welches Fehlern auf einem beliebigen Knoten widerstehen kann.
Die Schlüsselaufgabe in diesem Szenario besteht darin, zu
verhindern, dass der primary
-Knoten des Clusters
ausfällt. Sollte es dennoch passieren, ist der
secondary
-Knoten da, um nahtlos einzuspringen, das
Dateisystem zu prüfen, einzuhängen und mit der Arbeit
fortzufahren, ohne dass auch nur ein einzelnes Bit an Daten verloren
ging.
Um diese Aufgabe zu bewerkstelligen, ist es nötig, eine
weitere Eigenschaft zu nutzen, die unter FreeBSD verfügbar ist,
welche ein automatisches Failover auf der IP-Schicht ermöglicht:
CARP. CARP steht für
Common Address Redundancy Protocol und erlaubt es mehreren Rechnern
im gleichen Netzsegment, die gleiche IP-Adresse zu verwenden. Setzen
Sie CARP auf beiden Knoten des Clusters anhand der
Dokumentation in Abschnitt 32.13, „CARP - Common Address Redundancy Protocol“ auf. Nachdem dieser Schritt
abgeschlossen ist, sollte jeder Knoten seine eigene
carp0
-Schnittstelle mit der geteilten
IP-Adresse 172.16.0.254
besitzen.
Selbstverständlich muss der primäre
HAST-Knoten des Clusters der
CARP-Masterknoten sein.
Der HAST-Pool, welcher im vorherigen Abschnitt
erstellt wurde, ist nun bereit für den Export über das
Netzwerk auf den anderen Rechner. Dies kann durch den Export
über NFS, Samba
etc. erreicht werden, indem die geteilte IP-Addresse
172.16.0.254
verwendet wird. Das einzige
ungelöste Problem ist der automatische Failover, sollte der
primäre Knoten einmal ausfallen.
Falls die CARP-Schnittstelle aktiviert oder deaktiviert wird, generiert das FreeBSD-Betriebssystem ein devd(8)-Ereignis, was es ermöglicht, Zustandsänderungen auf den CARP-Schnittstellen zu überwachen. Eine Zustandsänderung auf der CARP-Schnittstelle ist ein Indiz dafür, dass einer der Knoten gerade ausgefallen oder wieder verfügbar ist. In diesem Fall ist es möglich, ein Skript zu starten, welches den Failover automatisch durchführt.
Um diese Zustandsänderungen auf der
CARP-Schnittstelle abzufangen, müssen die
folgenden Zeilen in der Datei /etc/devd.conf
auf
jedem Knoten eingefügt werden:
Um diese neue Konfiguration zu aktivieren, starten Sie devd(8) auf beiden Knoten neu, um die neue Konfiguration wirksam werden zu lassen:
#
/etc/rc.d/devd restart
Für den Fall, dass die
carp0
-Schnittstelle aktiviert oder
deaktiviert wird (sich also der Status der Schnittstelle
ändert), erzeugt das System eine Meldung, was es dem
devd(8)-Subsystem ermöglicht, ein beliebiges Skript zu
starten, in diesem Fall also
/usr/local/sbin/carp-hast-switch
. Dies ist das
Skript, dass den automatischen Failover durchführt. Für
genauere Informationen zu der obigen devd(8)-Konfiguration,
lesen Sie die devd.conf(5)-Manualpage.
Ein Beispiel für ein solches Skript könnte wie folgt aussehen:
Im Kern führt das Skript die folgenden Aktionen durch,
sobald ein Knoten zum master
/
primary
wird:
Es ernennt den HAST-Pool als den primären für einen gegebenen Knoten.
Es prüft das Dateisystem, dass auf dem HAST-Pool erstellt wurde.
Es hängt die Pools an die richtige Stelle im System ein.
Wenn ein Knoten zum backup
/
secondary
ernannt wird:
Hängt es den HAST-Pool aus dem Dateisystem aus.
Degradiert es den HAST-Pool zum sekundären.
Bitte beachten Sie, dass dieses Skript nur ein Beispiel für eine mögliche Lösung darstellt. Es behandelt nicht alle möglichen Szenarien, die auftreten können und sollte erweitert bzw. abgeändert werden, so dass z.B. benötigte Dienste gestartet oder gestoppt werden usw.
Für dieses Beispiel wurde ein Standard-UFS Dateisystem verwendet. Um die Zeit für die Wiederherstellung zu verringern, kann ein UFS mit Journal oder ein ZFS-Dateisystem benutzt werden.
Weitere detaillierte Informationen mit zusätzlichen Beispielen können auf der HAST Wiki-Seite abgerufen werden.
HAST sollte generell ohne Probleme funktionieren. Jedoch kann es, wie bei jeder anderen Software auch, zu gewissen Zeiten sein, dass sie sich nicht so verhält wie angegeben. Die Quelle dieser Probleme kann unterschiedlich sein, jedoch sollte als Faustregel gewährleistet werden, dass die Zeit für beide Knoten im Cluster synchron läuft.
Die Anzahl an Debugging-Meldungen von hastd(8) sollte
erhöht werden, wenn Fehler von HAST bereinigt
werden. Dies kann durch das Starten des hastd(8)-Dienstes mit
der Option -d
erreicht werden. Wichtig zu wissen
ist, dass diese Option mehrfach angegeben werden kann, um die Anzahl
an Meldungen weiter zu erhöhen. Sie können viele
nützliche Informationen auf diese Art bekommen. Sie sollten
ebenfalls die Verwendung der Option -F
in
Erwägung ziehen, die den hastd(8)-Dienst in den Vordergrund
bringt.
Die Konsequenz aus der Situation, wenn beide Knoten des Clusters
nicht in der Lage sind, miteinander zu kommunizieren und dadurch
beide als primäre Knoten fungieren, wird als
split-brain
bezeichnet. Dies ist ein
gefährlicher Zustand, weil es beiden Knoten erlaubt ist,
Änderungen an den Daten vorzunehmen, die miteinander nicht in
Einklang gebracht werden können. Diese Situation sollte vom
Systemadministrator händisch bereinigt werden.
Um diese Situation zu beheben, muss der Administrator entscheiden, welcher Knoten die wichtigsten Änderungen von beiden besitzt (oder diese manuell miteinander vermischen) und anschliessend den HAST-Knoten die volle Synchronisation mit jenem Knoten durchführen zu lassen, welcher die beschädigten Daten besitzt. Um dies zu tun, geben Sie die folgenden Befehle auf dem Knoten ein, der neu synchronisiert werden soll:
#
hastctl role init <resource>
#
hastctl create <resource>
#
hastctl role secondary <resource>
Wenn Sie Fragen zu FreeBSD haben, schicken Sie eine E-Mail an
<de-bsd-questions@de.FreeBSD.org>.
Wenn Sie Fragen zu dieser Dokumentation haben, schicken Sie eine E-Mail an
<de-bsd-translators@de.FreeBSD.org>.