ZFS 重複排除 を使用して節約バックアップ (CentOS7)

某バックアップソフトウェアで取得していたCentOS サーバーのバックアップがある日突然エラーになり取得できなくなった。

・メーカーサポートではRedhatしかサポートしてくれない。
・上司もお金は出したくない（とは言わないがなんとかしろとしか言わない）
・取得するサイズはトータル 180GB。
・社内規則により世代バックアップは欲しい(日次 7日)


某バックアップソフトウェアでは重複排除により容量を25% ほどに抑えていた。
最後の要件が普通のNASではだめだったので、ZFS環境で重複排除を試してみることに。

環境：CentOS7

１．ZFS インストール
rpm -ivh http://download.zfsonlinux.org/epel/zfs-release.el7_3.noarch.rpm
yum install -y kernel-devel zfs
reboot


２．zfs module をロードし、filesystem に zfs が追加されたことを確認

/sbin/modprobe zfs
cat /proc/filesystems
> nodev     zfs

３．再起動時に zfs module をロード
vi /etc/modules-load.d/zfs.conf
> zfs

４．zfs デーモン起動
systemctl start zfs-zed.service # ZFS イベントデーモン
systemctl start zfs-share.service # ZFS 共有デーモン
systemctl start zfs.target # ZFS ターゲットデーモン
systemctl start zfs-import-cache.service
systemctl start zfs-import-scan.service 

５．rootpool "disk" を作成し /root/nfs にマウントする 
zpool create -m /root/nfs/ disk /dev/sdd

６．zfs の dedup機能をオン
zfs set dedup=on disk
zfs set atime=off disk
zfs set compression=lz4 disk
zpool set cachefile=/etc/zfs/zpool.cache disk

systemctl enable zfs-zed.service # ZFS イベントデーモン
systemctl enable zfs-share.service # ZFS 共有デーモン
systemctl enable zfs.target # ZFS ターゲットデーモン
systemctl enable zfs-import-cache.service
systemctl enable zfs-import-scan.service 

７．バックアップ
BACURAなるソフトを意気込んで試したもののイメージファイルの重複が利かなかった。ブロックレベルとはなんぞや。
まっとうなスクリプトを書こうとするも3秒ほどで頓挫。

rsyncで放り込んで cp で世代送りする力業で解決することにしました。

``` bash:/etc/cron.daily/zz02_rsync 
#!/bin/sh
rsync -4 -avz --bwlimit=4096 --exclude-from=/root/nfs/conf/getdir.conf --exclude="*" --delete root@<バックアップ先ホスト名>:/ /root/nfs/<ホスト名>/current/
```
``` bash:/root/nfs/conf/getdir.conf
+ /home/***
+ /usr/
+ /usr/local/
+ /usr/local/app/***
+ /usr/local/projects/***
+ /usr/local/svnroot/***
+ /usr/local/trac-backup/***
- *
```
``` bash:/etc/cron.daily/zz01_lifecycle 
#!/bin/sh
# 昨日の日付のディレクトリ作成し、/root/nfs/<バックアップ先ホスト名>/current を放り込む
mkdir "/root/nfs/<バックアップ先ホスト名>/`date '+%Y%m%d' -d yesterday`" 
cp -a /root/nfs/<バックアップ先ホスト名>/current/ /root/nfs/<バックアップ先ホスト名>/`date '+%Y%m%d' -d yesterday`/
#↓外部取込用
#rsync -a --bwlimit=20000 /root/nfs/<バックアップ先ホスト名>/current/ /root/nfs/<バックアップ先ホスト名>/`date '+%Y%m%d' -d yesterday`/
# 作成されたディレクトリ名(日付)を対象に、本日からcurrentを除く6日分を残し、残りのディレクトリを削除
find  /root/nfs/<バックアップ先ホスト名>/ -maxdepth 1 -name current -prune -o -daystart -mtime +6 -type d -print | xargs rm -rf
```
Cronに放り込んで完成。

８．出来上がり
一週間経過した状況。

``` 
[root@hostname]# df -h
ファイルシス            サイズ  使用  残り 使用% マウント位置
/dev/mapper/centos-root    28G  3.5G   25G   13% /
devtmpfs                  3.9G     0  3.9G    0% /dev
tmpfs                     3.9G     0  3.9G    0% /dev/shm
tmpfs                     3.9G   57M  3.9G    2% /run
tmpfs                     3.9G     0  3.9G    0% /sys/fs/cgroup
/dev/sda1                 494M  278M  217M   57% /boot
disk                      1.7T  1.5T  296G   83% /root/nfs　　バックアップディレクトリ
``` 
``` 
[root@hostname]# du -h --max-depth=1 /root/nfs/<バックアップ先ホスト名>/
181G    /root/nfs/<バックアップ先ホスト名>/current
181G    /root/nfs/<バックアップ先ホスト名>/20171127
180G    /root/nfs/<バックアップ先ホスト名>/20171130
180G    /root/nfs/<バックアップ先ホスト名>/20171129
180G    /root/nfs/<バックアップ先ホスト名>/20171124
181G    /root/nfs/<バックアップ先ホスト名>/20171126
181G    /root/nfs/<バックアップ先ホスト名>/20171125
180G    /root/nfs/<バックアップ先ホスト名>/20171128
1.5T    /root/nfs/<バックアップ先ホスト名>/
``` 
``` 
[root@hostname]# zpool list
NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
disk   696G   345G   351G         -    78%    49%  4.24x  ONLINE  -
``` 

7日分 1.7TB相当が 345GB (ALLOCが実使用量) に収まっている。