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 <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).
Te weten hoe de netwerkinterfaces en andere kerndeelsystemen van FreeBSD in te stellen (Hoofdstuk 12).
Netwerken op FreeBSD goed te begrijpen (Deel IV in FreeBSD handboek).
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.
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 staat toe om elk bestandssysteem dat door FreeBSD wordt ondersteund te gebruiken.
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.
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.
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.
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 de volgende 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 simpelst mogelijke configuratie:
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, is het mogelijk om de HAST-pool aan te maken. Voer de volgende 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.
HAST is niet verantwoordelijk voor het kiezen van de rol van een knooppunt (primair of secundair). De rol van een knooppunt dient door een beheerder of andere software zoals Heartbeat gebruikmakend van hastctl(8) te worden geconfigureerd. Voer het volgende commando uit op het primaire knooppunt ( hasta):
# hastctl role primary test
Voer het volgende, soortgelijke, commando uit op het secundaire knooppunt (hastb):
# hastctl role secondary test
Let opHet kan gebeuren dat beide knooppunten niet met elkaar kunnen communiceren en beiden geconfigureerd zijn als primaire knooppunten; het gevolg van deze situatie wordt split-brain genoemd. Volg de stappen zoals beschreven in Paragraaf 19.18.5.2 om deze situatie op te lossen.
Het is mogelijk om met het gereedschap hastctl(8) het resultaat op elk knooppunt te verifiëren:
# hastctl status test
Het belangrijke gedeelte van de uitvoer 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 het commando hastctl status 0 bytes aan dirty extents rapporteert.
De laatste 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), en het enkele minuten kan duren afhankelijk van de grootte van de harde schijf:
# 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. De volgende regel dient aan het bestand /etc/rc.conf te worden toegevoegd:
hastd_enable="YES"
Het doel van dit voorbeeld is om een robuust opslagsysteem te bouwen dat resistent is tegen het falen van alle knooppunten. De hoofdtaak is het oplossen van een scenario waarin een primair knooppunt van het cluster faalt. Mocht dit gebeuren, dan neemt het secundaire knooppunt het feilloos over, controleert en koppelt het het bestandssysteem aan, en gaat het verder zonder dat er een bit aan gegevens ontbreekt.
Om deze taak voor elkaar te krijgen, is het nodig om een andere eigenschap te gebruiken die beschikbaar is op FreeBSD en dat voorziet in automatische failover van de IP-laag -- CARP. CARP staat voor Common Address Redundancy Protocol en 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 deze taak voltooid is, zou elk knooppunt een eigen interface carp0 met een gedeeld IP-adres 172.16.0.254 moeten hebben. 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. In zulke gevallen is het mogelijk om een script te draaien dat automatisch de failover afhandelt.
Om de toestandsverandering op de CARP-interfaces af te vangen, dient de volgende configuratie te worden toegevoegd 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"; };
Draai het volgende commando 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).
Het volgende 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 doet het script het volgende 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 de juiste plaats aankoppelen.
Wanneer een knooppunt backup / secundair wordt:
De HAST-pools afkoppelen.
De HAST-pools degraderen naar secundair.
Let opHoud in gedachte dat dit slechts een voorbeeldscript is dat dienst doet 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 het doel van 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.
HAST zou over het algemeen zonder problemen moeten werken, maar 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.
Het debug-niveau van hastd(8) dient verhoogd te worden wanneer problemen met HAST worden verholpen. Dit kan gedaan 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. Het is ook de moeite te overwegen om het argument -F te gebruiken, dat het daemon hastd(8) in de voorgrond zal starten.
Het gevolg van de situatie waarin beide knooppunten van het cluster niet met elkaar kunnen communiceren en beide als primaire knooppunten zijn ingesteld wordt split-brain genoemd. Dit is een gevaarlijke situatie omdat het beide knooppunten in staat stelt om incompatibele veranderingen aan de gegevens te maken. Deze situatie dient handmatig door de systeembeheerder te worden afgehandeld.
Om deze situatie op te lossen moet de beheerder besluiten welk knooppunt de belangrijkere veranderingen bevat (of ze handmatig samenvoegen) en HAST de volledige synchronisatie op het knooppunt dat de kapotte gegevens heeft laten uitvoeren. Voer hiervoor de volgende commando's uit op het knooppunt dat opnieuw gesynchroniseerd moet worden:
# hastctl role init <resource> # hastctl create <resource> # hastctl role secondary <resource>