起因

最近我的蜗牛星际测试机在测试一些项目,并且存储了许多重要的测试数据,所以我就准备组一个Raid,保证我的数据安全。但是我又不想动我现有的存储方案,最终就找到了SnapRAID这个解决方案。

SnapRAID简介

SnapRAID介绍:是磁盘整列的备份程序,可存储磁盘的奇偶校验信息,在两个磁盘损坏时也能恢复数据。

SnapRAID定位:家庭媒体中心,特别适合于文件较大较多且较少改变的系统。

SnapRAID特点:

  1. 所有数据都有完整性校验,避免数据悄然损坏;
  2. 如果磁盘损坏的过多影响恢复,那么你损坏的也不是全部数据,未损害硬盘的数据不受影响,可以单独读取;
  3. 如果你不小心删掉了一些数据,你仍然可以恢复它们;
  4. 对于已有数据的磁盘,你无需格式化硬盘便可以加入整列,磁盘中的已有数据不受影响;
  5. 整列的磁盘可以容量不同;
  6. 随时添加磁盘;
  7. 每个磁盘数据相互独立,每个磁盘读写也独立,也就是说可以单盘读写,其余磁盘休眠,节能环保延长磁盘寿命;
  8. 基于上一点特性,你不会因为SnapRAID而提高整个整列的读写性能;
  9. 它不会锁定数据,可以随时停止使用SnapRAID而不需要移除数据或者格式化硬盘,各个磁盘中的数据不受影响,可以单独读写。

各种RAID特性比较

除标准RAID磁盘部署解决方案外,还有众多解决方案。根据奇偶校验的实时性可以把各种冗余分为两大类:

  1. 一类是实时(realtime)奇偶校验的冗余方案,这类方案的冗余不需要人为干预,实时更新,像RAID;
  2. 一类是快照(snapshot)奇偶校验的冗余方案,这类方案的冗余是在接收到人为指令后更新,像Backup。

主要解决方案有:

  1. unRAID-商业和开源GPL2的解决方案,修改版可实现Linux下ReiserFS文件系统实时冗余,不支持任何完整性校验。
  2. FlexRAID-Windows下商业和专有C ++ / Java应用,可有限支持linux。它同时支持快照冗余和实施冗余,支持完整性校验。
  3. disParity-Windows下专有的. NET应用,支持快照冗余和完整性校验。
  4. ZFS-开源文件系统(但与GPL不兼容),支持实时冗余和完整性校验。
  5. Btrfs-开源GPL2授权的文件系统,支持实时冗余,Linux内核3.9以上开始支持RAID 5 / 6冗余和完整性校验。
  6. Storage Spaces-最后是来自微软的方案,改方案已经集成到Win8了,支持专有的实时冗余,不支持完整性校验,但是在ReFS文件系统开始提供一些有限的支持。

这些方案各有优缺点,综合各特性针对于家庭媒体中心的解决方案SnapRAID应运而生:

SnapRAID unRAID FlexRAID disParity ZFS Btrfs Storage Spaces
冗余模式 快照 实时 快照和实时 快照 实时 实时 实时
完整性校验 默认校验方式 支持SpookyHash 128 bit 不支持 支持Adler3232 bit 支持MD5 128 bit 支持fletcher4 256 bit 支持CRC32C 32 bit 不支持
如果发生silent errors可否通过校验盘计算修复 支持 不支持 不支持 不支持 支持 支持 不支持
允许磁盘故障数 1 2 3 4 5 6 1 1 2 3 4 5 6+ 1 1 2 3 1 2 1
如果磁盘损坏块数超过冗余数可否恢复未损坏磁盘数据 支持 支持 支持 支持 不支持 不支持 不支持
读取单个文件时有几块硬盘运行 1 1 1 1 全部 全部 全部
可否添加已有数据的磁盘而不影响磁盘中的数据 支持 不支持 支持 支持 不支持 不支持 不支持
支持的操作系统 Linux | Windows | Mac OS X | OpenIndiana | Solaris | BSD Linux Windows | Linux Windows Mac OS X | OpenIndiana | Solaris | BSD Linux Windows
首次正式支持RAID5冗余及更高冗余的时间 2011 2005 2008 2009 2006 2013 2012
授权和价格 Open Source GPL3 Free Open Source GPL2 69/119/119 Proprietary 40/100/100 Proprietary Free Open Source CDDL Free Open Source GPL2 Free Proprietary Windows 8
交互方式 命令行或 Elucidate 图形 图形 命令行 命令行 命令行 图形

snapraid安装

安装编译软件

apt-get update && apt-get install gcc git make -y

创建编译目录

mkdir -p /tmp/snapraid
cd /tmp/snapraid

下载并解压源码

wget https://github.com/amadvance/snapraid/releases/download/v12.1/snapraid-12.1.tar.gz
tar xzvf snapraid-12.1.tar.gz
cd snapraid-12.1/

编译安装

./configure
make
make check
make install
cp /tmp/snapraid/snapraid-12.1/snapraid.conf.example /etc/snapraid.conf

清除安装文件

rm -rf /tmp/snapraid

下面是我的snapraid.conf配置文件

# Example configuration for snapraid

# Defines the file to use as parity storage
# It must NOT be in a data disk
# Format: "parity FILE [,FILE] ..."
parity /home/备份/snapraid.parity #备份目录,改为自己的目录

# Defines the files to use as additional parity storage.
# If specified, they enable the multiple failures protection
# from two to six level of parity.
# To enable, uncomment one parity file for each level of extra
# protection required. Start from 2-parity, and follow in order.
# It must NOT be in a data disk
# Format: "X-parity FILE [,FILE] ..."
#2-parity /mnt/diskq/snapraid.2-parity
#3-parity /mnt/diskr/snapraid.3-parity
#4-parity /mnt/disks/snapraid.4-parity
#5-parity /mnt/diskt/snapraid.5-parity
#6-parity /mnt/disku/snapraid.6-parity

# Defines the files to use as content list
# You can use multiple specification to store more copies
# You must have least one copy for each parity file plus one. Some more don't hurt
# They can be in the disks used for data, parity or boot,
# but each file must be in a different disk
# Format: "content FILE"
content /var/snapraid/snapraid.content # 文件信息存储目录,文件很小,建议每个硬盘都存放一份
content /home/暂存/snapraid/snapraid.content
content /home/下载/snapraid/snapraid.content
content /home/备份/snapraid/snapraid.content
content /home/服务器/snapraid/snapraid.content

# Defines the data disks to use
# The name and mount point association is relevant for parity, do not change it
# WARNING: Adding here your /home, /var or /tmp disks is NOT a good idea!
# SnapRAID is better suited for files that rarely changes!
# Format: "data DISK_NAME DISK_MOUNT_POINT"
data d1 /home/暂存/ # 数据目录,可以设置多个
data d2 /home/下载/
data d3 /home/服务器/

# Excludes hidden files and directories (uncomment to enable).
#nohidden

# Defines files and directories to exclude
# Remember that all the paths are relative at the mount points
# Format: "exclude FILE"
# Format: "exclude DIR/"
# Format: "exclude /PATH/FILE"
# Format: "exclude /PATH/DIR/"
exclude *.unrecoverable # 排除的文件,就是不要备份的文件,下面有详解
exclude /tmp/
exclude /lost+found/
exclude /data/docker/docker/
exclude /docker/

# Defines the block size in kibi bytes (1024 bytes) (uncomment to enable).
# WARNING: Changing this value is for experts only!
# Default value is 256 -> 256 kibi bytes -> 262144 bytes
# Format: "blocksize SIZE_IN_KiB"
#blocksize 256

# Defines the hash size in bytes (uncomment to enable).
# WARNING: Changing this value is for experts only!
# Default value is 16 -> 128 bits
# Format: "hashsize SIZE_IN_BYTES"
#hashsize 16

# Automatically save the state when syncing after the specified amount
# of GB processed (uncomment to enable).
# This option is useful to avoid to restart from scratch long 'sync'
# commands interrupted by a machine crash.
# It also improves the recovering if a disk break during a 'sync'.
# Default value is 0, meaning disabled.
# Format: "autosave SIZE_IN_GB"
autosave 10 # 生成校验数据时,每处理 10 GiB 数据自动保存一次,方便断点继续

# Defines the pooling directory where the virtual view of the disk
# array is created using the "pool" command (uncomment to enable).
# The files are not really copied here, but just linked using
# symbolic links.
# This directory must be outside the array.
# Format: "pool DIR"
#pool /pool

# Defines a custom smartctl command to obtain the SMART attributes
# for each disk. This may be required for RAID controllers and for
# some USB disk that cannot be autodetected.
# In the specified options, the "%s" string is replaced by the device name.
# Refers at the smartmontools documentation about the possible options:
# RAID -> https://www.smartmontools.org/wiki/Supported_RAID-Controllers
# USB -> https://www.smartmontools.org/wiki/Supported_USB-Devices
#smartctl d1 -d sat %s
#smartctl d2 -d usbjmicron %s
#smartctl parity -d areca,1/1 /dev/sg0
#smartctl 2-parity -d areca,2/1 /dev/sg0

排除列表与包含列表

因为 SnapRAID 是工作在文件系统之上、基于目录的冗余存储方案,因此可以很方便选择哪些目录和文件需要做冗余,哪些不需要。在配置文件中 includeexclude 的规则如下:

  • 可以使用 * ? [1-3] 这样的简单通配符;
  • / 开头的路径匹配的是数据盘的根目录,而不是系统的根目录;
  • / 结尾的路径只会匹配目录;
  • 不以 / 结尾的路径只会匹配文件;
  • 如果最后一条规则是包含include),则所有未匹配的路径都会被排除
  • 如果最后一条规则是排除exclude),则所有未匹配的路径都会被包含

常用的 SnapRAID 命令

  • snapraid sync:根据数据盘生成校验盘;
  • snapraid diff:查看有哪些数据需要 sync;
  • snapraid status:查看磁盘阵列的状态;
  • snapraid scrub:进行数据擦洗,提早发现磁盘阵列中的错误。

SnapRAID 首次同步完成之后,可以将 snapraid syncsnapraid scrub 加入 cron / systemd timer,定时运行。后者默认配置下每次运行擦洗全部数据的 8%,并且会挑选最近 10 天内没有被擦洗过的数据进行擦洗。如果每天运行一次 snapraid scrub 的话,每 12.5 天所有数据都会被擦洗一遍,形成一个健康的循环。

当擦洗发现有数据损坏,或是更糟糕地,某天整块磁盘挂了(不转了),就需要修复数据了。这时候应该做的是停掉所有的定时任务,然后换上新的磁盘,然后用 snapraid fix -d name_of_disk 命令,根据健在磁盘的内容,在新磁盘里重建坏掉磁盘里的内容。只要坏掉的磁盘数量小于等于校验盘的数量,SnapRAID 都能完整地修复数据。

由于 snapraid sync 是定期执行的,这意味着在下次同步之前,磁盘阵列是有机会恢复到上次同步的状态的,因此 snapraid fix 除了可以重建整个磁盘,也可以重建单个文件,也就是反删除。如果你误删除了文件,可以用 snapraid fix -f path/to/file 来恢复文件到上次同步时的状态。

自动备份设置

下面是我写的用过脚本,包括了Sync和Scrub,还有log的存储

mkdir -p /etc/snapraid
nano /etc/snapraid/snapraid.sh

snapraid.sh

#!/bin/bash

# Sync日志存储目录
srlogsyncpath=/root/logs/snapraid/sync
# Scrub日志存储目录
srlogscrubpath=/root/logs/snapraid/scrub

Green="\033[32m"
Red="\033[31m"
Yellow='\033[33m'
Font="\033[0m"
INFO="[${Green}INFO${Font}]"
ERROR="[${Red}ERROR${Font}]"
WARN="[${Yellow}WARN${Font}]"
Time=$(date +"%Y-%m-%d %T")
INFO(){
echo -e "${Time} ${INFO} ${1}"
}
ERROR(){
echo -e "${Time} ${ERROR} ${1}"
}
WARN(){
echo -e "${Time} ${WARN} ${1}"
}

if [ ! -d "${srlogsyncpath}" ]; then
    mkdir -p ${srlogsyncpath}
fi
if [ ! -d "${srlogscrubpath}" ]; then
    mkdir -p ${srlogscrubpath}
fi

srlogname=$(date +%Y%m%d-%H%M%S)

SYNC_PATH=${srlogsyncpath}/${srlogname}.log

INFO "Snapraid sync start" >> ${SYNC_PATH} 2>&1
snapraid sync >> ${SYNC_PATH} 2>&1
INFO "Snapraid sync finish" >> ${SYNC_PATH} 2>&1

SCRUB_PATH=${srlogscrubpath}/${srlogname}.log

INFO "Snapraid scrub start" >> ${SCRUB_PATH} 2>&1
snapraid -p 5 -o 20 scrub >> ${SCRUB_PATH} 2>&1
INFO "Snapraid scrub finish" >> ${SCRUB_PATH} 2>&1

nano /etc/systemd/system/snapraid.service

snapraid.service

[Unit]
Description=Logs system statistics to the systemd journal
Wants=snapraid.timer

[Service]
Type=oneshot
ExecStart=/etc/snapraid/snapraid.sh

[Install]
WantedBy=multi-user.target
nano /etc/systemd/system/snapraid.timer

snapraid.timer

[Unit]
Description=Logs some system statistics to the systemd journal
Requires=snapraid.service

[Timer]
Unit=snapraid.service
OnCalendar=*-*-* 00:00:00 #每天0点自动运行

[Install]
WantedBy=timers.target
systemctl enable snapraid.timer # 开机自启
systemctl start snapraid.timer # 开启循环

第一次可以手动运行,看看正不正常

systemctl start snapraid

默认log文件生成在/var/log/snapraid文件夹下

感谢

https://wzyboy.im/post/1186.html

http://www.songming.me/snapraid-compare.html

https://zhuanlan.zhihu.com/p/32040033

https://zhuanlan.zhihu.com/p/258076824

https://zackreed.me/setting-up-snapraid-on-ubuntu/

http://www.snapraid.it/manual