19.18. Highly Available Storage (HAST)
Terug | Hoofdstuk 19. Opslag | Volgende

## 19.18. Highly Available Storage (HAST)

Bijgedragen door Daniel Gerzo.
Met informatie van Freddie Cash, Pawel Jakub Dawidek, Michael W. Lucas en Viktor Petersson.

### 19.18.1. Overzicht

Hoge beschikbaarheid is een van de hoofdzaken in serieuze zakelijke toepassingen en hoog beschikbare opslag is een sleutelonderdeel in zulke omgevingen. Hoog beschikbare opslag, of HASTHighly Available STorage, werd ontwikkeld door Pawel Jakub Dawidek `<pjd@FreeBSD.org>` als een raamwerk dat transparante opslag van dezelfde gegevens toestaat over fysiek gescheiden machines die verbonden zijn door een TCP/IP-netwerk. HAST kan gezien worden als een netwerkgebaseerde RAID1 (spiegel) en is vergelijkbaar met het DRBD® opslagsysteem bekend van het GNU/Linux® platform. In combinatie met andere eigenschappen voor hoge beschikbaarheid van FreeBSD zoals CARP maakt HAST het mogelijk om een opslagcluster met hoge beschikbaarheid te bouwen dat resistent is tegen falende hardware.

Na het lezen van deze sectie weet u:

- Wat HAST is, hoe het werkt en welke mogelijkheden het biedt.

- Hoe HAST op FreeBSD te op te zetten en te gebruiken.

- Hoe CARP en devd(8) te integreren om een robuust opslagsysteem te bouwen.

Voor het lezen van deze sectie dient u:

- De beginselen van UNIX® en FreeBSD te begrijpen (Hoofdstuk 4, UNIX® beginselen).

- Te weten hoe de netwerkinterfaces en andere kerndeelsystemen van FreeBSD in te stellen (Hoofdstuk 12, Instellingen en optimalisatie).

- Netwerken op FreeBSD goed te begrijpen (Deel IV, “Netwerkcommunicatie”).

- FreeBSD 8.1-RELEASE of nieuwer te gebruiken.

Het HAST-project werd gesponsord door The FreeBSD Foundation met ondersteuning van OMCnet Internet Service GmbH en TransIP BV.

### 19.18.2. Eigenschappen van HAST

De belangrijkste eigenschappen van HAST zijn:

- Het kan gebruikt worden om I/O-fouten op lokale harde schijven te maskeren.

- Agnostisch qua bestandssysteem, dus het werkt met elk bestandssysteem dat door FreeBSD wordt ondersteund.

- Efficiënte en snelle hersynchronisatie, alleen de blokken die zijn veranderd toen een knooppunt uitstond worden gesynchroniseerd.

- Het kan gebruikt worden in reeds uitgerolde omgevingen om aanvullende redundantie toe te voegen.

- Samen met CARP, Heartbeat of andere gereedschappen kan het worden gebruikt om een robuust en duurzaam opslagsysteem te bouwen.

### 19.18.3. Werking van HAST

Omdat HAST synchrone replicatie op blokniveau van elk opslagmedium naar verscheidene machines biedt, heeft het tenminste twee knooppunten (fysieke machines) nodig — het `primaire` (ook bekend als `meester`) knooppunt en het `secundaire` (`slaaf`) knooppunt. Tezamen worden deze twee machines een cluster genoemd.

### Opmerking:

HAST is momenteel beperkt tot een totaal van twee clusterknooppunten.

Aangezien HAST in een primaire-secundaire configuratie werkt, kan er op elk moment slechts één van de clusterknooppunten actief zijn. Het `primaire` knooppunt, ookwel `actief`, is degene die alle I/O-verzoeken aan apparaten die door HAST worden beheerd afhandelt. Het `secundaire` knooppunt wordt dan automatisch gesynchroniseerd vanuit het `primaire` knooppunt.

De fysieke componenten van het HAST-systeem zijn:

- lokale schijf (op primair knooppunt)

- schijf op verre machine (secundair knooppunt)

HAST werkt synchroon op blokniveau, wat het transparant maakt voor bestandssystemen en toepassingen. HAST biedt reguliere GEOM-aanbieders aan in `/dev/hast/` voor zowel andere gereedschappen als toepassingen, er is dus geen verschil tussen het gebruik van apparaten die door HAST worden geleverd en rauwe schijven, partities, etc.

Elke bewerking met betrekking tot schrijven, verwijderen of spoelen wordt naar de plaatselijke schijf en over TCP/IP naar de verre schijf gestuurd. Elke leesbewerking wordt gedaan door de plaatselijke schijf, tenzij de plaatselijke schijf niet actueel is of er een I/O-fout optreed. In zulke gevallen wordt de leesbewerking naar het secundaire knooppunt gestuurd.

#### 19.18.3.1. Synchronisatie- en replicatiemodi

HAST probeert om een snel herstel van fouten te leveren. Om deze reden is het heel belangrijk om de synchronisatietijd te verkorten nadat een knooppunt is hersteld van een uitval. Om een snelle synchronisatie te leveren, beheert HAST op de schijf een bitmap van gebruikte extents en synchroniseert het die alleen tijdens een reguliere synchronisatie (met uitzondering van de initiëe synchronisatie).

Er zijn vele manieren om synchronisatie af te handelen. HAST implementeert meerdere replicatiemodi om verschillende synchronisatiemethodes af te handelen:

- memsync: rapporteer een schrijfbewerking als voltooid wanneer de plaatselijke schrijfbewerking klaar is en wanneer het verre knooppunt de gegevensaankomst bevestigt, maar voordat het de gegevens daadwerkelijk heeft opgeslagen. De gegevens op het verre knooppunt zullen meteen na het versturen van de bevestiging worden opgeslagen. Deze modus is bedoeld om latency te verminderen en nog steeds een zeer goede betrouwbaarheid te bieden. De replicatiemodus memsync is momenteel niet geïmplementeerd.

- fullsync: rapporteer een schrijfbewerking als voltooid wanneer zowel de plaatselijke en de verre schrijfbewerking voltooid zijn. Dit is de veiligste en traagste replicatiemodus. Dit is de standaardmodus.

- async: rapporteer de schrijfbewerking als voltooid wanneer de plaatselijke schrijfbewerking klaar is. Dit is de snelste en gevaarlijkste replicatiemodus. Het dient gebruikt te worden wanneer er naar een ver knooppunt wordt gerepliceerd en de latency te hoog is voor andere modi. De replicatiemodus async is momenteel niet geïmplementeerd.

### Waarschuwing:

Momenteel wordt alleen de replicatiemodus fullsync ondersteund.

### 19.18.4. HAST-configuratie

HAST heeft ondersteuning voor `GEOM_GATE` nodig om te kunnen functioneren. De kernel `GENERIC` bevat standaard geen `GEOM_GATE`, de laadbare module `geom_gate.ko` is echter beschikbaar in de standaardinstallatie van FreeBSD. Zorg ervoor dat deze module beschikbaar is voor afgeslankte systemen. Het is ook mogelijk om ondersteuning voor `GEOM_GATE` statisch in de kernel te bouwen, door deze regel aan het kernelconfiguratiebestand toe te voegen:

    options	GEOM_GATE

Het HAST-raamwerk bestaat vanuit het besturingssysteem gezien uit verschillende delen:

- het daemon hastd(8) dat verantwoordelijk is voor de gegevenssynchronisatie,

- het beheerprogramma hastctl(8) voor de gebruikers,

- het configuratiebestand hast.conf(5).

Het volgende voorbeeld beschrijft hoe twee knooppunten in een `meester`-`slaaf` / `primaire`-`secundaire` opstelling te configureren door HAST te gebruiken om de gegevens tussen de twee te repliceren. De knooppunten worden `hasta` met IP-adres `172.16.0.1` en `hastb` met IP-adres `172.16.0.2` genoemd. Beide knooppunten hebben een toegewijde harde schijf `/dev/ad6` van dezelfde grootte om met HAST te werken. De HAST-pool (soms ook een hulpbron genoemd, i.e., de GEOM-aanbieder in `/dev/hast/`) wordt `test` genoemd.

Het bestand `/etc/hast.conf` regelt de configuratie van HAST. Dit bestand dient hetzelfde te zijn op beide knooppunten. Het volgende is de eenvoudigste configuratie die mogelijk is:

    resource test {
    	on hasta {
    		local /dev/ad6
    		remote 172.16.0.2
    	}
    	on hastb {
    		local /dev/ad6
    		remote 172.16.0.1
    	}
    }

Raadpleeg voor geavanceerdere configuraties de handleidingpagina hast.conf(5).

### Tip:

Het is ook mogelijk om hostnamen in de regels met `remote` te gebruiken. Zorg er in dat geval voor dat deze hosts vindbaar zijn, bijvoorbeeld doordat ze zijn gedefinieerd in het bestand `/etc/hosts` of anders in het plaatselijke DNS.

Nu de configuratie op beide knooppunten aanwezig is, kan de HAST-pool aangemaakt worden . Voer deze commando's op beide knooppunten uit om de initiële metagegevens op de plaatselijke schijf te plaatsen en het hastd(8)-daemon te starten:

    # hastctl create test
    # service hastd onestart

### Opmerking:

Het is niet mogelijk om GEOM-aanbieders met een bestaand bestandssysteem te gebruiken (i.e., een bestaande opslag omzetten naar een door HAST beheerde pool), omdat deze procedure wat metagegevens op de aanbieder moet opslaan en er daarvoor niet genoeg beschikbare ruimte is.

De rol van een HAST-knooppunt (`primair` of `secundair`) wordt uitgekozen door een beheerder of software zoals Heartbeat dat het gereedschap hastctl(8) gebruikt. Voer het volgende commando uit op het primaire knooppunt ( `hasta`):

    # hastctl role primary test

Voer dit soortgelijke commando uit op het secundaire knooppunt ( `hastb`):

    # hastctl role secondary test

### Let op:

De situatie dat de knooppunten niet met elkaar kunnen communiceren en beide geconfigureerd zijn als primaire knooppunten; wordt `split-brain` genoemd. Volg de stappen zoals beschreven in Paragraaf 19.18.5.2, “Herstellen van de Split-brain-conditie” om deze situatie op te lossen.

Verifieer met het gereedschap hastctl(8) het resultaat op elk knooppunt:

    # hastctl status test

De belangrijke tekst is de regel met `status` dat voor alle knooppunten `complete` dient te bevatten. Als het `degraded` bevat, is er iets verkeerd gegaan. Op dat moment is de synchronisatie tussen de knooppunten al begonnen. De synchronisatie is compleet wanneer `hastctl status` 0 bytes aan `dirty` extents rapporteert.

De volgende stap is het aanmaken van een bestandssysteem op de GEOM-aanbieder `/dev/hast/test` en het aan te koppelen. Dit moet op het `primaire` knooppunt gebeuren, aangezien `/dev/hast/test` alleen op het `primaire` knooppunt verschijnt. Het aanmaken van het bestandssysteem kan afhankelijk van de grootte van de harde schijf enkele minuten duren:

    # newfs -U /dev/hast/test
    # mkdir /hast/test
    # mount /dev/hast/test /hast/test

Wanneer het HAST-raamwerk correct is geconfigureerd, betreft de laatste stap het ervoor zorgen dat HAST automatisch tijdens het opstarten wordt gestart. Voeg deze regel toe aan het bestand `/etc/rc.conf`:

    hastd_enable="YES"

#### 19.18.4.1. Failover-configuratie

Het doel van dit voorbeeld is om een robuust opslagsysteem te bouwen dat resistent is tegen het falen van alle knooppunten. Het scenario is dat een `primair` knooppunt van het cluster faalt. Als dit gebeurt, dan neemt het `secundaire` knooppunt het feilloos over, controleert het het bestandssysteem en koppelt het het bestandssysteem aan, en gaat het verder zonder dat er een bit aan gegevens ontbreekt.

Om dit voor elkaar te krijgen, is er een andere eigenschap die beschikbaar is op FreeBSD dat voorziet in automatische failover van de IP-laag — CARP. CARP (Common Address Redundancy Protocol) maakt het mogelijk dat meerdere hosts in hetzelfde netwerksegment een IP-adres delen. Stel CARP in op beide knooppunten van het cluster volgens de documentatie die beschikbaar is in Paragraaf 31.13, “Common Address Redundancy Protocol (CARP)”. Nadat de opzet voltooid is, heeft elk knooppunt een eigen interface `carp0` met een gedeeld IP-adres `172.16.0.254`. Het primaire HAST-knooppunt van het cluster moet het meester-CARP-knooppunt zijn.

De HAST-pool die in de vorige sectie is gemaakt is nu klaar om geëxporteerd te worden naar de andere hosts op het netwerk. Dit kan gedaan worden door het te exporteren over NFS, Samba, etc., door gebruik te maken van het gedeelde IP-adres `172.16.0.254`. Het enige overgebleven probleem is een automatische failover in het geval dat het primaire knooppunt het begeeft.

Als een CARP-interface aan- of uitgaat, genereert FreeBSD een devd(8)-gebeurtenis, wat het mogelijk maakt om toestandsveranderingen op de CARP-interfaces in de gaten te houden. Een toestandsverandering op het CARP-interface geeft aan dat een van de knooppunten het begaf of weer online kwam. Deze toestandsveranderingen maken het mogelijk om een script te draaien dat automatisch de HAST-failover afhandelt.

Voeg, om toestandsverandering op de CARP-interfaces af te vangen, het volgende toe aan het bestand `/etc/devd.conf` op elk knooppunt:

    notify 30 {
    	match "system" "IFNET";
    	match "subsystem" "carp0";
    	match "type" "LINK_UP";
    	action "/usr/local/sbin/carp-hast-switch master";
    };

    notify 30 {
    	match "system" "IFNET";
    	match "subsystem" "carp0";
    	match "type" "LINK_DOWN";
    	action "/usr/local/sbin/carp-hast-switch slave";
    };

Herstart devd(8) op beide knooppunten om de nieuwe configuratie te laten gelden:

    # service devd restart

Als het interface `carp0` aan of uit gaat (i.e., de toestand van het interface verandert), genereert het systeem een notificatie wat het subsysteem devd(8) in staat stelt om een willekeurig script te draaien, in dit geval `/usr/local/sbin/carp-hast-switch`. Dit is het script dat de automatische failover afhandelt. Raadpleeg de handleidingpagina devd.conf(5) voor verdere uitleg over de bovenstaande configuratie van devd(8).

Dit zou een voorbeeld van zo'n script kunnen zijn:

    #!/bin/sh
    # Origineel script door Freddie Cash <fjwcash@gmail.com>
    # Gewijzigd door Michael W. Lucas <mwlucas@BlackHelicopters.org>
    # en Viktor Petersson <vpetersson@wireload.net>

    # De namen van de HAST-hulpbronnen, zoals vermeld in /etc/hast.conf
    resources="test"

    # vertraging voor het aankoppelen van de HAST-hulpbron na het worden van meester
    # doe een gok
    delay=3

    # logging
    log="local0.debug"
    name="carp-hast"

    # einde van gebruiker-instelbare dingen

    case "$1" in
    	master)
    		logger -p $log -t $name "Omschakelen naar primaire aanbieder voor ${resources}."
    		sleep ${delay}

    		# Wacht totdat de "hastd secondary" processen zijn gestopt
    		for disk in ${resources}; do
    			while $( pgrep -lf "hastd: ${disk} \(secondary\)" > /dev/null 2>&1 ); do
    				sleep 1
    			done

    			# Verwissel de rol voor elke schijf
    			hastctl role primary ${disk}
    			if [ $? -ne 0 ]; then
    				logger -p $log -t $name "Omschakelen van rol naar primair voor hulpbron ${disk} mislukt."
    				exit 1
    			fi
    		done

    		# Wacht totdat de apparaten /dev/hast/* verschijnen
    		for disk in ${resources}; do
    			for I in $( jot 60 ); do
    				[ -c "/dev/hast/${disk}" ] && break
    				sleep 0.5
    			done

    			if [ ! -c "/dev/hast/${disk}" ]; then
    				logger -p $log -t $name "GEOM-aanbieder /dev/hast/${disk} is niet verschenen."
    				exit 1
    			fi
    		done

    		logger -p $log -t $name "Rollen van HAST-hulpbronnen ${resources} omgeschakeld naar primair."

    		logger -p $log -t $name "Schijven aankoppelen."
    		for disk in ${resources}; do
    			mkdir -p /hast/${disk}
    			fsck -p -y -t ufs /dev/hast/${disk}
    			mount /dev/hast/${disk} /hast/${disk}
    		done

    	;;

    	slave)
    		logger -p $log -t $name "Omschakelen naar secundaire aanbieder voor ${resources}."

    		# Schakel de rollen van de HAST-hulpbronnen om
    		for disk in ${resources}; do
    			if ! mount | grep -q "^/dev/hast/${disk} on "
    			then
    			else
    				umount -f /hast/${disk}
    			fi
    			sleep $delay
    			hastctl role secondary ${disk} 2>&1
    			if [ $? -ne 0 ]; then
    				logger -p $log -t $name "Omschakelen van rol naar secundair voor hulpbron ${disk} mislukt."
    				exit 1
    			fi
    			logger -p $log -t $name "Rol van hulpbron ${disk} omgeschakeld naar secundair."
    		done
    	;;
    esac

In een notendop neemt het script deze acties wanneer een knooppunt `meester` / `primair` wordt:

- De HAST-pools opwaarderen naar primair op een gegeven knooppunt.

- Het bestandssysteem onder de HAST-pool controleren.

- De pools op een juiste plaats aankoppelen.

Wanneer een knooppunt `back-up` / `secundair` wordt:

- De HAST-pools afkoppelen.

- De HAST-pools degraderen naar secundair.

### Let op:

Houd in gedachte dat dit slechts een voorbeeldscript is om aan te tonen dat alles werkt. Het behandeld niet alle mogelijke situaties en kan op elke manier worden uitgebreid of veranderd, het kan bijvoorbeeld benodigde diensten starten en stoppen.

### Tip:

Voor dit voorbeeld hebben we een standaard UFS-bestandssysteem gebruikt. Om de tijd die nodig is voor herstel te verkorten, kan een bestandssysteem met UFS-journalling of ZFS worden gebruikt.

Meer gedetailleerde informatie met aanvullende voorbeelden kunnen gevonden worden op de HAST Wiki-pagina.

### 19.18.5. Problemen oplossen

#### 19.18.5.1. Algemene tips om problemen op te lossen

HAST zou over het algemeen zonder problemen moeten werken. Net als met elk ander software-product zijn er momenten waarop het anders werkt dan het zou moeten. De oorzaken van de problemen kunnen verschillen, maar de vuistregel is om ervoor te zorgen dat de klokken zijn gesynchroniseerd op alle knooppunten in het cluster.

Wanneer problemen met HAST worden verholpen, dient het debug-niveau van hastd(8) verhoogd te worden door het daemon hastd(8) met het argument `-d` op te starten. Merk op dat dit argument meerdere malen kan worden opgegeven om het debug-niveau nog verder op te hogen. Op deze manier kan veel nuttige informatie worden vergaard. Overweeg ook om het argument `-F` te gebruiken, dat het daemon hastd(8) in de voorgrond zal starten.

#### 19.18.5.2. Herstellen van de Split-brain-conditie

`Split-brain` treedt op waneer de knooppunten van het cluster niet met elkaar kunnen communiceren, en beide als primair zijn geconfigureerd. Dit is een gevaarlijke situatie omdat het beide knooppunten in staat stelt om incompatibele veranderingen aan de gegevens te maken. Dit probleem dient handmatig door de systeembeheerder te worden gecorrigeerd.

De beheerder moet besluiten welk knooppunt de belangrijkere veranderingen bevat (of ze handmatig samenvoegen) en HAST een volledige synchronisatie op het knooppunt dat de kapotte gegevens heeft laten uitvoeren. Voer hiervoor deze commando's uit op het knooppunt dat opnieuw gesynchroniseerd moet worden:

    # hastctl role init <resource>
    # hastctl create <resource>
    # hastctl role secondary <resource>

Terug | Omhoog | Volgende
19.17. Het versleutelen van de wisselbestand ruimte | Begin | Hoofdstuk 20. GEOM: Modulair schijftransformatie raamwerk