Github:axkibe/lsyncd
官方文档:Lsyncd – Live Syncing (Mirror) Daemon
首先,你需要知道rsync的基本用法,以下的rsync命令就可以把文件从本地的“/data/wwwroot”目录推送到远程的“remote@192.168.1.6::wwwroot/”目录中,运行在“rsync同步模式”的lsyncd正是通过组装类似这样的命令来同步文件的:
rsync -avz --partial --delete /data/wwwroot remote@192.168.1.6::wwwroot/ --password-file=/etc/rsyncd.password
有人可能会疑惑,既然rsync本身就可以同步,那要lsyncd干嘛?有两个原因:
实时同步。
减少rsync扫描文件带来的延时和性能损耗。
rsync无法知道“什么时候同步”,因为rsync只有执行同步命令的时候,才会去扫描文件判断哪些文件被修改了,只能建立一个定时任务,每隔一定的时间(比如5分钟,10分钟等等)去执行一次同步,这样虽然能同步,但却“不实时”。
lsyncd就可以监听文件的修改,换句话说,某个文件修改了,lsyncd会得到通知(原理是使用linux系统的inotify/fsevents功能),得到通知之后,再去调用rsync把修改的文件进行同步(即组装一句rsync同步语句并执行),达到“实时同步”的效果。
lsyncd调用rsync同步命令的时候,会用rsync的–include-from=FILE之类的选项来指定要同步哪些文件,这样可以达到“减少rsync扫描文件带来的延时和性能损耗”。
为什么这么说呢?因为如果让rsync自己去查询哪些文件改变了,需要消耗较多的时间和服务器资源,试想一下,在100万个文件中,有一个文件添加了一个英文的句号.,如果没有lsyncd告诉rsync改变的是这个文件,那rsync就要去扫描100万个文件来找出这个仅仅多了一个.的文件,虽然rsync的查找效率很高,但这个查找是非常没有必要的,这就是为什么lsyncd能“减少rsync扫描文件带来的延时和性能损耗”。
明白了rsync同步模式,就不难明白rsyncssh模式,因为rsync本身就是有ssh模式的,lsyncd同样是负责监听哪些文件变化了,然后组装rsync同步命令进行同步。
rsync的ssh模式,主要的好处是用于文件移动的时候。
├── dir1
│ ├── aa.txt
│ ├── bb.txt
│ └── cc.txt
└── dir2
└── dd.txt
├── dir1
│ └── aa.txt
└── dir2
├── bb.txt
├── cc.txt
└── dd.txt
这个模式用于本地的两个目录之间同步,不用于远程服务器同步。lsyncd同样是监听文件变化事件,然后把变化的文件从源目录同步到目标目录,同步的命令,就是linux系统本身的命令,比如cp、rm、mv,增加了文件用cp拷过去,删除了文件,那边也用rm删除,移动了文件,那边也用mv移动。
假设有A和B两台机,A同步到B,则:
A中的lsyncd监听到文件变化后,调用A中的rsync向B推送文件,B因为运行有一个rsyncd服务,所以可以接收这个推送,从而完成文件的同步。另外还可以有C、D、E、F、……,它们都与B相同,只要运行rsyncd服务即可,A上可配置一次性推送向多台机器。
安装、配置Rsync服务端,请参考:安装、配置Rsync服务
rsync的默认端口是873,如果你是CentOS7的firewalld防火墙,可以用以下方法允许873端口:
firewall-cmd --zone=public --add-port=873/tcp --permanent
firewall-cmd --reload
如果你是本地做实验觉得防火墙麻烦,也可关闭防火墙:
systemctl stop firewalld
##RPM包安装
yum install http://rpmfind.net/linux/epel/7/x86_64/Packages/l/lsyncd-2.2.2-1.el7.x86_64.rpm
##yum直接安装
yum -y install epel-release
yum -y install rsync lsyncd
手动启动
如何启动的官方文档:官方文档
#启动方式是:
lsyncd -log Ex /etc/lsyncd.conf
#查看log文件,你会看到已经同步了很多文件:
tail -100f /var/log/lsyncd/lsyncd.log
systemctl 启动
#启动:
systemctl start lsyncd
#停止:
systemctl stop lsyncd
#重启:
systemctl restart lsyncd
#查看启动状态:
systemctl status lsyncd
#设置开机自启动:
systemctl enable lsyncd
查看是否启动成功:
ps aux | grep lsyncd
#如何进程正常运行,可以看到:
root 5238 7.7 0.6 13348 3340 ? Ss 21:46 0:15 lsyncd /etc/lsyncd.conf
配置文件:/etc/lsyncd.conf,使用lua语言写的,所以注释要用lua语言的注释符号,即两个横杠–。
/etc/lsyncd.conf也可以写成/etc/lsyncd.lua,它本身就是用lua(一种脚本语言)写配置的。
配置文件主要有三部分:
以下是两个官方的配置文档:
settings {
-- 指定日志文件位置
logfile = "/var/log/lsyncd/lsyncd.log",
-- 指定状态文件位置
statusFile = "/var/log/lsyncd/lsyncd.status",
-- 是否以后台的方式运行,注意它是nodaemon,所以是双重否定,如果填false,意思就是“不要不后台运行”(即后台运行),非后台运行一般用于调试,把rsync的verbose也设置为true,这样会把同步的细节输出到控制台,方便调试
nodaemon = false,
-- 系统inotify指定监听的变化,什么事件才同步。CloseWrite表示文件关闭的时候同步(创建文件,修改文件后保存都会触发CloseWrite事件),可以是"Modify"、"CloseWrite" (默认) 或"CloseWrite or Modify"。
inotifyMode = "CloseWrite",
-- 最大同步进程数(default.rsyncssh模式,则必须设置为1,这就是rsyncssh模式的缺点了,如果是default.rsync模式则可以设置大于1,这样会有多个同步进程,速度更快)
maxProcesses = 8,
-- maxProcesses = 1,
-- 配合下面的delay选项使用,delay单位是秒,当delay时间到了,不管maxDelays设置多少,都会同步,同样,当maxDelays达到了设定值,不管是否到delay时间,都会同步,即两个选项有一个满足即会触发同步,为了实时同>步,我们一般设置为1,表示即使只有一个文件改变也同步
maxDelays = 1,
}
---- 同步配置default.rsync模式(比如配置从哪同步到哪,忽略哪些文件,多久同步一次等),可以有多个sync模块,每个模块用于设置一台目标机器
sync {
-- 有default.rsync/default.direct/default.rsyncssh三种模式,我们默认都用default.rsync即可。
default.rsync,
-- 同步源目录(本机某个目录)
source = "/data/wwwroot",
-- 同步目标地址,不同同步模式有不同写法,由于绝大多数情况都采用rsync同步,所以这里写的是rsync的同步地址
target = "remote@192.168.1.6::wwwroot",
-- 默认true,允许删除目录服务器中的某些文件(即删除“那些在源服务器中不存在的文件”),可选值有: true/false/startup/running,startup就是只在启动lsyncd服务的时候判断目标服务器中有哪些文件在源服务器中没有,然后把这些文件删除,但启动之后如果目标服务器又新增了文件,这些文件即使在源服务器不存在,也不会被删除;而running与startup正好相反,是在启动的时候不会删除,启动之后会删除,true=running+startup,false相当于running和startup都不做。
-- delete = true,
-- 哪些文件不同步(可用正则))
exclude = {
'.**',
'.git/**',
'*.bak',
'*.tmp',
'runtime/**',
'cache/**'
},
-- 与上边的maxDelays配合,maxDelays是累计事件数(单位:个),delay是时间(单位:秒),这两个只要有一个符合条件就会同步一次,但为了确保实时同步,maxDelays我们一般设置为1,也就是只要有一个文件变化事件,就会同步一次,而delay是比较大的,默认是15。当然,假如我们把maxDelays设置为100,那可能15秒到了也没有达到100个文件变化,但由于到达时间了,它也会同步。
delay = 15,
-- 当init = false时只同步进程启动以后发生改动事件的文件,原有的目录即使有差异也不会同步,如果为true,则启动后如果源目录与目标目录的文件有差异都会同步,默认为true。
-- init = false,
-- rsync的配置(这是default.rsync模式,如果是default.rsyncssh模式,该模块的配置会有所不同)
rsync = {
-- rsync可执行文件的绝对路径
binary = "/usr/bin/rsync",
-- 密码文件路径(default.rsyncssh模式不需要该项)
password_file = "/etc/rsyncd.password",
-- 打包后再同步(注意,打包不等于压缩,打包即可以压缩也可以不压缩)
archive = true,
-- 压缩后再同步
compress = false,
-- 输出同步信息(由于是后台执行,所以没必要输出,如果非后台执行可以设置为true,非后台执行主要用于调试)
verbose = false,
-- 由于rsync有非常多的选项(请自己rsync --help查看),部分非主要选项可以用_extra的方式指定,双引号引住,逗号分隔(bwlimit中的bw是bandwith,即带宽,整个意思是带宽限制,omit-link-times忽略符号链接的修改时间)
_extra = {"--bwlimit=200", "--omit-link-times"}
}
}
解释几个选项:
exclude再可以用excludeFrom来代替,这样就可以在外部文件单独写要排除同步的文件:
excludeFrom = "/etc/lsyncd_exclude.lst",
外部排除同步文件/etc/lsyncd_exclude.lst的写法:
.svn
Runtime/*
Uploads/*
若某个事件的路径中的某些片段匹配这些文本,那么排除。比如/bin/foo/bar匹配规则foo。
– 如果规则以/开始,那么只匹配路径的开始
如果规则以/结束,那么只匹配路径的结束
– ? 匹配任何不是/的字符
– *匹配0或多次非/字符
– **匹配任何字符0或多次。
相比rsync,主要修改的有以下几点:
Error: error preparing /etc/lsyncd.conf: /etc/lsyncd.conf:69: default.rsyncssh must have maxProcesses set to 1.
settings {
-- 指定日志文件位置
logfile = "/var/log/lsyncd/lsyncd.log",
-- 指定状态文件位置
statusFile = "/var/log/lsyncd/lsyncd.status",
-- inotify事件模式,什么事件才同步,CloseWrite表示文件关闭的时候同步(创建文件,修改文件后再关闭(如vim的:wq)都会触发CloseWrite事件)
inotifyMode = "CloseWrite",
-- 最大同步进程数(default.rsyncssh模式必须设置为1,否则无法启动,default.rsync模式可以设置大于1)
maxProcesses = 1,
-- 配合下面的delay选项使用,delay单位是秒,当delay时间到了,不管maxDelays设置多少,都会同步,同样,当maxDelays达到了设定值,不管是否到delay时间,都会同步,即两个选项有一个满足即会触发同步,为了实时同>步,我们一般设置为1,表示即使只有一个文件改变也同步
maxDelays = 1,
-- 是否以后台的方式运行,注意它是nodaemon,所以是双重否定,如果填false,意思就是“不要不后台运行”(即后台运行),非后台运行一般用于调试,把rsync的verbose也设置为true,这样会把同步的细节输出到控制台,方便调试
nodaemon = false,
}
-- 同步配置default.rsync模式(比如配置从哪同步到哪,要忽略哪些文件,多久同步一次等),可以有多个sync模块,每个模块用于设置一台目标机器
sync {
-- 有default.rsync/default.direct/default.rsyncssh三种模式,我们默认都用default.rsyncssh方式,因为这种方式其实是最好的。
default.rsyncssh,
-- 同步源目录(本机某个目录)
source = "/data/wwwroot/",
-- 同步目标地址,rsyncssh模式写法
host="192.168.1.6",
targetdir="/data/wwwroot/",
-- 默认true,允许删除目录服务器中的某些文件(即删除“那些在源服务器中不存在的文件”),可选值有: true/false/startup/running,startup就是只在启动lsyncd服务的时候判断目标服务器中有哪些文件在源服务器中没有,然后把这些文件删除,但启动之后如果目标服务器又新增了文件,这些文件即使在源服务器不存在,也不会被删除;而running与startup正好相反,是在启动的时候不会删除,启动之后会删除,true=running+startup,false相当于running和startup都不做。
-- delete = true,
-- 哪些文件不同步(可用正则))
exclude = {
'.**',
'.git/**',
'*.bak',
'*.tmp',
'runtime/**',
'cache/**'
},
-- 忽略文件路径规则也可用外部配置文件
-- excludeFrom = "/etc/lsyncd_exclude.lst",
-- 与上边的maxDelays配合,maxDelays是累计事件数(单位:个),delay是时间(单位:秒),这两个只要有一个符合条件就会同步一次,但为了确保实时同步,maxDelays我们一般设置为1,也就是只要有一个文件变化事件,就会同步一次,而delay是比较大的,默认是15。当然,假如我们把maxDelays设置为100,那可能15秒到了也没有达到100个文件变化,但由于到达时间了,它也会同步。
delay = 15,
-- 当init = false时只同步进程启动以后发生改动事件的文件,原有的目录即使有差异也不会同步,如果为true,则启动后如果源目录与目标目录的文件有差异,就会同步,我们当然要设置为true,默认为true,所以这个设置可以不写,写在这里是为了解释它。
-- init = false,
-- rsyncssh的配置(这是default.rsyncssh模式,如果是default.rsyncssh模式,该模块的配置会有所不同)
rsync = {
-- rsync可执行文件的绝对路径
binary = "/usr/bin/rsync",
-- 密码文件路径(rsync模式不用该配置,rsyncssh模式才需要该项)
-- password_file = "/etc/rsyncd.password",
-- 打包后再同步(注意,打包不等于压缩,打包即可以压缩也可以不压缩)
archive = true,
-- 压缩后再同步
compress = true,
-- 同步符号链接文件
copy_links = true,
-- 同步符号链接目录
copy_dirlinks = true,
-- 输出同步信息(由于是后台执行,所以没必要输出,如果非后台执行可以设置为true,非后台执行主要用于调试)
verbose = false,
-- 由于rsync有非常多的选项(请自己rsync --help查看),部分非主要选项可以用_extra的方式指定,双引号引住,逗号分隔(bwlimit中的bw是bandwith,即带宽,整个意思是带宽限制,omit-link-times忽略符号链接的修改时间)
_extra = {"--bwlimit=200", "--omit-link-times"},
-- 指定ssh相关参数选项
rsh = "/usr/bin/ssh -l xiebruce -i /root/.ssh/id_rsa -o StrictHostKeyChecking=no"
}
}
其中这一句就是用来通过ssh登录到服务器的:
rsh = "/usr/bin/ssh -l xiebruce -i /root/.ssh/id_rsa -o StrictHostKeyChecking=no"
The authenticity of host '192.168.1.6 (192.168.1.6)' can't be established.
ECDSA key fingerprint is SHA256:xcDUp3zNlJvhY4fwfwDH1pgOyc5p8Vsr2OjopanEQBw.
Are you sure you want to continue connecting (yes/no)?
如果你输入no那就不会登录,如果你输入yes,就会登录,并且把这个“key fingerprint”(指纹密钥)添加到你终端的ssh配置目录下的known_hosts文件中,这个文件的位置,对于Mac/Linux电脑,是在~/.ssh/known_hosts,Windows的话则是在C:\Users\用户名\目录下。
同理,现在是rsync登录你的ssh,所以rsync也会存储这样的指纹密钥,如果“StrictHostKeyChecking”设置为yes,就意味着每次都要严格检查密钥(就相当于你用终端登录时,每次都要你输入一遍yes),这样显然是没必要的,所以我们要把它设置为“StrictHostKeyChecking=no”。
sync {
default.direct,
source = "/home/user/src/",
target = "/home/user/trg/"
}
lsyncd 配置
格式如下,每台目标服务器一个sync模块即可,每个sync模块都像上边说的那样写就行,其实就只是ip不同,其他都一样:
settings {
logfile = "/var/log/lsyncd/lsyncd.log",
inotifyMode = "CloseWrite or Modify",
-- statusFile = "/var/log/lsyncd/lsyncd.status",
}
-- B服务器配置
sync {
default.rsync,
source = "/etc/nginx/",
target = "rsync://rsync@192.168.1.6:1873/nginx/",
exclude = { ".*", "*.tmp", "*.swp", "*.bak", "*.log", "*.swx", "*~", "sets/config.json", "listen_local_*" },
delay = 2,
init = false,
rsync = {
password_file = "/etc/rsyncd.passwd",
archive = true,
compress = true,
verbose = true,
checksum = true,
ignore_times = true
}
}
-- C服务器配置
sync {
default.rsync,
source = "/data/scripts/",
target = "rsync://rsync@192.168.1.100:1873/script/",
exclude = { ".*", "*.tmp", "*.swp", "*.bak", "*.log", "*.out", "*/logs/*", "*.swx", "*~" },
delay = 2,
init = false,
rsync = {
password_file = "/etc/rsyncd.passwd",
archive = true,
compress = true,
verbose = true,
checksum = true,
ignore_times = true
}
}
rsyncd.conf 配置
#/etc/rsyncd: configuration file for rsync daemon mode
uid = root
gid = root
#use chroot = yes
use chroot = no
max connections = 10
strict modes =yes
address = 192.168.1.5
port = 1873
timeout = 600
dont compress = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2
#ignore nonreadable = yes
motd file = /etc/rsyncd.motd
secrets file = /etc/rsyncd.secrets
[nginx]
path = /etc/nginx/
comment = nginx conf file
ignore errors
read only = no
write only = no
hosts allow=192.168.1.0/24
#hosts deny = *
list = false
auth users = rsync
#/etc/rsyncd: configuration file for rsync daemon mode
uid = root
gid = root
#use chroot = yes
use chroot = no
max connections = 10
strict modes =yes
address = 192.168.1.5
port = 1873
timeout = 600
dont compress = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2
#ignore nonreadable = yes
motd file = /etc/rsyncd.motd
secrets file = /etc/rsyncd.secrets
[script]
path = /data/scripts/
comment = scripts file
ignore errors
read only = no
write only = no
hosts allow=192.168.1.0/24
#hosts deny = *
list = false
auth users = rsync