ZFS v13 在FreeBSD 8.0 rc2中的实践

ZFS v13 在FreeBSD 8.0 rc2中的实践

属主:ZoomQuiet

参考:存储的规划[URL:http://www.bsdart.org/archives/20101226/518.html]

概述

本文包含 FreeBSD 8.0rc2 环境中一个 raidz-2+hot spares 配置和测试实例,为其它有意使用 ZFS 代替raid* 来保卫数据安全的SA, 在进行硬盘和 zpool 规划时,提供了一个足够友好的参考。

条件

* OS: FreeBSD svnmain.s.kingsoft.net 8.0-RC1 FreeBSD 8.0-RC1 #0: Thu Sep 17 18:50:57 UTC 2009 root@mason.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC amd64

目标

在足够的硬盘数量支持下:

1,尽可能的使用多的空间
2,运用双奇偶检验来确保数据写安全
3,附加一个热备硬盘来冗灾数据盘的坏损
4,系统分区坏损时也可以立即恢复

硬件

Dell? PowerEdge? 2900 III
6x500G SAS 硬盘
6G 内存

规划

ZFS v13 在FreeBSD 8.0 rc2中的实践

意图

6x300G SAS 空间划分相同=>4G+496G 两部分

    6x4G 空间
    >>3组作系统空间,进行相同的分区,并定期进行 dd 备份
    >>3组作swap 给系统提供 16G 缓存,刚好是内存的两倍
    6x496G 空间
    >>1.5T 可用(3+2) RAID-Z2+1 hot spare

部署

简要说明在部署过程中的关键操作和思路

BIOS

    因为,下单时考虑不周,主机带了个绕不过去的 RAID 卡
    所以,必须先在 BIOS 中使用 raid0 策略对所有硬盘进行配置,否则 FreeBSD 安装程序无法加载硬盘

FreeBSD

* 使用 sysinstall 标准的进行 BSD 安装 * 注意对预备进行系统冗灾备份的分区要进行大小一致的划分(bsdlabel) * 每个分区的大小是精心测算过的:

1,/ → ??Mb 因为
2,/tmp → ??Mb 因为
3,/var → ??Mb 因为
4,/usr → ??Mb 因为

* 这样确保系统在4G 空间中就可以完全运行起来!

geom label

因为将来各个硬盘都有可能先杯具,所以,不能依赖盘序会孬 BIOS 自动调整的 bsd卷标
使用 geom label 进行固化!

##重启系统,在 loader 提示符下键入 4 启动到单用户模式
# glabel label rootfs /dev/mfid0s1a
GEOM_LABEL: Label for provider /dev/mfid0s1a is label/rootfs
# glabel label var /dev/mfid0s1d
GEOM_LABEL: Label for provider /dev/mfid0s1d is label/var
# glabel label usr /dev/mfid0s1f
GEOM_LABEL: Label for provider /dev/mfid0s1f is label/usr
# glabel label tmp /dev/mfid0s1e
GEOM_LABEL: Label for provider /dev/mfid0s1e is label/tmp
# glabel label swap /dev/mfid0s1b
GEOM_LABEL: Label for provider /dev/mfid0s1b is label/swap
# glabel label disk0 /dev/mfid0s2
GEOM_LABEL: Label for provider /dev/mfid0s2 is label/disk0

## 根据规划对所有硬盘的所有分区进行固定卷标
# cat /etc/fstab
… 类似
# Device                Mountpoint      FStype  Options         Dump    Pass#
/dev/label/swap         none            swap    sw              0       0
/dev/label/rootfs       /               ufs     rw              1       1
/dev/label/tmp          /tmp            ufs     rw              2       2
/dev/label/usr          /usr            ufs     rw              2       2
/dev/label/var          /var            ufs     rw              2       2
##正常重启后观察:
$ sudo mount
/dev/label/rootfs on / (ufs, local)
/dev/label/tmp on /tmp (ufs, local, soft-updates)
/dev/label/usr on /usr (ufs, local, soft-updates)
/dev/label/var on /var (ufs, local, soft-updates)

系统的 dd 备份

为确保备用系统分区随时可用,需要进行精密的复制:

#格式
sudo dd if= “系统分区全路径” of=“备份分区全路径”
#本例
sudo dd if=rootfs of=rootfs1
sudo dd if=rootfs of=rootfs2

要将所有系统分区都进行复制

ZFS

建立 3+2 RAID-Z2+1 host spare

$sudo zfs create svnpool raidz2 disk[0-4] spare disk5
$ zpool status
  pool: svnpool
state: ONLINE
scrub: resilver completed after 0h0m with 0 errors on Thu Nov 12 17:35:09 2009
config:

    NAME             STATE     READ WRITE CKSUM
    svnpool          ONLINE       0     0     0
      raidz2         ONLINE       0     0     0
        label/disk0  ONLINE       0     0     0  27.5K resilvered
        label/disk1  ONLINE       0     0     0  29K resilvered
        label/disk5  ONLINE       0     0     0  44K resilvered
        label/disk3  ONLINE       0     0     0  28.5K resilvered
        label/disk4  ONLINE       0     0     0  28K resilvered
    spares
      label/disk2    AVAIL 

$ zpool upgrade -v
This system is currently running ZFS pool version 13.

演习

通过实地热插拔硬盘来模拟实际常见灾难来明确在 ZFS 保卫中的系统和数据恢复

系统盘崩溃

模拟

1,先关机,拔除系统硬盘
2,开机后,无法引导

模拟成功…

处置

1,重启,进入 BIOS
2,调整硬盘启动顺序,指定 disk4/5 任意一块(有系统分区在的)
3,用光盘重启,使用 sysinstall—label功能手动挂载分区表 并写入启动硬盘 M键挂载分区,W写入更改
    第1分区 → /
    第2分区 → /tmp
    第3分区 → /var
    第4分区 → /usr
4,重启,将正常引导,而且使用 zpool status 测试,明确存储池也正常

处置成功,总用时 < 25分钟

数据盘崩溃

模拟

1,拔除任何一颗数据硬盘 (disk1~5)
2,系统丢出错误,重启
3,zfs 将观察到 DEGRADED 状态

模拟成功…

处置

1,先撤出故障盘

$ sudo zpool detach svnpool /dev/label/disk2
zpool status
  pool: svnpool
state: ONLINE
scrub: resilver completed after 0h0m with 0 errors on Thu Nov 12 17:35:09 2009
config:

        NAME             STATE     READ WRITE CKSUM
        svnpool          ONLINE       0     0     0
          raidz2         ONLINE       0     0     0
            label/disk0  ONLINE       0     0     0  27.5K resilvered
            label/disk1  ONLINE       0     0     0  29K resilvered
            label/disk5  ONLINE       0     0     0  44K resilvered
            label/disk3  ONLINE       0     0     0  28.5K resilvered
            label/disk4  ONLINE       0     0     0  28K resilvered
        spares
          label/disk5      INUSE     currently in use

2,FreeBSD 中的ZFS 当前无法自动激活热备件启用,手动替换之
格式: zpool replace svnpool ‘故障盘’ ‘热备件’

$ sudo zpool replace svnpool /dev/label/disk2 /dev/label/disk5
$ zpool status
  pool: svnpool
state: ONLINE
scrub: resilver completed after 0h0m with 0 errors on Thu Nov 12 17:35:09 2009
config:

        NAME             STATE     READ WRITE CKSUM
        svnpool          ONLINE       0     0     0
          raidz2         ONLINE       0     0     0
            label/disk0  ONLINE       0     0     0  27.5K resilvered
            label/disk1  ONLINE       0     0     0  29K resilvered
            label/disk5  ONLINE       0     0     0  44K resilvered
            label/disk3  ONLINE       0     0     0  28.5K resilvered
            label/disk4  ONLINE       0     0     0  28K resilvered

3,待修复故障硬盘或在同一物理位置替换(同大小)物理硬盘之后,手工追加热备件

$ sudo zpool add svnpool spare /dev/label/disk2
$ zpool status
  pool: svnpool
state: ONLINE
scrub: resilver completed after 0h0m with 0 errors on Thu Nov 12 17:35:09 2009
config:

        NAME             STATE     READ WRITE CKSUM
        svnpool          ONLINE       0     0     0
          raidz2         ONLINE       0     0     0
            label/disk0  ONLINE       0     0     0  27.5K resilvered
            label/disk1  ONLINE       0     0     0  29K resilvered
            label/disk5  ONLINE       0     0     0  44K resilvered
            label/disk3  ONLINE       0     0     0  28.5K resilvered
            label/disk4  ONLINE       0     0     0  28K resilvered
        spares
          label/disk2    AVAIL

4,安全起见 zpool clear ,并zpool status -x检查

处置完毕, 用时 10~15分钟

TODO

1,如何对 zpool 的变化进行自动报警?
2,如何自动使用 hot spare 替代离线的硬盘?
3,4G 的系统空间不足时,如何将耗空间的 目录链接到 zpool 中,而又保障依然可以正常用后备系统盘快速恢复?

讨论

这样是否最合理?
如果该主机只用以提供 SVN 服务,还有什么可以优化的?
如果该主机只用以提供 Samba 服务,还有什么可以优化的?
如果该主机只用以提供 ftp 服务,还有什么可以优化的?
如果该主机只用以提供 PostgreSQL 服务,还有什么可以优化的?
如果该主机用以提供 综合 服务,还有什么需要注意的?

原文链接:http://wiki.freebsdchina.org/doc/z/zfsusageforbsd8.0

FreeBSD ZFS存储服务器的规划

FreeBSD ZFS存储服务器的规划

注意:本文内容已经过时。TODO:需要进行一部分改写,包括:zpool根fs不应挂载、关于如何配置纯ZFS系统的介绍、4K扇区等话题。

FreeBSD 7.0具备以 ZFS 作为根文件系统的能力。本文将以一台有6块硬盘的服务器介绍从FreeBSD/amd64 7.0 LiveFS光盘(随发行版发行的LiveCD系统)全新安装一份FreeBSD,并使用ZFS作为根目录的具体方法。

存储的规划

我们假定有6块750GB的SATA硬盘,ad0-ad5;系统有8GB RAM,希望作为存储服务器。在尽量保证数据完整性和性能的前提下,我们会希望有:

    使用五块硬盘作为RAIDZ1或RAIDZ2卷;一块硬盘作为备盘;
    系统的引导和配置信息保存2份,以便当系统无法引导时进行灾难恢复;
    适当大小的 swap 空间,在本例中,我们选择的容量是 8GB。

分区如下所示:

FreeBSD ZFS存储服务器的规划

说明:对于新系统,可以使用 GPT 分区、纯ZFS。此时,分配格局大致如下:

FreeBSD ZFS存储服务器的规划

初始化命令为:

gpart create -s gpt ad0
gpart add -s 94 -t freebsd-boot ad0
gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ad0
gpart add -s 4194304 -t freebsd-swap -l swap0 ad0
gpart add -t freebsd-zfs -l disk0 ad0

准备

使用 LiveFS 光盘引导之后会自动进入sysinstall,选择 Fixit → CDROM。进入Fixit shell,会看到这样的提示符:

Fixit#

这时,我们可以开始分区了。首先,初始化覆盖所有磁盘的slice:

fdisk -IB /dev/ad0
fdisk -I /dev/ad1
fdisk -I /dev/ad2
fdisk -I /dev/ad3
fdisk -I /dev/ad4
fdisk -IB /dev/ad5

接下来在这些磁盘上初始化bsdlabel。由于 bsdlabel 需要调用 vi(透过 EDITOR 环境变量),而 sysinstall会将这个环境变量设置为 /mnt2/stand/vi,因此需要改一下:

unsetenv EDITOR
bsdlabel -wB /dev/ad0s1
bsdlabel -w /dev/ad1s1
bsdlabel -w /dev/ad2s1
bsdlabel -w /dev/ad3s1
bsdlabel -w /dev/ad4s1
bsdlabel -wB /dev/ad5s1

分别编辑这些labels。对于ad0和ad5,类似这样:

8 partitions:
#           size        offset        fstype
a:  4194304              16      unused
c:              *                0       unused
d:             *                 *       unused

对于ad1-ad4,类似这样:

8 partitions:
#           size        offset        fstype
b:  4194304              16      unused
c:              *                0       unused
d:             *                 *       unused

我们希望不因为盘序问题导致混乱,因此会用到 geom label。在本次启动时,我们并不立即创建 ZFS,而只是初始化一个用于启动的 UFS 分区:

newfs -L boot /dev/ad0s1a
mount -o async /dev/ufs/boot /mnt

下面,从光盘上复制一系列文件到这个分区上:

cd /mnt
cp -pR /mnt2/*bin /mnt2/boot /mnt2/etc /mnt2/lib* /mnt2/usr /mnt2/var .
mkdir dev

接下来进行初步的配置:

cd /mnt/boot
rm loader.conf mfsroot.gz
echo "/dev/ufs/boot / ufs rw 0 0" > /mnt/etc/fstab
echo "/dev/ad1s1b none swap sw 0 0" >> /mnt/etc/fstab
echo "/dev/ad2s1b none swap sw 0 0" >> /mnt/etc/fstab
echo "/dev/ad3s1b none swap sw 0 0" >> /mnt/etc/fstab
echo "/dev/ad4s1b none swap sw 0 0" >> /mnt/etc/fstab
touch /etc/rc.conf
cd /
umount /mnt
tunefs -n enable /dev/ufs/boot

现在就可以从硬盘引导系统了。

创建 ZFS

从硬盘引导之后,以 root 身份登录。首先,我们为将要加入 zpool 的磁盘指定 GEOM label:

glabel label disk0 /dev/ad0s1d
glabel label disk1 /dev/ad1s1d
glabel label disk2 /dev/ad2s1d
glabel label disk3 /dev/ad3s1d
glabel label disk4 /dev/ad4s1d
glabel label disk5 /dev/ad5s1d

然后,在其上建立 zpool,我们将这个zpool命名为tank,将disk0-4作为其raidz1成员,并使用disk5作为热备盘:

zpool create tank raidz /dev/label/disk[0-4] spare /dev/label/disk5

此时,这个zpool会被自动挂接到 /tank。如果CPU比较快,通常启用压缩会改善性能:

zfs set compression=on tank

复制文件

首先需要为现在我们用来引导的这个 UFS 卷指定一个归宿:

mkdir /tank/bootdir

系统引导之后,需要访问某些 /boot 的内容:

cd /tank
ln -s bootdir/boot boot

复制 / 到 /tank:

cd /
cp -pR /*bin /etc /lib* /usr /var /tank
mtree -deUf /etc/mtree/BSD.root.dist -p /tank
mtree -deUf /etc/mtree/BSD.var.dist -p /tank/var
chmod u+s,g+s /tank/usr/bin/su

配置以ZFS作为 / 启动,修改 /boot/loader.conf 使其包含:

zfs_load="YES"
vfs.root.mountfrom="zfs:tank"

将 zpool 上的 ZFS 挂接方式改为 legacy:

zfs set mountpoint=legacy tank

在重启之前,需要修改 /etc/fstab:

/dev/ufs/boot /bootdir ufs rw 0 0

重新启动系统。此时根目录应该就是 zfs 了,接下来,可以在 /etc 中进行配置。

此后,建议使用通常的方式联编系统,以确保文件/目录权限的正确性。

配置的备份和同步

我们前面将 /dev/ad5s1a 留作配置备份卷。这个卷在未来出问题的时候应该是可以帮助你启动的,现在我们来对它进行初始化:

newfs -U -L altboot /dev/ad5s1a
mkdir -p /altbootdir

接下来我们需要将 /bootdir 的内容复制过去:

mount /dev/ufs/altboot /altbootdir
cd /bootdir
tar cf – * | tar xf – -C /altbootdir

平时将 /altbootdir 卷卸下即可。当对系统的配置进行较大的变动,特别是对 zpool 内容进行变动或升级内核之后,应再次重复前面的复制步骤。

原文链接:http://wiki.freebsdchina.org/doc/z/zfs_root