使用 ZFS 构建易管理的镜像服务器

我们在某机房托管了很多服务器,更新和初次安装时经常会占用大量下行带宽(虽然下行是不收钱的),也拖慢了部署机器的速度,于是我在机房里搭建了一个镜像服务器。

一开始我使用的是 XFS 作为文件系统,在 rsync 列目录和 du 统计文件大小时经常挂住,系统 load 常常能到 60,在某天 … 硬盘终于挂了

于是经由朋友诱惑换到了 ZFS,再也无需担心 load 的问题了 … 抹泪啊真是

那么,ZFS 有啥好的?

首先镜像服务不只是镜像一个发行版,由于历史遗留原因,我们同时在用的发行版有 Red Hat、CentOS、Debian、Ubuntu。

而各种发行版的同步方式并不都是 rsync,如果都是 rsync 的话,加个 --report 参数就能知道每次变更的大小了。那我之前是怎么做的呢?

du -sh ./ 记录一遍,然后再 du -sh ./ 记录一遍,算差值。du 扫目录的时候经常 load 会很高,主要都在等 IO 了。

而换到 ZFS 之后,每个镜像项目是一个单独的 volume,我只需要记录卷占用的变化就可以了,还用扫什么目录啊!

好话说完了那么:

ZFS 有啥不好的呢

ZFS 需要大量的系统资源,另外对 32 位系统的支持不是很好。
当然这都不算问题啦,内存也不贵多买几条就是了然后现在还有人在服务器上用 32 位系统嘛(

下面来讲讲怎么用 …

安装 ZFS on Linux

以下例子中系统环境为 Debian GNU/Linux 7.6 (wheezy) x86_64

1
2
3
4
wget http://archive.zfsonlinux.org/debian/pool/main/z/zfsonlinux/zfsonlinux_2%7Ewheezy_all.deb
sudo dpkg -i zfsonlinux_2~wheezy_all.deb
sudo apt-get update
sudo apt-get install debian-zfs

需要注意的是安装时会编译内核模块,会比较慢,耐心等待就好。

创建存储池

官方文档里推荐是使用 /dev/disk/by-id/ 里的名称来创建存储池,用 /dev/sd* 可能偶尔会导致一些导入错误。

1
zpool create -o ashift=12 mpool /dev/disk/by-id/scsi-14d534654202020207a348b11c863ea4a9099563cb847fbcf

创建完成后可以用 zpool list 命令来检查是否已经成功创建:

1
2
NAME    SIZE  ALLOC   FREE    CAP  DEDUP  HEALTH  ALTROOT
mpool 1.81T 1.72T 95.7G 94% 1.00x ONLINE -

管理镜像项目

首先为这个镜像创建一个 volume:

1
zfs create mpool/puppetlabs-apt

然后进行初次同步

1
2
cd /mpool/puppetlabs-apt
rsync -aHvh --delete --delete-delay --no-owner --no-group --stats --safe-links --timeout=120 --contimeout=120 --delay-updates -4 rsync://apt.puppetlabs.com/packages/apt/ /data/mirror/storage/puppet-deb

这就完了?当然没有。

是不是在 apt-get update 的时候遇到过以下的提示?

1
2
3
4
5
6
7
8
9
10
11
W: Failed to fetch http://mirrors.agslb.com/puppetlabs-apt/dists/trusty/main/source/Sources  404  Not Found

W: Failed to fetch http://mirrors.agslb.com/puppetlabs-apt/dists/trusty/dependencies/source/Sources 404 Not Found

W: Failed to fetch http://mirrors.agslb.com/puppetlabs-apt/dists/trusty/main/binary-amd64/Packages 404 Not Found

W: Failed to fetch http://mirrors.agslb.com/puppetlabs-apt/dists/trusty/dependencies/binary-amd64/Packages 404 Not Found

W: Failed to fetch http://mirrors.agslb.com/puppetlabs-apt/dists/trusty/main/binary-i386/Packages 404 Not Found

W: Failed to fetch http://mirrors.agslb.com/puppetlabs-apt/dists/trusty/dependencies/binary-i386/Packages 404 Not Found

嗯,有了 ZFS,这种现象就不会有啦~

在增量同步前先对当前本地镜像做一次 snapshot:

1
zfs snapshot mpool/puppetlabs-apt@20140829

然后挂载到一个新目录,再将 nginx 里的路径指向这个新目录:

1
mount -t zfs mpool/puppetlabs-apt@20140829 /var/www/mirror/puppetlabs-apt/20140829

同步完成后,再将 nginx 里的路径指向原来的目录即可。是不是很方便呐~

– EOF –