在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系统中,几乎所有的配置文件都是这个格式
编辑配置文件,并写入以下配置信息, 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
# blog:Warning:
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
# blog:Warning:
# 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