menu Chancel's blog
rss_feed
Chancel's blog
有善始者实繁,能克终者盖寡。

使用Rsync结合Inotify实现双机文件热备

作者:Chancel Yang, 创建:2019-03-01, 字数:4785, 已阅:664, 最后更新:2024-03-10

1. 背景

现代Web应用很常见会将用户相关缓存例如头像/附件等文件存储到到本地磁盘,用于程序读取,数据库记录文件的位置即可

这种常规的做法在同步数据库应用的时候就必须保证文件缓存也要一起同步

Linux下最常见的同步工具便是Rsync工具

rsync是类unix系统下的数据镜像备份工具——remote sync。一款快速增量备份工具 Remote Sync,远程同步 支持本地复制,或者与其他SSH、rsync主机同步

搭配Inotify则可以做到实时备份文件

Inotify 是一个 Linux特性,它监控文件系统操作,比如读取、写入和创建。Inotify 反应灵敏,用法非常简单,并且比 cron 任务的繁忙轮询高效得多。

2. 配置

为了方便称呼,将需要备份(数据来源)的服务器称为 Master服务器,简称M服务器,对进行备份存储的服务器称为 Slave服务器,简称S服务器

2.1. Slave服务器初始化

操作系统选用与需要备份的服务器一致,选用国内最常见的 Cent7.6 OS

安装操作系统之后禁止ROOT登录与密码登录,更新国内源并更新操作系统

Bash
cd /etc/yum.repos.d/
sudo mkdir repo_bak
sudo mv * repo_bak/
sudo wget http://mirrors.aliyun.com/repo/Centos-7.repo
sudo wget http://mirrors.163.com/.help/CentOS7-Base-163.repo
sudo yum clean all && sudo yum makecache
sudo yum update

使用 fdisk -l查看附属硬盘情况,此处用于存储的硬盘为 /dev/vdb,初始化硬盘并格式化之后挂载它

Bash
sudo fdisk /dev/vdb
sudo mkfs.ext4 /dev/vdb1
sudo mkdir /mnt/vdb
sudo mount /dev/vdb1 /mnt/vdb

将挂载写入到开机启动中 /etc/fstab

Bash
# 查看硬盘UUID
ll /dev/disk/by-uuid


# 参考我的fstab文件
[chancel@yofus-dev-0002 yum.repos.d]$ cat /etc/fstab 

#
# /etc/fstab
# Created by anaconda on Wed Feb 27 06:58:16 2019
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=4c2c090d-4228-49fc-9cbe-3920b3bf287c /                       ext4    defaults        1 1
UUID=661e9d9e-d80e-4b8a-b52e-01522e96ab2e /mnt/vdb ext4 defaults 0 0

2.1.1. Slave服务器的同步配置

首先安装 rsync

Bash
sudo yum -y install rsync

然后编辑配置文件 sudo vim /etc/rsyncd.conf,配置内容参考下面例子

TEXT
# /etc/rsyncd: configuration file for rsync daemon mode
# See rsyncd.conf man page for more options.
# configuration example:
 uid = root
 gid = root
 use chroot = no
 max connections = 10
 strict modes = no
 # pid文件,如无法再次启动可删除
 pid file = /var/run/rsyncd.pid
 lock file = /var/run/rsyncd.lock
 log file = /var/run/rsyncd.log
# exclude = lost+found/
# transfer logging = yes
# timeout = 900
# ignore nonreadable = yes
# dont compress   = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2
# [ftp]
#        path = /home/ftp
#        comment = ftp export area
[example]
# 本地存放的目录
path = /mnt/vdb/
comment = example rsync backup
ignore errors
read only = no
write only = no
# 多个IP地址可以使用空格隔开 例如 192.168.11.11/24
hosts allow = *
list = false
# 可自定义,确保对目录有写入权限
uid = chancel
gid = chancel
auth users = hot
# 密码文件,内容为“账户:密码”
secrets file = /etc/rsync_user.pass

添加用于备份的用户列表,新增 /etc/rsync_user.pass文件,用户列表格式为 user:password,文件内容如下

TEXT
hot:0a1e9969c6466600e1fb1180fdad7910

修改用户列表文件权限为只读 sudo chmod 400 /etc/rsync_user.pass

添加开机自启rsync,此处端口可自定义,注意与端口客户端保持一致和防火墙放行 sudo echo "/usr/bin/rsync --port=30488 --daemon" >>/etc/rc.local

Cent7需要进一步解锁rc.local权限,否则开机不会启动 sudo chmod 700 /etc/rc.local

S服务器到此配置完毕,重启之后查看rsync进程服务是否正常启动

2.2. Master服务器的同步配置

安装rsync和inotify-tools、supervisord

TEXT
yum -y install rsync inotify-tools supervisord

如果inotify-tools无法通过yum安装(已安装则跳过此步骤),也可从github下载自行编译安装,下面给出参考例子,下载地址可能失效,请自行上GITHUB找

TEXT
# 创建inotiify文件夹
sudo mkdir /opt/inotify-tools-3.14/
sudo chown chancel:chancel /opt/inotify-tools-3.14/
mkdir /tmp/inotify-tools && cd /tmp/inotify-tools
wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz 
tar -zxf inotify-tools-3.14.tar.gz
cd inotify-tools-3.14
# 编译并安装
./configure --prefix=/opt/inotify-tools-3.14/
make && make install

紧接着创建 /etc/rsync_user.pass文件并修改权限,注意M服务器的rsync用户配置文件不需要用户名,只需要输入密码即可

TEXT
sudo echo "0a1e9969c6466600e1fb1180fdad7910" > /etc/rsync_user.pass
sudo chmod 600 /etc/rsync_user.pass

测试同步能否正常运行,如若不能正常运行请根据提示自行排查问题

TEXT
sudo rsync -vzrtopg --delete --progress --password-file=/etc/rsync_user.pass --port=30488 /mnt/vdb/odoo/data_dir hot@139.9.51.220::example

测试同步正常之后,创建自动同步脚本并使用Supervisor后台运行,编辑脚本 sudo vim /etc/inoitify-tools.sh

Bash
#!/bin/bash
/opt/inotify-tools-3.14/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f %e' -e close_write,delete,create,attrib /mnt/vdb/odoo/data_dir \
| while read files
        do
        rsync -vzrtopg --delete --progress --password-file=/etc/rsync_user.pass --port=30488 /mnt/vdb/odoo/data_dir hot@139.9.51.220::example
                echo "${files} was rsynced" >>/tmp/rsync.log 2>&1
        done

3. 测试

为了验证脚本的能力,我们这里尝试添加10w个小文件用于测试 seq 1000000 | xargs -i dd if=/dev/zero of={}.dat bs=1024 count=1

查看文件同步以及日志输出 tail -100f /tmp/rsync.log是否正常

如若正常,配置后台运行Supervisor,编辑 sudo vim /etc/supervisor.d/inoitify-tools.conf

TEXT
[program:inoitify-tools]
command=bash /etc/inoitify-tools.sh
user=chancel
stopsignal=INT
autostart=true
autorestart=true
startsecs=3
stderr_logfile=/var/log/supervisor/inoitify-tools.error.log
stdout_logfile=/var/log/supervisor/inoitify-tools.output.log

[[replyMessage== null?"发表评论":"发表评论 @ " + replyMessage.m_author]]

account_circle
email
web_asset
textsms

评论列表([[messageResponse.total]])

还没有可以显示的留言...
[[messageItem.m_author]] [[messageItem.m_author]]
[[messageItem.create_time]]
[[getEnviron(messageItem.m_environ)]]
[[subMessage.m_author]] [[subMessage.m_author]] @ [[subMessage.parent_message.m_author]] [[subMessage.parent_message.m_author]]
[[subMessage.create_time]]
[[getEnviron(messageItem.m_environ)]]