在linux系统中,需要注意空格使用,有着整体性原则,并且注意大小写问题
Rsync数据同步工具
开源、快速、多功能、可实现全量和增量的本地或远程
具有本地和远程两台主机之间数据快速同步镜像、远程备份的功能类似ssh带的scp命令,还可以实现删除文件和目录的功能,同步内容和属性,还可以同步一个文件里有变化的内容部分
全量: 全部备份
增量:差异化备份,效率更高
rsync –version # 查看版本信息
Rsync的特性
- 支持拷贝特殊文件如链接文件、设备等
- 可以有排除指定文件或目录同步功能,相当于tar的排除功能
- 可以做到保持原文件或,目录的权限、时间、软硬链接、主、组等所有属性均不变
- 可以实现增量同步,即只同步发送变化的数据,因此数据传输效率很高
- 可以通过socket(进程方式)传输文件和数据(服务端和客户端),远程数据同步
- 支持匿名或认证(无需系统用户)的进程模式传输,可实现方便安全的数据备份及镜像
Rsync企业工作场景
两台服务器之间同步数据
方案1:cron + rsync 定时备份针对内部人员,配置信息,发布代码
方案2:sersync+rsync 或 inotify+rsync 实时备份,用户所有数据
rsync工作方式
- 本地模式, 相当于cp
cp -a /etc/hosts /tmp/ # 把hosts文件拷贝到 /tmp目录下 rsync -vzrtopg /etc/hosts /mnt/ # 等价于上一个 rsync -avz --delete /tmp/ /mnt/ # 删除两个文件中单个存在的文件,源和目标保持一致,这个慎用,除非必须要求两个目录文件文件保存一致
--delete 生产中不用和慎用删除相关的操作,一旦删除数据不可挽回
Rsync 作为客户端详细选项
进行备份时候,有末尾带斜线和不带斜线区别,带斜线只备份该目录下所有内容,不带斜线包括目录本身和目录下所有内容
如: /data/mysql/ /data/mysql ,前者只备份mysql目录下内容, 后者备份 mysql 目录和目录下所有内容
-v 详细输出,传输时的进度等信息
-z 传输是进行压缩以提高传输效率
-a 归档模式,表示以递归方式传输文件,保持所有文件属性,把下面的选项包了
-r 对子目录以递归模式,即目录下的所有目录都是同样传输
-t 保持文件时间信息
-o 保持文件主信息
-p 保持文件权限
-g 保持文件组信息
-P 显示同步的过程与传输时的进度等信息
-D 保持设备文件信息
-l 保留软链接
一般来讲, -avz 就可以了
-e 使用信息协议,指定替代rsh和shell程序上
--exclude=PATTERN 指定排除必须的文件模式(和tar参数一样)
--exclude-from=file(文件名所在的目录文件)(和tar参数一样)
--bwlimit= 限速,单位为k
--delete 让目标目录SRC和源目录数据DST一致
备份需要考虑带宽进行限速,时间选择晚上用户访问少,rsync scp ftp 都有限速功能
遇到的工作故障:
1. 某DBA做数据同步,导致用户无法访问网站的问题。
问题原因:
白天时候进行数据库同步备份,并没有对备份进行带宽限速,造成备份时候,占满带宽,用户打不开网页
解决方法:
选择夜间用户访问量少的时候进行备份,以及备份时候进行备份带宽限制,让其不能占满服务带宽
dd if=/dev/zero of=test1 bs=1M count=128 # 当前目录下创建 128M大小的 test1文件, 模拟测试数据 rsync -avz --bwlimit=10 /backup/ rsync_backup@172.16.1.41::backup/ --password-file=/etc/rsync.password # --bwlimit= 限速,单位是k/s
第二个模式: 使用远端的shell
rsync -avz /etc/hosts -e 'ssh -p 22' root@10.0.0.31:/mnt # 把 /etc/hosts 文件通过 ssh 服务,推送到远端服务器 10.0.0.31 以root角色接收,存放在/mnt下, 用户@ip:目录,其中两个特殊符号@ 和 : , -p指定端口
第三个模式,以守护进程的方式传输数据(重点),采用这种模式
rsync 端口 873
守护进程: 持续运行的进程
demon 搭在备份服务器上,其他机器把备份文件推送到备份服务器,这个是大多数企业采用的方案
如何搭建demon,服务端?
1. 默认配置文件不存在,可以创建一个配置文件
touch /etc/rsyncd.conf # 在linux系统中,几乎所有的配置文件都是这个格式
2. 编辑配置文件,并写入以下配置信息, vim /etc/rsyncd.conf
##rysncd.conf start## uid = rsync # 主,在linux中进程和文件必须属于主和组,远端连接过来时候使用该主访问文件 gid = rsync # 组 use chroot = no # 安全机制 max connections = 200 # 最大连接数 timeout = 300 # 超时时间,断掉无意义连接 pid file = /var/run/rsyncd.pid # 进程文件 lock file = /var/run/rsync.lock # 锁文件 log file = /var/log/rsyncd.log # 日志文件 [backup] # 配置模块名 path = /backup # 服务器提供的访问目录 ignore errors # 忽略错误 read only = false # 可写 list = false # 不可列表 host allow = 172.16.1.0/24 # 允许远端连接的主机网段 host deny = 0.0.0.0/32 # 拒绝主机 auth users = rsync_backup # 独立于系统的虚拟用户,用于验证 secrets file = /etc/rsync.password # 虚拟用户名密码 #rysnc_config_________________end
3. 添加用户:
useradd rsync -s /sbin/nologin -M # 不允许登录并不需要家目录
4. 启动rsync demon
rsync --daemon
5. 查看是否有这个进程:
ps -ef|grep rsync|grep -v grep # 进程是用root存在
6. 创建 /backup 目录,更改用户和组为配置文件中设定的主和组,不然远端推送不过来
# low方法:把 这个目录权限位 777,太危险,把配置文件中uid和gid都改为root mkdir /backup # 创建服务器提供的访问目录 chown rsync.rsync /backup/ # 用户远端推送使用 rsync身份 ll -d /backup/ # 检查一下
7. 创建 /etc/rsync.password 文件,写入: resync_backup:beimenchuixue
chmod 600 /etc/rsync.password # 存放密码文件,缩小权限 # 这个文件是客户端连接过来时候带来的密码beimenchuixue,用户就可以不需要root密码实现远程推送文件,验证用户和密码是以冒号作为分隔符,密码是明文
8. 检查端口:
lsof -i :873 # 查看端口是否开启 或 netstat -lntup|grep 873
9. 让其开机自启动
echo '/usr/bin/rsync --daemon' >> /etc/rc.local cat /etc/rc.local # 检查
客户端:
1. 检查是否有rsync服务
rpm -qa *rsync* rsync --version
2. 只需要生成密码文件即可
echo 'beimenchuixue' >> /etc/rsync.password # 设置连接备份服务端密码 cat /etc/rsync.password # 检查 chmod 600 /etc/rsync.password # 最小化权限 ll /etc/rsync.password # 检查
3. 创建 /backup目录,对备份文件,首先要打包到这个目录下,统一推送过去
mkdir -p /backup
测试:
客户端
touch stu{01..100} # 在/backup下创建100个文件
推送1 :
rsync -avz /backup/ rsync_backup@172.16.1.41::backup/ --password-file=/etc/rsync.password
推送2:
rsync -avz /backup/ rsync://rsync_backup@172.16.1.41/backup/ --password-file=/etc/rsync.password
backup/ 模块名,如果推到某个子目录,直接在模块后面跟子目录,依赖于客户端配置
在linux系统中,配置文件会加载到内存,修改配置文件需要重启服务
pkill rsync # 结束进程 lsof -i :873 # 检查进程是否结束 rsync --daemon # 启动 lsof -i :873 # 检查服务是否启动
问题排错:
1. @ERROR: chdir failed
服务器端对应模块下没有备份目录
解决方法:
mkdir /backup # 创建这个模块对应的目录
2. rsync: mkstemp ".stu100.JWpxhq" (in backup) failed: Permission denied (13)
权限不够
解决方法:
chown rsync.rsync /backup/ # 更改为 rsync需要的主和组 ll -d /backup/ # 检查
3. @ERROR: invalid uid rsync
备份服务器rsync这个用户不存在
解决方法:
useradd rsync -s /sbin/nologin -M # 添加这个用户,不需要家目录和不允许登录 id rsync # 检查
4. @ERROR: auth failed on module backup
模块验证失败
解决方法:
客户端和服务器端:
检查客户端 /etc/rsync.password ,注意文件中是有多余空格和敲错的字符
检查客户端和服务端的 /etc/rsync.password 是否授权为600
cat -A /etc/rsync.password # 查看所有字符,包括空格结尾符号
5. rsync: failed to connect to 172.16.1.22: Connection refused (111)
解决方法: 服务端 rsync --daemon 没开
ps -ef | grep rsync # 检查 rsync --daemon # 启动
如何对应多个模块?
更改 /etc/rsyncd.conf配置文件,把共有的部分提取放到全局
uid = rsync gid = rsync use chroot = no max connections = 200 timeout = 300 pid file = /var/run/rsyncd.pid lock file = /var/run/rsync.lock log file = /var/log/rsyncd.log path = /backup ignore errors read only = false list = false host allow = 172.16.1.0/24 #host deny = 0.0.0.0/32 auth users = rsync_backup secrets file = /etc/rsync.password [backup] path = /backup [beimen] path = /beimen # 每个单独的模块,单独有一个path,对应不同的推送过来的数据
修改配置的时候,需要时刻备份,出了问题可以快速复原
cp /etc/rsyncd.conf{,.$(date +%F)_v1} # 专业备份格式,加上备份时间和更改次数版本
假如想要排除一些文件如何做?
--exclude=文件名 # 排除单个文件
--exclude={filename1, filename2,...} 排除多个文件
--exclude={a..z} 排除连续的
--exclude=paichu.log 按文件排除
无差异同步
--delete
服务器端放了文件,推送的时候,以客户端推送目录为依据,客户端有啥服务端就有啥,多余的删除
拉取,以客户端/backuo为依据
与这个无差异同步发生的血案:
视频网站,推到服务器上上线发布,本地/backup只有当天发布的内容,服务器上却有以前的所有文件,执行含 --delete 的rsync推送命令
结果: 服务器端删除以前的所有,只有当天的了
相当于 rm -rf
提示: 非常危险,慎用
rsync三种工作模式:
1. 本地模式,相当于cp
2. 通道模式 -e指定用什么协议传输
rsync -avz /etc/hosts -e 'ssh -p 22' root@10.0.0.31:/mnt,配合ssh密钥进行免密码传输
3. daemon模式
提示:内网不需要加密,加密性能能有损失
跨机房,使用vpn(pptp, openvpn, ipsec)
rsync
优点:
- 增量备份,支持socket(deamon),集中备份(支持推拉,以客户端为参照物)
- 可以利用ssh, vpn服务等加密传输远程数据
缺点:
- 大量小文件同步时候,对比时间长,有时候rsync进程会停止
- 同步大文件,比如10G会出现中断问题,未同步完成前,是隐藏文件,通过续传等参数实现传输
- 一次性远程拷贝可以用scp
如何检查服务端防火墙是否阻挡?
telnet ip地址 端口
rsypnc服务配置过程总结:
服务器端:
1. 检查rsync安装包
rmp -qa rsync
2. 添加rsync服务用户,管理本地目录的
usradd rsync -s /sbin/nologin -M
3. 生成rsyncd.conf配置文件
vim rsyncd.conf 放入已经配置好的配置文本
4. 根据 rsyncd.conf 的auth users 配置账号,用于远程连接,并根据 secrets file 参数生成密码文件
5. 为密码文件配置权限
chmod 600 /etc/rsync.password ll /etc/rsync.password
6. 创建备份目录,并授权rsync服务管理
mkdir -p /backup chown -R rsync.rsync /backup ll /backup
7. 启动 rsync服务的daemon模式,接收其他服务器推送过来的数据
rsync --daemaon lsof -i :873
8. 加入开机自启动
echo `/usr/bin/rsync --daemon` >> /etc/rc.local tail -1 /etc/rc.local
客户端:
1. 生成服务器端需要的密码文件
echo `beimenchuixue` > /etc/rysnc.password cat /etc/password
2. 为密码文件配置权限
chmod 600 /etc/rsync.password ll /etc/rsync.password
测试:
往服务器推送文件,看能不能成功
rsync -avz /backup/ rsync_backup@172.16.1.41::backup --password-file=/etc/rsync.password
出错误排错方式:
1. 看输出结果
2. 看日志 /var/log/rsync.log
3. 熟悉部署流程
总结过程:
服务端:
1. 添加对备份文件操作的用户,为了统一,客户端和服务端统一名字
useradd rsync -s /sbin/nologin -M id rsync
2. 创建备份目录 /backup
mkdir /backup
3. 把1步骤建立的用户,授权 /backup目录
chown -R rsync.rsync /backup/
4. 写配置文件, /etc/rsyncd.conf
vim /etc/rsyncd.password uid = rsync gid = rsync use chroot = no max connections = 200 timeout = 300 pid file = /var/run/rsyncd.pid lock file = /var/run/rsync.lock log file = /var/log/rsyncd.log path = /backup ignore errors read only = false list = false host allow = 172.16.1.0/24 #host deny = 0.0.0.0/32 auth users = rsync_backup secrets file = /etc/rsync.password [backup] path = /backup
5. 写密码文件 /etc/rsync.password,rsync_backup这个只是用于客户端验证的用户,让其他人不可见
echo 'rsync_backup:beimenchuixue' > /etc/rsync.password
cat /etc/rsync.password
chmod 600 /etc/rsync.password
6. 启动daemon,并将这条启动写入/etc/rc.local
rsync --daemon echo 'rsync --daemon' >> /etc/rc.local tail -1 /etc/rc.local
客户端:
1. 编写 /etc/rsync.password 文件,写入密码,让其他人不可见
echo 'beimenchuixue' > /etc/rsync.password
chmod 600 /etc/rsync.password
2. -avz 备份上传,--password-file指定密码文件,本地文件和服务器的顺序决定是推还是拉
mkdir /backup echo 'echo hello' > /backup/hello.sh # 创建测试文件 rsync -avz /backup/ rsync_backup@172.16.1.22::backup/ --password-file=/etc/rsync.password # v 具体脚本可以省略,表示显示信息
3. 去backup服务器查看是否备份
过程程序化:
1. 一键配置rsync客户端
#!/bin/sh # author: beimenchuixue # email: 42283556@qq.com # blog:Warning: http://www.cnblogs.com/2bjiujiu/ rsyncConf="/etc/rsyncd.conf" rsyncPid="/var/run/rsyncd.pid" rsyncPath="/backup" ServerPwdFile="/etc/rsync.password" rsyncUser="rsync" loginUser="beimenchuixue" loginPwd="123456" . /etc/init.d/functions function sureOK { [ $? -eq 0 ] && { action "$2 is" /bin/true } || { action "$2 is" /bin/false exit $? } } function hasInstallRsync { rsync --version &> /dev/null sureOK $? "hasInstallRsync" } # hasInstallRsync function rsyncConf { [ -f $rsyncConf ] && { cat /dev/null > $rsyncConf sureOK $? "init rsyncConf" } cat >>$rsyncConf<<EOF uid = $rsyncUser gid = $rsyncUser use chroot = no max connections = 200 timeout = 300 pid file = $rsyncPid lock file = /var/run/rsync.lock log file = /var/log/rsyncd.log ignore errors read only = false list = false # host allow = 172.16.1.0/24 # host deny=0.0.0.0/32 auth users = $loginUser secrets file = $ServerPwdFile [backup] path = $rsyncPath EOF sureOK $? "rsyncConf" } # rsyncConf function addRsyncUser { id $rsyncUser &> /dev/null [ $? -eq 0 ] || { useradd $rsyncUser -s /sbin/nologin -M } sureOK $? "addRsyncUser" } # addRsyncUser function initRsyncPath { [ -d $rsyncPath ] || { mkdir -p $rsyncPath sureOK $? "create $rsyncPath" } chown -R ${rsyncUser}.${rsyncUser} $rsyncPath sureOK $? "initRsyncPath" } # initRsyncPath function initServerRsyncPwdFile { [ -f $ServerPwdFile ] && { cat /dev/null > $ServerPwdFile sureOK $? "clear ServerRsyncPwdFile" } echo "$loginUser:$loginPwd" > $ServerPwdFile sureOK $? "write rsyncPwd" chmod 000 $ServerPwdFile } # initServerRsyncPwdFile function main_BeiMenChuiXue { hasInstallRsync rsyncConf addRsyncUser initRsyncPath initServerRsyncPwdFile } main_BeiMenChuiXue
2. rsync启动脚本
#!/bin/sh # author: beimenchuixue # email: 42283556@qq.com # blog:Warning: http://www.cnblogs.com/2bjiujiu/ # chkconfig: 2345 98 25 rsyncPid="/var/run/rsyncd.pid" . /etc/init.d/functions function sureOK { [ $1 -eq 0 ] && { action "$2 is" /bin/true } || { action "$2 is" /bin/false exit $1 } } [ ${#} -eq 1 ] || { echo "$0 (start|stop|restart)" exit 1 } function startRsyncDaemon { [ -f $rsyncPid ] && { echo "rsync is running" sureOK 1 "start rsync" } rsync --daemon sureOK $? "start rsync" } # RsyncDaemon function stopRsyncDaemon { if [ ! -f $rsyncPid ]; then echo "rsync is stoping" sureOK 1 "stop rsync" else kill $(cat $rsyncPid) sleep 1 if [ -f $rsyncPid ]; then kill -9 $(cat $rsyncPid) sureOK $? "stop rsync" else sureOK 0 "stop rsync" fi fi } # stopRsyncDaemon function restartRsyncDaemon { stopRsyncDaemon startRsyncDaemon } case $1 in start) startRsyncDaemon ;; stop) stopRsyncDaemon ;; restart) restartRsyncDaemon ;; *) echo "$0 (start|stop|restart)" exit 3 esac