nfs实时备份案例

nfs网络文件系统

实现流程

nfs实时备份案例

本地文件操作方式

1.当用户执行mkdir命令,该命令会调用shell解释器翻译给内核
2.内核解析完成后会驱动对应的硬件设备,完成相应的操作

NFS实现原理(需要先了解[程序|进程|线程])

1.用户进程访问NFS客户端,使用不同的函数对数据进行处理
2.NFS客户端通过TCP/IP的方式传递给NFS服务端
3.NFS服务端接收到请求后,会先调用portmap进程进行端口映射
4.nfsd进程用于判断NFS客户端是否有用权限连接NFS服务端
5.Rpc.mount进程判断客户端是否有对应的权限进行验证
6.idmap进程实现用户映射和压缩
7.最后NFS服务端会将对应请求的函数转换为本地能识别的命令,传递至内核,由内核驱动硬件
注意:rpc是一个远程调用过程协议,那么使用nfs必须有rpc服务

nfs安装配置启动

centos7.5					NFS服务端		192.168.250.139      nfs01
centos7.5					NFS客户端		192.168.250.137			 head
# 关闭防火墙
nfs01]>>> systemctl disable firewalld
nfs01]>>> systemctl stop firewalld
# 关闭selinux防火墙
nfs01]>>> sed -ri '#^SELINUX=#cSELINUX=Disabled' /etc/selinux/config
nfs01]>>> setenforce 0
# 安装
nfs01]>>> yum install nfs-utils -y
nfs01]>>> systemctl start rpcbind
nfs01]>>> systemctl enable rpcbind

# 配置nfs服务,nfs服务程序的配置文件为`/etc/exports`,需要严格按照共享目录的路径,允许访问的NFS客户端(共享权限参数)格式书写,定义要共享的目录与相应的权限,如下
>>> man exports
# sample /etc/exports file  示例
/               master(rw) trusty(rw,no_root_squash)  # 共享的目录(/),共享给谁(主机名(权限))
/projects       proj*.local.domain(rw)
/usr            *.local.domain(ro) @trusted(rw)
/home/joe       pc001(rw,all_squash,anonuid=150,anongid=100)
/pub            *(ro,insecure,all_squash)
/srv/www        -sync,rw server @trusted @external(ro)
/foo            2001:db8:9:e54::/64(rw) 192.0.2.0/24(rw)
/build          buildhost[0-9].local.domain(rw)
# 示例
配置语法				/data					192.168.250.0/24				(rw,sync,all_squash)
语法含义				NFS共享目录			NFS客户端地址				(参数1,参数2....)

# 配置场景,将nfs服务端的/data目录共享给192.168.250.0/24网段内的所有主机
1)所有客户端主机都拥有读写权限
2)在将数据写入到NFS服务器的硬盘中后才会结束操作,最大限度保证数据不丢失
3)将所有用户映射为本地的匿名用户(nfsnobody)
# NFS客户端地址与权限之间没有空格
nfs01]>>> vim /etc/exports
/data		192.168.250.0/24(rw,sync,all_squash)
# 在NFS服务器上建立用于NFS文件共享的目录,并设置对应权限
nfs01]>>> mkdir /data
nfs01]>>> chown -R nfsnobody.nfsnobody /data
nfs01]>>> systemctl start nfs-server  # 启动nfs
nfs01]>>> systemctl enable nfs-server

nfs01]>>> cat /var/lib/nfs/etab  # 当nfs启动后,这里面记录这共享信息


# 客户端操作
head]>>> yum install nfs-utils -y
head]>>> systemctl start rpcbind
head]>>> systemctl enable rpcbind
# 检测是否有共享的内容
head]>>> showmount -e 192.168.250.139
Export list for 192.168.250.139:
/data 192.168.250.0/24
# 挂载
head]>>> mount -t nfs 192.168.250.139:/data /opt
# 检测挂载是否成功
head]>>> df -h

# 客户端将nfs挂载信息写入/etc/fstab文件中,实现永久挂载
head]>>> vi /etc/fstab
192.168.250.139:/data			/opt		nfs01			defaults		0	0
>>> mount -a  # 验证fstab开机启动是否填写错误

# nfs挂载说明
客户端当前的目录仅仅只是nfs服务端共享目录的一个入口文件,当在web删除文件的时候,其实是删除的nfs服务端的目录

# 卸载
>>> umount /opt

nfs配置详解

>>> man exports
nfs共享参数				参数作用
rw							读写权限        # 常用
ro							只读权限
root_squash			当nfs客户端以root管理员访问时,映射为nfs服务器的匿名用户(不常用)
no_root_squash	当nfs客户端以root管理员访问时,映射为nfs服务器的root管理员(不常用)
all_squash			无论nfs客户端用什么账号访问,均映射为nfs服务器的匿名用户  # 常用
no_all_squash		无论nfs客户端使用什么账户访问,都不进行压缩
sync						同时将数据写入到内存与硬盘中,保证不丢失数据  #常用
async						优先将数据保存到内存,然后再写入硬盘,这样效率更高,但可能会丢失数据
anonuid				  配置all_squash使用,指定NFS的用户UID,必须存在系统  #常用
anongid				  配置all_squash使用,指定NFS的用户UID,必须存在系统  # 常用

验证all_squash,anonuid,anongid

# 如果只用all_squash,不用anonuid,anongid,那么就会自动生成uid为65534,用户名为nfsnobody

# 服务端
nfs01]>>> vi /etc/exports
/data 192.168.250.0/24(rw,sync,all_squash,anonuid=666,anongid=666)
nfs01]>>> groupadd -g 666 www
nfs01]>>> useradd -u 666 -g 666 www
nfs01]>>> chown -R www.www /data/
nfs01]>>> systemctl restart nfs-server  # 重启nfs

# 客户器重新挂载验证
head]>>> touch /opt/file   
head]>>> ll  # 可以看到创建的文件的属主用户为666,客户端如果觉得666不好看,建议在客户端上创建同名的用户以及uid
head]>>> groupadd -g 666 www
head>>> useradd -u 666 -g 666 www

实时同步

1.什么是实时同步,只要当前目录发生变化则会触发一个事件,事件触发后将变化的目录同步至远程服务器
2.为什么要实时同步,保证数据的连续性,减少人力维护成本,解决nfs单点故障
3.实时同步实现原理,实时同步需要借助Inotify通知接口,用来监控目录的变化,如果监控的目录发生变更,则触发动作,这个动作可以是进行一次同步操作,或其它操作
4.实时同步工具选择,有sersync(),inotify+rsync,通常我们会选择sersync,因为sersync是国人基于rsync+inotify-tools开发的工具,不仅保留了优点同时还强化了实时监控,文件过滤,简化配置等功能,帮助用户提高运行效率,节省时间和网络资源。

实时同步案例

# 实现head上传视频文件,实则是写入nfs01至存储,当nfs存在新的数据则会实时的复制到备份服务器
head				192.168.250.137			httpd+php
nfs01				192.168.250.139			nfsServer、rsync+inotify+sersync
backup			192.168.250.138			rsync-server

web上传视频至nfs存储

# nfs存储服务 192.168.250.139
# 安装
nfs01]>>> yum intsll nfs-utils -y
# 配置
nfs01]>>> vim /etc/exports
/data 192.168.250.0/24(rw,sync,all_squash,anonuid=666,anongid=666)
nfs01]>>> groupadd -g666 www
nfs01]>>> useradd -u 666 -g 666 www
nfs01]>>> mkdir /data
nfs01]>>> chown -R www.www /data/
# 启动
nfs01]>>> systemctl start nfs-server
nfs01]>>> systemctl enable nfs-server


# head服务器操作:192.168.250.137
# 安装
head]>>> yum install httpd php -y
# 挂载
head]>>> mount -t nfs 192.168.250.139:/data	/var/www/html
head]>>> cd /var/www/html/
head]>>> # 将php程序放入到/var/www/html目录下,
# 修改文件大小 php.ini文件
>>> vi /etc/php.ini
upload_max_filesize = 200M 
post_max_size = 200M
# 权限修改
>>> sed -i '/^User/c User www' /etc/httpd/conf/httpd.conf
>>> sed -i '/^Group/c Group www' /etc/httpd/conf/httpd.conf
# 启动
head]>>> systemctl start httpd

head和nfs01的数据都备份在备份服务器的/backup

# 备份服务器192.168.250.138
# 安装
backup]>>> yum install rsync -y
# 配置
backup]>>> vim /etc/rsyncd.conf
uid = www    # 修改为www,目的是为了以后nfs服务器故障的时候,head中的web数据可以直接备份到backup服务器
gid = www
port = 873
fake super = yes
use chroot = no
max connections = 200
timeout = 600
ignore errors
read only = false
list = false
auth users = rsync_backup
secrets file = /etc/rsync.passwd
log file = /var/log/rsyncd.log

[backup]  # 备份数据存放目录
path = /backup

[data]  # web数据存放目录
path = /data

# 创建用户
backup]>>> groupadd -g 666 www
backup]>>> useradd -u666 -g666 www
# 准备虚拟用户和密码用于连接
backup]>>> echo "rsync_backup:1" > /etc/rsync.passwd
backup]>>> chmod 600 /etc/rsync.passwd

# 创建目录及授权
backup]>>> mkdir /backup
backup]>>> mkdir /data
backup]>>> chown -R www.www /backup
backup]>>> chown -R www.www /data

# 启动
backup]>>> systemctl restart rsyncd

# 客户端执行脚本,测试rsync的备份是否ok(客户端的数都写入到/backup目录中)
head]>>> sh /scripts/client_push_data_server.sh   # 脚本参考之前rsync
# 脚本内容
#!/usr/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
Path=/backup
Host=$(hostname)
Addr=$(ifconfig ens33 | awk '/inet / { print $2 }')
Date=$(date +%F)
Dest=${Path}/${Host}_${Addr}_${Date}
# 1.创建好对应的备份目录
[ -d $Dest ] ||  mkdir -p $Dest
# 2.打包要备份的数据
cd / && \
[ -f $Dest/sys.tar.gz ] || tar czf $Dest/sys.tar.gz etc/passwd etc/fstab etc/hosts && \
[ -f $Dest/other.tar.gz ] ||  tar czf $Dest/other.tar.gz var/spool/cron scripts
# 3.添加标记
[ -f $Dest/flag_${Date} ] || md5sum $Dest/*.tar.gz > $Dest/flag_${Date}
# 4.推送数据至远程仓库
export RSYNC_PASSWORD=1
rsync -avz $Path/  rsync_backup@192.168.250.138::backup
# 5.保留最近7天备份数据
find $Path/ -type d -mtime +7 | xargs rm -rf

nfs01]>>> sh /scripts/client_push_data_server.sh  # 脚本参考之前rsync
# 脚本内容
#!/usr/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
Path=/backup
Host=$(hostname)
Addr=$(ifconfig ens33 | awk '/inet / { print $2 }')
Date=$(date +%F)
Dest=${Path}/${Host}_${Addr}_${Date}
# 1.创建好对应的备份目录
[ -d $Dest ] ||  mkdir -p $Dest
# 2.打包要备份的数据
cd / && \
[ -f $Dest/sys.tar.gz ] || tar czf $Dest/sys.tar.gz etc/passwd etc/fstab etc/hosts && \
[ -f $Dest/other.tar.gz ] ||  tar czf $Dest/other.tar.gz var/spool/cron scripts
# 3.添加标记
[ -f $Dest/flag_${Date} ] || md5sum $Dest/*.tar.gz > $Dest/flag_${Date}
# 4.推送数据至远程仓库
export RSYNC_PASSWORD=1
rsync -avz $Path/  rsync_backup@192.168.250.138::backup
# 5.保留最近7天备份数据
find $Path/ -type d -mtime +7 | xargs rm -rf


backup]>>> ll /backup/

如何将nfs的数据实时的同步到备份服务器的/data目录

# 监控nfs01服务器上面的/data目录,如果发生变化则触发动作,动作可以是执行一次同步
# 安装 https://github.com/wsgzao/sersync  下载tar包
nfs01]>>> yum install inotify-tools -y  # 安装监控工具
nfs01]>>> tar -xzf sersync2.5.4_64bit_binary_stable_final.tar.gz
nfs01]>>> mv GNU-Linux-x86/ /usr/local/sersync
# 配置
nfs01]>>> vim /usr/local/sersync/confxml.xml
<filter start="false"> # 排除不想同步的文件
</filter>
<inotify>	 # 监控的事件类型
  <fileSystem xfs="true"/>
  <createFile start="true"/>
  <attrib start="true"/>
  <modify start="true"/>
</inotify>  
<sersync>
  <localpath watch="/data">  # 监控nfs01的/data目录
              <remote ip="192.168.250.138" name="data"/>  # 只要上面nfs01的/data发生变化就推送到192.168.250.138backup的data目录
<rsync># 使用rsync推送的选项
  <commonParams params="-az"/>  
  <auth start="true" users="rsync_backup" passwordfile="/etc/rsync.pass"/>  # rsync的nfs01客户端的虚拟用户和密码
</rsync>
<timeout start="true" time="100"/>

# 创建密码文件
nfs01]>>> echo "1" > /etc/rsync.pass
nfs01]>>> chmod 600 /etc/rsync.pass

# 启动
nfs01]>>> /usr/local/sersync/sersync2 -dro /usr/local/sersync/confxml.xml
nfs01]>>> cd /data && rsync -az -R --delete ./  --timeout=100 rsync_backup@192.168.250.138::data --password-file=/etc/rsync.pass  # 上面启动后,手动执行下命令检测rsync是否错误

# 测试
head页面上传一个文件,首先会同步到nfs01上面,然后同时备份到backup服务上

如果平滑的迁移nfs数据到backup服务器。并且让后续的上传都是上传至backup(不能出现业务中断)

# 1.backup服务器上需要运行和nfs服务器上一样的业务环节
backup]>>> yum install -y nfs-utils
backup]>>> rsync -avz 192.168.250.139:/etc/exports /etc/exports  # 将nfs的exports文件拷贝到backup服务器上
backup]>>> groupadd -g 666 www
backup]>>> useradd -g666 -u666 www
backup]>>> systemctl restart nfs-server

# 2.先实现实时的同步

# 3.在head上实现切换,卸载nfs的/data目录,重新挂载backup服务的/data目录
head]>>> umount -lf /var/www/html/ && mount -t nfs 192.168.250.138:/data /var/www/html/
head]>>> umount /opt  # 将原来练习挂载的/opt卸载掉

# 4.测试
head页面上传一个文件,查看backup服务器上/data/下面是否有文件,如果有,说明切换成功了,同时也需要查看nfs01服务器上/data/目录,如果没有,也说明切换成功

总结

# sersync对数百万张图片数据做到了实时同步,新增的数据能够立马同步到另一台,最后上百G的图片数据实现了在线迁移
# 实时同步
1.为什么要使用实时同步?
	- 解决nfs单点
	- 大量的静态资源迁移(本地迁移云端)
2.实时同步能解决什么问题?
	- 平滑的迁移
	- 备份:减少人为的干预
3.实时同步工具选择?
	- rsync+inotify-tools  # 少量文件同步,麻烦,同步大文件太慢,遍历扫描,非常影响效率
	- sersync  # 配置简单,多线程同步,同步快,适合大量的小文件或图片
	- lsryncd
4.流程
用户上传文件-->web浏览器head服务器-->写入-->nfs存储-->inotify(监控)-->action(动作)-->rsync-->backup服务器
用户上传文件-->web浏览器head服务器-->写入-->nfs存储(本地)-->实时同步到--> 存储(云端) web浏览器(head服务器)-->卸载存储(本地)--> 重新挂载存储(云端)
上一篇:spring-cloud-sleuth+zipkin追踪服务实现(二)


下一篇:Python、JavaScript和Rust的Web性能比较 - Alex