树莓派 – 闲鱼二手硬盘组建raid1
一直以来,我都是从家中的树莓派定期同步博客的数据到SD卡以便备份,这样可以一定程度避免云主机故障丢失数据的概率。
但是SD卡毕竟寿命也不太好,所以我就从闲鱼淘了2块500G的二手机械硬盘,组建了软Raid1阵列(raid1就是2份磁盘保存一样的数据)用作数据存储,同时也可以拿来下下电影,总比原先的SD卡靠谱一些吧。
下面先介绍一下树莓派备份博客的技术现状,然后再讲一下我买了什么硬件,做了什么事情。
备份方式
mysql
我在树莓派上也启动了mysql,并且配置了slave实时同步云上的博客数据库。
为了增加数据回滚的能力,我在树莓派上每天会对本地数据库执行依次mysqldump保留一份快照文件,并且会按时间久远程度保留N份历史版本。
wordpress
博客在磁盘上除了有代码外,还有很多上传的附件,因此也需要备份。
我使用rsync每天增量同步数据到树莓派,并且对树莓派本地wordpress目录进行tar打包快照,按时间久远程度保留N份历史版本。
备份程序
程序非常简单,我用python调用shell实现的同步与快照逻辑:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
import os import subprocess import time import fcntl import glob # 项目目录 work_dir = os.path.abspath(os.path.dirname(__file__)) # 数据目录 data_dir = os.path.join(work_dir, 'data') # mysql目录 mysql_dir = os.path.join(data_dir, 'mysql') os.makedirs(mysql_dir, exist_ok=True) # wordpress目录 wordpress_dir = os.path.join(data_dir, 'wordpress') os.makedirs(wordpress_dir, exist_ok=True) # 文件日期 date_name = time.strftime('%Y_%W') # 并发执行锁 def lock(f): def wrapper(*args, **kwargs): with open(os.path.join('/tmp', f.__name__), 'w') as fp: try: fcntl.flock(fp, fcntl.LOCK_EX | fcntl.LOCK_NB) f(*args, **kwargs) fcntl.flock(fp, fcntl.LOCK_UN) except: pass return wrapper # 过期文件清理 def delete_extra_files(pattern, keep_cnt): files = glob.glob(pattern) file_infos = [(fname, os.path.getmtime(fname)) for fname in files] del_files = sorted(file_infos, key=lambda item: item[1], reverse=True)[keep_cnt:] for f in del_files: os.remove(f) @lock def sync_wordpress(): cmd = 'rsync -avz --delete username@domain:/home/web/wordpress {}'.format(wordpress_dir) subprocess.run(cmd, shell=True, check=True) filename = '{}.tar.gz'.format(os.path.join(wordpress_dir, date_name)) cmd = 'tar czvf {} {}'.format(filename, os.path.join(wordpress_dir, 'wordpress')) subprocess.run(cmd, shell=True, check=True) delete_extra_files('{}/*.tar.gz'.format(wordpress_dir), 12) @lock def dump_mysql(): filename = '{}.sql'.format(os.path.join(mysql_dir, date_name)) cmd = 'mysqldump -u username wordpress -p\'password\' > {}'.format(filename) subprocess.run(cmd, shell=True, check=True) delete_extra_files('{}/*.sql'.format(mysql_dir), 12) sync_wordpress() dump_mysql() |
仅供大家简单参考。
购买硬盘盒/托/柜
因为树莓派只有USB口,所以需要买这样的硬盘托来转换,也就是SATA接口转USB3.0。
我购买的就是如图的双盘位硬盘托,2块硬盘插上,然后一根USB3.0线接到电脑/树莓派上,就可以识别出2个块设备 or 盘符,两块盘可以同时读写使用。
当然,这样硬盘托插上硬盘后不太稳定容易晃动,如果有经济条件可以买硬盘柜,可以更好的保护硬盘:
注意硬盘柜很多是带raid卡的,因为raid卡这个东西各家没有统一标准,故障了比较麻烦,建议还是买没有raid卡的,后续通过linux建立软raid即可。
盘位数量根据自己的条件选择即可,为了组建raid至少要2个盘位。
购买硬盘
有经济条件建议买新的硬盘,没有条件买闲鱼翻新货。
硬盘建议购买西数的,最适合做24*7服务的是红盘,但是价格很贵:
其次可以买蓝盘或者绿盘,它们基本就是个家用台式机的水平。
我在闲鱼用100元买了两块500G的二手蓝盘,因为数据也没那么重要,所以无所谓了。
硬盘插到PC上之后不一定显示盘符,因为可能硬盘是个裸盘没做文件系统(也就是没有格式化),所以我们需要一个工具来帮助我们格式化硬盘:diskgenius。如果你经常装windows系统的话应该一点也不陌生。
该工具如果能识别硬盘,则可以对其进行格式化,此后应该可以在我的电脑看见盘符,可以试一下文件读写是否正常。
接下来必须进行坏道检测,看一下硬盘是否是一块好盘。
坏道扫描需要花费数个小时,如果有红色坏道就尝试修复一下,如果坏道修不好或者有很多坏道,那么就联系卖家换退货即可(找个好卖家,保留好聊天记录,少点折腾)。
正常硬盘都提供一个s.m.a.r.t统计信息,点击这里了解,其显示硬盘的历史读写次数和通电时间,但是一般奸商都会抹掉这个信息,所以唯一能验证磁盘好的方法就是检测坏道,然后试试读写速度。
组建raid1
将硬盘托插到树莓派上。
然后看一下2块硬盘的块设备信息是否识别:
1 2 3 4 5 6 7 8 9 |
pi@raspberrypi:~ $ sudo lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 465.8G 0 disk └─md0 9:0 0 465.7G 0 raid1 /home/pi/raid1 sdb 8:16 0 465.8G 0 disk └─md0 9:0 0 465.7G 0 raid1 /home/pi/raid1 mmcblk0 179:0 0 59.5G 0 disk ├─mmcblk0p1 179:1 0 43.9M 0 part /boot └─mmcblk0p2 179:2 0 59.4G 0 part / |
图中是我已经做过raid1的样子。
没做raid1之前,你只能看到sda和sdb两个块设备,也就是两块硬盘,可以查看/dev/sda和/dev/sdb查看这2个块设备。
块设备只有格式化文件系统才能被linux访问,而linux有很多种文件系统可供选择,不同文件系统的特性不同,这里我计划使用普通的ext4文件系统。
但是别着急,软raid技术实际上是虚拟块设备的技术,而不是虚拟文件系统。所以,我们接下来先要创建raid1的虚拟块设备,把sda和sdb两个块设备组建成一个raid1块设备。
操作流程
raid1的效果是双写数据到2个磁盘并保持同步。
网上有一份历史悠久的经典教程,大家可以参考:https://linux.cn/article-6093-1.html。
实际操作过程很简单,首先是安装mdadm这个软raid管理工具:
1 |
sudo apt-get install mdadm |
然后直接创建一个raid1块设备/dev/md0:
1 |
sudo mdadm --create /dev/md0 --level=mirror --raid-devices=2 /dev/sda /dev/sdb |
level=mirror就是指raid1。
然后可以查看raid1的块设备状态:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
pi@raspberrypi:~ $ sudo mdadm --detail /dev/md0 /dev/md0: Version : 1.2 Creation Time : Mon Oct 7 20:52:17 2019 Raid Level : raid1 Array Size : 488255488 (465.64 GiB 499.97 GB) Used Dev Size : 488255488 (465.64 GiB 499.97 GB) Raid Devices : 2 Total Devices : 2 Persistence : Superblock is persistent Intent Bitmap : Internal Update Time : Wed Oct 9 13:11:40 2019 State : clean Active Devices : 2 Working Devices : 2 Failed Devices : 0 Spare Devices : 0 Name : raspberrypi:0 (local to host raspberrypi) UUID : 40f6d90a:241e14a7:804eca4e:45fc187f Events : 14904 Number Major Minor RaidDevice State 0 8 0 0 active sync /dev/sda 1 8 16 1 active sync /dev/sdb |
刚创建的raid1的State会显示为resyncing,这个同步过程会花费数个小时,在此之前两块盘的IO非常高,会持续的做数据同步。
格式化文件系统
有了raid1块设备之后,只需要在块设备上制作文件系统:
1 |
sudo mkfs.ext4 /dev/md0 |
有了文件系统,就可以将其挂载到某个文件路径下使用了:
1 |
sudo mount /dev/md0 /home/pi/raid1/ |
记得给这个路径改一下权限,以便普通用户可以访问到。
自动挂载raid
首先需要开机后自动组建raid1设备,这需要配置mdadm:
1 |
sudo mdadm --detail --scan --verbose >> /etc/mdadm/mdadm.conf |
这会将当前配置的raid信息保存到配置文件里,下次开机mdadm会自动的配置raid1块设备,其内容如下:
1 2 |
ARRAY /dev/md0 level=raid1 num-devices=2 metadata=1.2 name=raspberrypi:0 UUID=40f6d90a:241e14a7:804eca4e:45fc187f devices=/dev/sda,/dev/sdb |
接下来还需要自动挂载文件系统,打开文件/etc/fstab,添加一行:
1 |
/dev/md0 /home/pi/raid1 ext4 defaults 0 0 |
最后
raid1是虚拟块设备,它将metadata保存在每一块盘的super block上,剩余的block会用来做文件系统从而管理用户数据。
如果某块盘挂了,那么换盘重新加入到raid阵列就行,可以参考网上的一些做法。
如果是树莓派系统挂了重做系统或者换了其他设备,那么原先的硬盘直接插到系统上就可以自动被mdadm检测到并恢复raid,自己看一下lsblk即可。
如果没有自动重建则执行下面的第1条指令。
如果重建后mdadm –detail显示resyncing pending的话,可以执行下面的第2条指令立即触发重建。
1 2 |
mdadm --assemble /dev/md0 /dev/sda /dev/sdb mdadm --readwrite /dev/md0 |
全部完成后,重新把配置写入到/etc/mdadm/mdadm.conf和/etc/fstab就行,具体遇到再研究吧。
如果文章帮助您解决了工作难题,您可以帮我点击屏幕上的任意广告,或者赞助少量费用来支持我的持续创作,谢谢~

1