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 HAST, werd ontwikkeld door Pawel Jakub Dawidek 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:

Voor het lezen van deze sectie dient u:

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:

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:

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.

WaarschuwingMomenteel 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 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
# /etc/rc.d/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 opDe 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 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 32.14. 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:

# /etc/rc.d/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 opHoud 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>