gmirror und ZFS kombinieren

Daemotron

Well-Known Member
Moin,

ich plane gerade ein Testsystem für STABLE (Server), auf dem ich gerne ZFS einsetzen möchte. Die Maschine ist mit 2 identischen Festplatten ausgestattet. Nun würde ich gerne folgendes tun:

Das Standard-System (/, /var, /usr, /tmp) würde ich gerne auf UFS installieren, und zwar möglichst gespiegelt. Den Rest der Platten würde ich gerne in ein ZFS RaidZ packen.

Nun zum Problem: Von Linux her (Stichwort: Device Mapper, mdadm) kenne ich die Möglichkeit, Partitionen einzeln zu spiegeln. Auf FreeBSD übersetzt würde ich also ad0s1 und ad1s1 spiegeln und aus ad0s2 und ad1s2 einen RAIDZ-Pool bauen.

Dummerweise scheint gmirror darauf ausgelegt zu sein, immer komplette Platten zu verfrühstücken - jedenfalls finde ich in der Manpage und im Handbuch immer nur Hinweise auf ganze Platten. Die Rede ist dort immer von "Component", aber es ist nirgends erläutert, woraus eine Component bestehen kann (dass nur ganze Platten gehen, leite ich aus den gezeigten Beispielen ab - explizit stehen tut das auch nirgends...).

Wenn ich tatsächlich nicht slice-weise spiegeln kann, wäre die einzige andere Option, die ich momentan sehe, ZFS auf dem gm0 obendrauf laufen zu lassen. Wie gesund das allerdings ist, kann ich nicht beurteilen. Wie schaut's aus, hat jemand von Euch schon mal mit sowas hantiert und eine brauchbare Lösung gefunden?
 
Ich kann mir nicht vorstellen, dass es für gmirror einen Unterschied macht ob da eine ganze Platte oder bloß ein slice oder eine Partition ist.

Man kann unter FreeBSD Slices munter schachteln, also ein Slice nehmen und es wie eine normale Platte wieder Slicen.
 
Ich sehe da auch kein Problem. gmirror frist alles, was man ihm vorwirft, egal ob Platte oder nur Slices davon.

Mir ist es bei der Einrichtung von gmirror schon ein paarmal passiert, das ich durch Vertippen/Pennen statt Platten Slices im Verbund hatte.

Einfach als Component Platte+Slice wählen und fertig ist der Lack.

Gruß c.
 
OK, das klingt schon mal ermutigend. Eine Verständnisfrage muss ich an dieser Stelle allerdings noch mal loswerden: Ich gehe jetzt davon aus, dass ich auf beiden Platten mit fdisk -Bf /meine/partitionierung.txt Slices und Bootcode einspiele. Dann baue ich mit gmirror aus den jeweils paarigen Slices ein gm-Device, auf das ich wiederum bsdlabel loslasse - oder muss ich auf einem gm-Device auf jeden Fall eine Partitonstabelle mit fdisk erzeugen?
 
Also erst einmal. Ein BSDlabel ohne Partitionen nennt man "dangerous dedicated". Wie der Name schon sagt ist es böse, man sollte es meiden. Es wurde mit FreeBSD 4.0 als obsolet markiert und zumindest zur Zeit kann FreeBSD 8-CURRENT diese Parititionen nicht ohne weitergehendes Gefrickel lesen. Allerdings gibt es da Kräfte, die es weiter unterstützen wollen. Also, tue dir selbst den Gefallen und lasse es :)

Aber auch sonst. Wenn du eine Partition spiegelst, wieso auf dem Spiegel noch einmal Partitionen anlegen? Eine Komponente des Spiegels wäre dann z.B. ad0s1d1a, wenn man sie einzeln einhängt. Das funktioniert natürlich mit FreeBSD, aber wehe da kommt mal ein anderes OS - wie Windows - zwischen... Das explodiert wunderschön.
 
Hmm, jetzt bin ich vollends verwirrt. Also den Spiegel auf Ebene der Disklabel anlegen? Würde bedeuten, beide Platten in Slices aufteilen, in der ersten Slice auf beiden Platten entsprechende Labels anlegen und dann die jeweiligen Labels per gmirror paaren und auf dem dabei entstehenden gm-Device die Dateisysteme erzeugen?
 
Hallo Ogion,

schau Dir mal http://people.freebsd.org/~rse/mirror/ an, sofern Du noch nicht drüber gestolpert bist. Da wird beschrieben wie Du auch einzelne Slices mit gmirror spiegeln kannst.
Ich bin schon mehrfach nach diesem Beispiel von rse vorgegangen. Funktioniert super. Natürlich kann man an einzelnen Punkten auch variieren. Ich habe z.B. beim letzten Mal noch glabel mit rein genommen.
 
Ja, das ist auch eine sehr gute Frage. Und die Antwort ist im Prinzip von allen schon gegeben worden.

Hier noch mal repetiert, ob ich's auch verstanden habe:

a) natürlich lässt sich eine gesamte Platte als Teil eines Spiegels nutzen. Aber man sollte dann wirklich mit einer entsprechenden Partition arbeiten, wie es Yamagi gesagt hat.

Auf der Platte (in dem Fall ad6) mit fdisk ein Slice ad6s1 anlegen. Das Slice labeln und eine Partition über die gesamte Platte erzeugen:

#bsdlabel -w ad6s1

Das Label mit dem Labeleditor editieren und die Partition ad6s1a, die über die gesamte Platte reicht, als 4.2BSD (unused -> 4.2BSD) Partiton auszeichnen:

#bsdlabel -e ad6s1

# /dev/ad6s1:
# size offset fstype [fsize bsize bps/cpg]
a: 41929571 16 4.2BSD 2048 16384 28528
c: 41929587 0 unused 0 0 # "raw" part, don't edit

(mit ":w" die Änderung speichern und mit ":q" den Editor verlassen ).

Dann hat man eine BSD Partition, die z.B. als Consumer für ein UFS2 Filesystem oder aber auch z.B. für ein gmirror benutzt werden kann.


b) Warum das?

Man könnte ja auch anders vorgehen und z.B. ein Slice (z.B. ad6s1) als Consumer verwenden. Spätestens in dem Moment, wo das Device auch Bootstrap-Code enthält, mutet das doch etwas paradox an:

#fdisk -B /dev/ad6
#bdslabel -B /dev/ad6s1
#newfs -U -O2 /dev/ad6s1 mit als Root-Filesystem

(Also wenn man sich das mal auf der Zunge zergehen lässt, das ist schon ein gewisser Wahnsinn. Was hatte ich mir damals nur dabei gedacht?)

Das hatte mal eine Zeit lang funktioniert, irgendwann ist dann aber beim Systemstart der Loader stehen geblieben, konnte also letztendlich den Kernel nicht nachladen.

Es half dann nur noch, die Fixit-Konsole von CD zu starten und wieder Bootstrap-Code zu installieren (s.o., fdisk -B u. bsdlabel -B), um das System dann wieder zu starten. Dies hielt aber nur ein paar Systemstarts! Die einzig saubere Lösung war dann eben, das System noch mal in einer Partiton ad6s1a zu installieren. Ab dem Punkt konnte dann immer sauber gebootet werden.

---

Also es sind dann wohle solche Konzepte wie Slices und Partitonen zu beachten, da man nie genau weiß, welche Programme was und wann an den Slices und Partitonen machen ohne dass man selbst manuell interveniert. Also ich weiß heute noch nicht, was dafür gesorgt hat, dass ad6s1 vom System manipuliert wurde und es nicht mehr booten konnte.
 
Hallo Ogion,

schau Dir mal http://people.freebsd.org/~rse/mirror/ an, sofern Du noch nicht drüber gestolpert bist. Da wird beschrieben wie Du auch einzelne Slices mit gmirror spiegeln kannst.
Ich bin schon mehrfach nach diesem Beispiel von rse vorgegangen. Funktioniert super. Natürlich kann man an einzelnen Punkten auch variieren. Ich habe z.B. beim letzten Mal noch glabel mit rein genommen.

Danke Dir für den Link - allerdings wird dort genau das beschrieben, was Yamagi (wenn ich ihn richtig verstanden habe) als "böse" bezeichnet hat: Zwei Slices (ad0s1 und ad1s1) werden zu einem gmirror-Device zusammengefasst (gm0). Auf diesem werden dann per bsdlabel die entsprechenden Labels erzeugt, so dass hierbei gm0a, gm0b, etc. entstehen.

spaulding schrieb:
Man könnte ja auch anders vorgehen und z.B. ein Slice (z.B. ad6s1) als Consumer verwenden. Spätestens in dem Moment, wo das Device auch Bootstrap-Code enthält, mutet das doch etwas paradox an:

#fdisk -B /dev/ad6
#bdslabel -B /dev/ad6s1
#newfs -U -O2 /dev/ad6s1 mit als Root-Filesystem
*brr* - das meinst Du nicht ernst, oder? Wenn man Slices als Component verwendet, erhält man ein Mirror-Device (z. B. gm0), das man erst noch mit bsdlabel bearbeiten muss. Ein Dateisystem auf einer Slice zu erzeugen ist nun wirklich nicht das, was ich vorhatte. Wie Du schon berichtet hast, kann man sich dabei den Bootcode zerschießen - und so ganz nebenbei auch die Meta-Informationen, die gmirror im letzten Sektor der Components ablegt.
 
*brr* - das meinst Du nicht ernst, oder? Wenn man Slices als Component verwendet, erhält man ein Mirror-Device (z. B. gm0), das man erst noch mit bsdlabel bearbeiten muss. Ein Dateisystem auf einer Slice zu erzeugen ist nun wirklich nicht das, was ich vorhatte. Wie Du schon berichtet hast, kann man sich dabei den Bootcode zerschießen - und so ganz nebenbei auch die Meta-Informationen, die gmirror im letzten Sektor der Components ablegt.

Richtig! Das was ich geschrieben habe, hat sich erst mal grundsätzlich mit den Slices/Partitionen beschäftigt und hat nichts mit deiner Spiegelung zu tun. Das war einer der groben Schnitzer, die ich mir beim ersten Umgang mit BSD erlaubt habe, weil man da einen Tick weiter denken muss im Gegensatz zu Linux, wo es keine Labels sondern nur fdisk-Partitionen sprich Slices gibt.

Bzgl. der Spiegelung wird wie in gmirror (8) vorgegangen und darauf dann all das an Labeln errichtet, was für Filesysteme benötigt wird. Klaro.
 
Zuletzt bearbeitet:
So, ich hab mal auf meinem elektronischen Schreibblock mitgeschnitten, wie ich das ganze bewerkstelligt habe. Das ganze funktioniert momentan problemlos, allerdings bin ich mir noch nicht sicher, ob ich mit dem, was Yamagi angedeutet hat, bei einem späteren Release von FreeBSD nicht doch Schwierigkeiten bekommen könnte...

Link: http://wiki.my-universe.com/HowTo/FreeBSD/RescueInstall
 
Danke Dir für den Link - allerdings wird dort genau das beschrieben, was Yamagi (wenn ich ihn richtig verstanden habe) als "böse" bezeichnet hat: Zwei Slices (ad0s1 und ad1s1) werden zu einem gmirror-Device zusammengefasst (gm0). Auf diesem werden dann per bsdlabel die entsprechenden Labels erzeugt, so dass hierbei gm0a, gm0b, etc. entstehen.

Soweit ich das verstanden habe könnte der Mirror genauso "gm0s1", "brotkorb" oder sonst wie heißen. Die Labels auf dem Spiegel befinden sich ja nachher auf den Slices, dürfte also nach meinem Verständnis nicht in die Kategorie "dangerous dedicated" gehören.
Ich benenne die Spiegel meist nach dem Schema gmxsy, da erkennt man dann nachher wenigstens noch was das für ein Mirror ist.
 
Ich sehe nicht was an dangerously dedicated so schlimm ist. Dann ist die Platte eben FreeBSD Only. Ich dachte immer das Layering wäre hier transparent, will heißen, ich bin davon ausgegangen bsdlabel nimmt nicht mal war ob es ein Slice oder eine ganze Platte vorgesetzt bekommt.

Ich kann ja auch newfs /dev/da0 bei einem USB-Stick verwenden. Da ich so etwas normalerweise nicht aufteile benötigt es meiner Meinung nach überhaupt keine Partitionierung.
 
In Deinem Wiki-Artikel ist mir gerade aufgefallen, dass Du split für den Mirror verwendest. Sind die Balance-Algorithmen mittlerweile schneller geworden? Ich habe mit load experimentiert, bin aber nachdem es wesentlich langsamer als round-robin war doch wieder zu diesem zurück.
Auf http://www.freebsdwiki.net/index.php/RAID,_performance_tests wurde u.a. auch die Performance der verschiedenen Algorithmen von gmirror getestet, allerdingsnoch mit 6.2:
Only results for gmirror's round-robin balance algorithm are shown here, because the load and split balance algorithms performed even more poorly than round-robin. Results for split are available as raw data if you click the image, but were not included on the graph itself. Load results are not available because initial testing showed it performing even worse than split and so the tests were not allowed to complete.
 
In Deinem Wiki-Artikel ist mir gerade aufgefallen, dass Du split für den Mirror verwendest. Sind die Balance-Algorithmen mittlerweile schneller geworden? Ich habe mit load experimentiert, bin aber nachdem es wesentlich langsamer als round-robin war doch wieder zu diesem zurück.
Hmm, es erschien mir einfach logisch, das split die beste Performance haben müsste, da parallel von beiden Platten gelesen wird. Dass load nicht besonders gut performt, hatte ich befürchtet - schließlich hängen die Platten den Entscheidungen des Kernels zeitlich immer ein gutes Stück hinterher; also ist load abhängig davon, wie gut die load prediction für den Zeitpunkt des tatsächlichen Read ist - hat für mich was von Glaskugel gucken ;)

Aber Du hast mich neugierig gemacht, also hab ich's ausprobiert. Als Testwerkzeug hab ich iozone auf mein RAID losgelassen (ich habe in /var/tmp getestet); Betriebssystem ist ein FreeBSD STABLE (RELENG_7) mit den Sourcen von heute. Vor der Ausführung von iozone hab ich die Kiste jeweils neu gebootet. Hier die Test-Parameter:
Code:
	Madvise enabled: 0
	File size set to 1048576 KB
	Record Size 4 KB
	SYNC Mode. 
	OPS Mode. Output is in operations per second.
	Command line used: iozone -+A1 -i2 -s 1024m -r 4k -o -O
	Time Resolution = 0.000001 seconds.
	Processor cache size set to 1024 Kbytes.
	Processor cache line size set to 32 bytes.
	File stride size set to 17 * record size.
Und hier die Testergebnisse:
Code:
==> iozone-roundrobin.txt <==
                                                            random  random    bkwd   record   stride                                   
              KB  reclen   write rewrite    read    reread    read   write    read  rewrite     read   fwrite frewrite   fread  freread
         1048576       4    1765    2083   390797   392278  140265     233  327824     2232   239656    18374    18032  326679   326255

==> iozone-split.txt <==
                                                            random  random    bkwd   record   stride                                   
              KB  reclen   write rewrite    read    reread    read   write    read  rewrite     read   fwrite frewrite   fread  freread
         1048576       4    1755    2087   391145   390148  140292     233  328843     2271   239136    18243    18217  326735   327317

Wie man sieht, schenken sich die beiden nicht viel; die Abweichungen liegen IMO im Bereich der Meßtoleranzen (auf dem System lief sonst nichts, ist noch sehr jungfräulich). Auf jeden Fall kann man jedoch festhalten, dass split (immerhin die Default-Einstellung von gmirror) nicht schlechter dasteht als round-robin; so verkehrt kann es also nicht sein.

Auf http://www.freebsdwiki.net/index.php/RAID,_performance_tests wurde u.a. auch die Performance der verschiedenen Algorithmen von gmirror getestet, allerdingsnoch mit 6.2:
Hmm, ich vermute mal, dass sich erstens seit 6.x etwas getan hat (definitiv schon mal am Scheduler), und zweitens einfaches kopieren von Dateien vielleicht nicht die aussagekräftigste Benchmark-Methode ist.
 
Soweit ich das verstanden habe könnte der Mirror genauso "gm0s1", "brotkorb" oder sonst wie heißen. Die Labels auf dem Spiegel befinden sich ja nachher auf den Slices, dürfte also nach meinem Verständnis nicht in die Kategorie "dangerous dedicated" gehören.
Exakt. Auf nun gespiegelten Slices liegen wie üblich die Label. Der MBR wird explizit auf ad0 und ad1 eingespielt, boot1+boot2 liegen auf den gespiegelten Slices. Hier wird also nach den üblichen Konventionen Stage 0-3 hochfahren. Ich sehe da auch nichts was "dangerous dedicated" sein könnte.
 
Und die nächste Frage:

Die Spiegelung setzt ja erst auf Ebene der Slices an. Was spricht dagegen, gleich die gesamten Platten zu spiegeln (ad0 + ad1 -> gm0) und ab dem Punkt dann zu fdisken, labeln etc.?

Die Strukturen sind dann auf beiden Platten identisch und das Betriebssystem ist vollständig auf jeder Platte beschrieben.

Ob nun beide Platten funktionieren oder nur eine (bzw. die zweite in einen anderen Rechner eingebaut wird und nun dort ihren eigenen Lebensweg alleine weiter geht), Bootstrap holt sich alles von der ersten Platte. Erst mit geom kommt die zweite Platte ins Spiel, der Spiegel wird erkannt, die Filesystem können gemountet werden, etc. pp. Sobald das System oben ist, werden alle Änderungen egal was man macht auf beiden Platten konsistent gehalten.

Das einzige was sich als Haken und wirkliches Problem herausstellen könnte wäre z.B., wenn während Stage 0-3 die erste Platte modifiziert (oder man auf einmal auf die Idee käme, mit fixit auf einer der Platten rumzufummeln) würde somit der Spiegel nicht mehr konsistent wäre und sich irgendwann im laufenden Betrieb bzw. beim Filesystemcheck Fehler bemerkbar machen würden.
 
Zuletzt bearbeitet:
Code:
read d1 d2 # read device names

fdisk -BI $d1 # create one mbr slice per disk
fdisk -BI $d2

bsdlabel -wB "$d1"s1 # create partitions for / /usr /var ...
bsdlabel -wB "$d1"s1

gmirror label -v -b round-robin root "$d1"s1a # please use *s1a for /
gmirror label -v -b round-robin root "$d2"s1a # repeat this for other planed ufs filesystem

newfs -UL root /dev/mirror/root # repeat this too

# finish with zfs foo

Bootloader sind im MBR, im bsdlabel und in /boot.
ZFSboot sollte es moeglich machen von nicht raidz[12] als / zu booten wenn man das will.
 
Und die nächste Frage:

Die Spiegelung setzt ja erst auf Ebene der Slices an. Was spricht dagegen, gleich die gesamten Platten zu spiegeln (ad0 + ad1 -> gm0) und ab dem Punkt dann zu fdisken, labeln etc.?

Dagegen spricht so lange nichts, wie man die kompletten Platten für UFS und Swap verwenden möchte. Ausgangssituation war aber, dass auch ZFS zum Einsatz kommen sollte - und einen zpool sollte man so tief wie möglich ansetzen, also möglichst direkt auf der Platte, notfalls auf Slices, noch notfälliger auf einem Label, nötigstenfalls auf einem virtuellen Device à la gmirror oder einer Datei.
 
Dagegen spricht so lange nichts, wie man die kompletten Platten für UFS und Swap verwenden möchte. Ausgangssituation war aber, dass auch ZFS zum Einsatz kommen sollte - und einen zpool sollte man so tief wie möglich ansetzen, also möglichst direkt auf der Platte, notfalls auf Slices, noch notfälliger auf einem Label, nötigstenfalls auf einem virtuellen Device à la gmirror oder einer Datei.

Stimmt, das schrobst du in deinem ersten Post:

Ogion schrieb:
Partitionen einzeln zu spiegeln. Auf FreeBSD übersetzt würde ich also ad0s1 und ad1s1 spiegeln und aus ad0s2 und ad1s2 einen RAIDZ-Pool bauen.

Dann ist für mich soweit alles klar. Einen RAIDZ-Pool doppelt spiegeln, das ist wirklich nicht nötig. Danke.
 
Zurück
Oben