Potreboval som vytvoriť lacné prostredie, ktoré by sa čo najviac približovalo finálnej verzii, použitej pri nasadení projektu do produkcie (ľubovoľný počet uzlov na jednom zdieľanom storidži, na ktorý by v danom momente mohli okrem čítania všetky uzly aj zapisovať – rovnocenné uzly).
Text (neviem, či je označiteľný za článok) rozdelím na 2 časti. V prvej budem popisovať problém a riešenie. V druhej popíšem konkrétny postup.
Najmenej nákladným riešením, ktoré mi v tom momente napadlo boli dva servery, ktoré si navzájom budú obojsmerne replikovať dáta a budú mať na sebe distribuovaný filesystém. Bez váhania som si zvolil sadu RHCS (RedHat Cluster Suite), poskytujúcu množstvo užitočných nástrojov, ktorá bude systémom poskytovať GFSv2 (Global Filesystem). Komerčné licencie plnohodnotne ustojí free verzia v podobe CentOS (pravdepodobne aj Fedora, ktorá obsahuje tiež všetko potrebné – neskúšal som). Celá suita sa v release 5 veľmi vylepšila, takže bolesti spôsobované pri verzii 3 a 4 ma teraz už netrápili.
Prvým problémom je samotná replikácia. Na ňu som využil DRBD, ktoré je v CentOS obsiahnuté a už od verzie 8.0 podporuje tzv. Dual-primary mód, kedy sú si oba uzly rovnocenné – dá sa do nich zapisovať. Pred verziou 8.0 fungovalo DRBD ako fail-over – bol primárny uzol, ktorý bol read/write a sekundárny – na ktorý sa replikovali dáta z primárneho (read only). DRBD všetko rieši na relatívne nízkej úrovni. Aby nedochádzalo k sústavnej likvidácii dát, potreboval som filesystém využívajúci zámky, aby si uzly neliezli do kapusty. Na to je GFS ako stvorený, podobne funguje OCFS (Oracle Cluster Filesystem), ktorý ale nepoznám, preto som ani neexperimentoval. Samozrejme, že je viacej podobných filesystémov ale toto nie je text o nich. Druhým problémom je fakt, že RHCS nemá práve najradšej clustre menšie ako 3 uzly – má radšej keď má master uzol, ktorý šéfuje zvyšku (dá sa to napriek tomu prežiť). Posledným problémom je samotný lacný hardvér (skladačky). Štandardne ak cluster zistí, že niektorý uzol má problém, tak vie využiť rôzne možnosti (power switch, fiber switch, drac, ibm rsa...) na zakázanie prístupu problémového uzlu k prostriedkom (fencing). Na skladačke sa väčšina enterprise vecí nenachádza, je teoreticky možné použiť power switch, ten sa ale neodporúča použiť práve v prípade distribuovaných filesystémov. Využil som preto fence_ack_manual, kedy sa ohraničí druhý uzol manuálne. Oficiálne sa táto možnosť neodporúča používať v produkcii, vznikla pre testovacie potreby a kameňom úrazu je to, že na živej nóde treba zadať príkaz, ktorý odblokuje prístup ku GFS, po detekovaní problému s druhým uzlom. Na tom som si vyrobil démona, ktorý to za mňa ošéfuje.
Teraz prakticky. Máme 2 zhodne nainštalované uzly s rovnakou minimálne jednou partíciou, ktorú použijeme na GFS. V oboch serveroch máme po 2 sieťové karty, jednu použijeme na bežnú komunikáciu, druhú si prepojíme napriamo káblom, aby sme v prípade replikácie eliminovali riziko zníženia rýchlosti kvôli pomalej sieti. Takto sa obmedzíme na rýchlosť diskov/diskových polí v uzloch, keďže Gbit (dnes štandardnú kapacitu sieťovej karty) low-cost diskami neprekonáme.
Nainštalujeme, čo potrebujeme (oproti starším RHCS natrepali teraz služby do cman balíka, takže nie je potrebných milión ako v minulosti):
yum install drbd82 kmod-drbd82 cman gfs2-utils
Na sekundárnych sieťovkách použijeme network podľa vlastnej ľubovôle, napríklad 172.16.0.1/30 a 172.16.0.2/30.
Na oboch nódach (ak máme zapnuté redhatovské iptables) urobíme napríklad:
iptables -I RH-Firewall-1-INPUT -i eth1 -j ACCEPT
service iptables save
do /etc/hosts pridáme:
172.16.0.1 node1.local
172.16.0.2 node2.local
a vytvoríme si /etc/drbd.conf:
global { usage-count no; }
common {
syncer {
rate 700000K;
}
}
resource drbd1 {
protocol C;
startup {
become-primary-on both;
wfc-timeout 12;
degr-wfc-timeout 120;
}
net {
allow-two-primaries;
after-sb-0pri discard-least-changes;
after-sb-0pri discard-younger-primary;
after-sb-0pri discard-zero-changes;
after-sb-1pri violently-as0p;
after-sb-2pri violently-as0p;
cram-hmac-alg sha1;
shared-secret "mojsikrit";
}
on node1.real.domain {
device /dev/drbd1;
disk /dev/node1vg/node1srv;
address 172.16.0.1:7789;
meta-disk internal;
}
on node2.real.domain {
device /dev/drbd1;
disk /dev/node2vg/node2srv;
address 172.16.0.2:7789;
meta-disk internal;
}
}
Je to za predpokladu, že /dev/node2vg/node2srv sú na oboch uzloch rovnaké. Samozrejme, že device môže byť akákoľvek. Ak potrebujeme viac replikovaných partícií, tak si môžme obdobne urobit drbd2, drbd3, jankoamarienka atď.
Konfiguračný súbor prenesieme aj na druhý uzol. Urobíme:
drbdadm create-md drbd1
Writing meta data...
initialising activity log
NOT initialized bitmap
New drbd meta data block sucessfully created.
Ak sme na danej partícii mali predtým dáta alebo metablok drbd z nejakých minulých neúspešných pokusov, môžme pomocou /dev/zero prepísať buď metadáta alebo rovno celý disk (dd if=/dev/zero ...)
A následne:
service drbd start
S veľkou pravdepodobnosťou sa drbd prepne do secondary módu a bude označený ako inconsistent (cat /proc/drbd).
Túto chorobu vyliečime:
drbdsetup /dev/drbd1 primary -o
Na prepínač -o pozor, neskôr, keď budú na zariadení dáta, by sme mali dávať na jeho použitie pozor (znamená to, že za každú cenu má zariadenie označiť ako konzistentné, bez ohľadu na stav dát).
Rovnako pomocou drbdadm vytvoríme zariadenie aj na druhom uzle, rovnako zapneme drbd a v /proc/drbd vidíme, že sa disky synchronizujú. Bude to trvať ( v závislosti na veľkosti partície, schopnosti sieťových kariet na eth1 a samozrejme rýchlosti disku/diskov ) niekoľko minút alebo desiatok minút.
Status zdravej drbd jednotky bude potom vyzerať takto:
cat /proc/drbd
version: 8.2.6 (api:88/proto:86-88)
GIT-hash: 3e69822d3bb4920a8c1bfdf7d647169eba7d2eb4 build by buildsvn@c5-x8664-build, 2008-08-07 17:50:35
1: cs:Connected st:Primary/Primary ds:UpToDate/UpToDate C r---
ns:64192 nr:7960 dw:23000 dr:1219772 al:30 bm:9 lo:0 pe:0 ua:0 ap:0 oos:0
Teraz nakonfigurujeme cluster manažéra (/etc/cluster/cluster.conf):
<?xml version="1.0"?>
<cluster name="potemkin" config_version="2">
<cman two_node="1" expected_votes="1">
</cman>
<clusternodes>
<clusternode name="node1.local" votes="1" nodeid="1">
<fence>
<method name="single">
<device name="human" ipaddr="172.16.0.1"/>
</method>
</fence>
</clusternode>
<clusternode name="node2.local" votes="1" nodeid="2">
<fence>
<method name="single">
<device name="human" ipaddr="172.16.0.2"/>
</method>
</fence>
</clusternode>
</clusternodes>
<fencedevices>
<fencedevice name="human" agent="fence_manual"/>
</fencedevices>
</cluster>
Opäť je dôležité, aby bol súbor na oboch strojoch rovnaký, ako aj pri drbd.conf.
Spustíme cman:
/etc/init.d/cman start
Starting cluster:
Loading modules... done
Mounting configfs... done
Starting ccsd... done
Starting cman... done
Starting daemons... done
Starting fencing...
Tu sa fenced zasekne, lebo druhá nóda ešte nebeží. Bude čakať 5 minút, kým ju začne pokladať za nedostupnú. Dovtedy, keď zapneme aj druhú nódu, fence sa spustí, prípadne sa bez čakania spustí aj v prípade, že na aktívnom uzle použijeme fence_ack_manual -n node2.local
Zvolili sme si manuálne ohraničenie pomocou fence_ack_manual a cman sa spustil komplet.
Pozrieme si status clustra:
cman_tool status
Version: 6.1.0
Config Version: 2
Cluster Name: potemkin
Cluster Id: 28388
Cluster Member: Yes
Cluster Generation: 544
Membership state: Cluster-Member
Nodes: 2
Expected votes: 1
Total votes: 2
Quorum: 1
Active subsystems: 7
Flags: 2node Dirty
Ports Bound: 0
Node name: node1.local
Node ID: 1
Multicast addresses: 239.192.110.83
Node addresses: 172.16.0.1
alebo obdobne zoznam uzlov (nód):
cman_tool nodes
Node Sts Inc Joined Name
1 M 540 2008-08-24 15:13:15 node1.local
2 X 552 node2.local
Službu cman zapneme aj na druhej nóde:
service cman start
...
...
cman_tool nodes
Node Sts Inc Joined Name
1 M 540 2008-08-24 15:13:15 node1.local
2 M 560 2008-08-24 15:26:46 node2.local
Je jedno na, ktorej nóde ideme vytvoriť gfs2 partíciu:
mkfs.gfs2 -t potemkin:srv -p lock_dlm -j 2 /dev/drbd1
-t je tzv locktable name, používa sa názov clustra, pre ktorý je a názov filesystému.
-p slúži na výber protokolu pre zamkýňanie zápisov. Gfs sa dá používať aj ako lokálny filesystém, kedy zvolíme bez zamykania, my sme zvolili lock_dlm (distributed lock management) a minimálne v minulosti (neviem ako teraz) ešte existoval aj lock_gnbd (pre zvedavcov global network block device - redhatovský spôsob exportu lokálneho systému po sieti na iné stroje)
-j je počet žurnálov, po prečítaní manuálovej stránky mkfs.gfs2 sa dozviete, že sa dá definovať aj veľkosť žurnálov a niekoľko ďalších vlastností.
A potom už spokojne na oboch nódach:
mount -t gfs2 /dev/drbd1 /srv/
Pozrieme, čo nám teraz cluster všetko poskytuje:
cman_tool services
type level name id state
fence 0 default 00010001 none
[1 2]
dlm 1 srv 00030001 none
[1 2]
gfs 2 srv 00020001 none
[1 2]
Z toho vieme vyčítať, že najnižšie je fence, nad ním dlm, nad ním gfs. Inak povedané, gfs, keďže je nastavený na lock_dlm, nám bez dlm nepôjde, dlm nepôjde bez fenced. Teraz môžme spokojne do /srv písať, nastaviť si naň služby atď. Nezabúdajte však, že RedHat-like systémy bežia štandardne so zapnutým SELinuxom a v príklade použitý /srv je neštandardný adresár, na ktorom nemá nastavené kontexty ani nič. Preto si ho buď dokonfigurujte, použite iné adresáre, alebo ho vypnite (čo by bola škoda).
Ďalej by som odporučil cez chkconfig –del vymazať služby drbd, cman, gfs2 a ostatné, čo chcete spúšťať nad gfs filesystémom a vytvoriť si démona, ktorý to všetko spustí a aj vypne v správnom poradí. RedHatovské init skripty to nemajú práve usporiadané pre takéto riešenie a je jednoduchšie to spustiť z jedného miesta, ako sa trápiť s prioritami a závislosťami initu. Rovnako by vaša služba/démon/čo chcete mala vedieť zavolať fence_ack_manual v prípade priekaku. Môžte použiť lokálny soket vo /var/run/cman_client, alebo jednoduché pingovanie strojov (čo môže byť neplecha, ak sa stroj len resetne), prípadne čítanie statusov zo syslogu, do ktorého cluster všetko píše. Máte neskutočne veľa možností (moje riešenie nie je freeware, tak ho nemôžem zverejniť).
Využiteľnosť tohto riešenia je diskutabilná. Je aj nie je použiteľné v produkčnom prostredí. Určite by som sa pobral cestou fiber diskového poľa, prípadne dualchannel scsi (s tým mám ale z minulosti zlé skúsenosti). V každom prípade, ak je obmedzený rozpočet a je treba vyššiu dostupnosť alebo aj výkon, dá sa uvažovať o výpomoci týmto riešením.
Vďaka zdieľanému read/write môžte urobiť napríklad round-robin v dns, môžte použiť inú časť z cluster suite (piranha), prípadne klasický heartbeat. Čokoľvek.
Cieľom tohto textu nebolo podrobne rozpísať funkcionalitu a možnosti RHCS, ktoré sú oveľa ďalej, ako tento príklad. RHCS poskytuje okrem iného automatické distribuovanie konfigurácií, failoverovanie, balancing atď. To už ale nie je o dvojuzlovom low-coste.
kazdy clanok o GFS je mi sympaticky ;)
priznam sa, neprecital som clanok dokladne, chystam sa na neho az za bieleho dna :-)
.
povedz mi, od coho je dobre aby 2 nody clustru zapisovaly naraz na jeden a ten isty filesystem?
- ide o cluster ako HA (high availability) alebo ako Grid computing?
- ako ako HA - tak je jasne ze app. bezi len na 1 node clustra - naco by mal mat druhy pravo pisat do filesystemu aplikacie ktora bezi na druhom node?
- ak ide o grid - takisto sa mi zda ze vyledok vypoctu nakoniec zapise len jeden nod.
je to riesenie pre load balancing. klasicky pristup k vysokej dostupnosti formou master-slave podla mojho nazoru velmi neefektivne vyuziva systemove prostriedky. grid computing je zase o niecom uplne inom (a len malokedy pracuje s datovymi archivmi).
ten najjednoduchsi priklad (ktory som aj v zavere nacrtol pri spomenuti round-robinu cez dns) je pre web server - mas napriklad nejaky video sharing a klasickym master-slave pristupom ziskas jedine to, ze vies rychlejsie citat ale ked ti ludia zacnu tlacit vela dat na upload tak mozes vyuzit iba mastra, v tomto pripade mas 2 stroje aj pre zapis (a vdaka zapisu encoding) a aj pre citanie. priklad som spomenul lebo je relativne popularny. na internete som cital aj o experimentoch so sambou prave na takomto istom rieseni. ked vezmes do uvahy na mieru robenu aplikaciu, ktora bude bud rozkladat zataz alebo vyuzijes aj dalsie moznosti rhcs na zdielanie ip adresy atd, tak ziskavas ovela komfortnejsi system ako nejaky heartbeat. a teoreticky ak objavis dostatocne inteligentny databazovy endzin ktory vie pouzivat externe zamky na filesysteme, tak nemusis pracne replikovat na urovni databazy. oracle clustre takto funguju bezne (preto aj oracle ma vlastny ocfs) a niekde som cital, ze po troche snahy dokazes podobne osefovat aj mysql (mam v todo) cim sa vyhnes pri stabilnych verziach (po 5.0) nutnosti pouzivat cirkularnu replikaciu (ake vykonne to bude neviem odhadnut).
ako som napisal v uvode, u mna ide len o docasne v podstate "testovacie" prostredie ale pri troche inspiracie sa da najst mnozstvo moznosti.
______________
nález plný strát
No, teraz jedna uplne sprosta otazka, ale na co sa pouzivaju clustre? Este som sa s tym nestretol
najcastejsie sa pouzivaju na zvysenie vykonu alebo/a dostupnosti. load balancing clustre ako napoveda nazov sa vyuzivaju na rozlozenie zataze medzi viacero uzlov (serverov), mozes ich nazvat aj serverovymi farmami (prakticky nasobis svoje kapacity). schrapnel spominal ha clustre, ktore su robene na vysoku dostupnost - garancia sluzieb - tiez mas viac serverov vzajomne prepojenych kde v najjednoduchsom 2uzlovom priklade je jeden master - ktory si drie a drie a ked sa mu nieco stane, tak slave ktory bol dovtedy len v pohotovosti a pripadne si aktualizoval data z mastra preberie funkciu mastra a po obnove sa ten povodny master prepne ako slave (mozes mat viac slave uzlov, viac master uzlov atd...). a do tretice sme spominali gridy, tie sa pouzivaju na distribuovany vypocet, ked sa jedna operacia rozklada na viacej uzlov - pouzivaju sa na rozne simulacie. okrem komercnych a akademickych su gridmi aj projekty ako distributed.net, seti@home a podobne.
______________
nález plný strát
Vdaka za clanok. Zvacsa netusim, o co ide :D, alebo len tak okrajovo, ale rad si vzdy precitam takyto clanok. Really nice :)