1. 写在前面
Lsyncd (Live Syncing Daemon) 轻量级本地与远程实时同步解决方案,遵循 GPL-2.0 license。本文将通过示例介绍如何在 Linux 环境中执行实时同步操作。
2. 概述
Lsyncd 使用文件系统事件接口(inotify 或 fsevents)来监视本地文件和目录的更改,并在短时内汇总合并事件,然后启动一个或多个进程将更改同步到远程文件系统,默认同步方式是 rsync 模式。
安装相对简单,对系统本身没有太多要求,也不会影响本地文件系统的性能。
作为 rsync 的替代方案,lsyncd 可以通过 rsync+ssh 模式提高同步效率,例如,重命名文件/目录或者移动位置(普通 rsync 通过删除旧文件然后重新传输整个文件来执行移动)。
优点:
实时同步(单向):lsyncd 通过监控文件系统事件(inotify 或 fsevents),可以在文件变化时触发同步;
基于 rsync:使用 rsync 进行实际的文件传输,继承 rsync 高效性和灵活性;
自动化:配置好,lsyncd 可以自动监控和同步文件变化;
灵活性:通过 Lua 脚本配置,定制同步行为;
缺点:
复杂性:配置文件高级用法可能对刚接触用户来说有些复杂;
资源消耗:实时监控和同步可能会消耗一定的系统资源,特别是在有大量文件变化的情况下;
延迟问题:尽管是实时同步,但对于非常频繁的变化,可能会有轻微的延迟;
使用场景:
日志文件同步:在需要实时同步日志文件到远程服务器进行分析时,lsyncd 非常有用;
实时备份:适用于需要实时备份重要数据的场景;
Web 服务器文件同步:在多台 Web 服务器之间同步静态文件,确保所有服务器上的文件保持一致;
3. 安装
Lsyncd 可在 Fedora、Debian 和 Ubuntu 的官方软件仓库中找到,例如:在 Debian 及其衍生版本上进行安装,可以使用 apt:
sudo apt install lsyncd
要在 Fedora 上安装 lsyncd,可以使用:
sudo dnf install lsyncd
lsyncd 不是 RHEL/CentOS 7 默认仓库的一部分,因此必须使用 EPEL 仓库安装它,可以使用以下命令安装 epel-repo:
[root@centos-7 ~]# yum -y install epel-release
安装 lsyncd:
[root@centos-7 ~]# yum -y install lsyncd
4. 配置 lsyncd
lsyncd 使用 Lua 配置文件,通常位于 /etc/lsyncd/lsyncd.conf.lua,也可以通过以下方式查看路径:
查看:systemctl status lsyncd
root@jpzhang-dev:~# systemctl status lsyncd
● lsyncd.service - LSB: lsyncd daemon init script
Loaded: loaded (/etc/init.d/lsyncd; generated)
Active: active (exited) since Tue 2024-07-30 00:31:05 CST; 23h ago
... ...
查看:/etc/init.d/lsyncd
... ...
CONFIG=/etc/lsyncd/lsyncd.conf.lua
... ...
默认配置路径:/etc/lsyncd/lsyncd.conf.lua,如果不存在则新建,或者从 /usr/share/doc/lsyncd*/examples 提供的示例中拷贝一份进行修改。
官方示例:
root@jpzhang-dev:/home/workspace/linux# ls /usr/share/doc/lsyncd*/examples
lalarm.lua lbash.lua lecho.lua lftp.lua lgforce.lua limagemagic.lua lpostcmd.lua lrsync.lua lrsyncssh.lua ls3.lua.gz lsayirc.lua
例如,下面配置:
settings {
logfile = "/var/log/lsyncd/lsyncd.log", -- 指定日志文件路径
statusFile = "/var/log/lsyncd-status.log", -- 指定状态文件路径
statusInterval = 20, -- 每 20 秒写入一次状态文件
nodaemon = true -- 守护进程模式运行
}
lsyncd 的配置文件是用 Lua 脚本编写的,支持高度的自定义。
以下是配置文件中的主要选项:
(1) settings 表
settings 表用于定义全局设置。
settings {
logfile = "/var/log/lsyncd/lsyncd.log", -- 指定日志文件路径
statusFile = "/var/log/lsyncd-status.log", -- 指定状态文件路径
inotifyMode = "CloseWrite or Modify", -- 指定 inotify 事件模式
statusInterval = 20, -- 每 20 秒写入一次状态文件
nodaemon = true -- 守护进程模式运行
}
logfile: 日志文件路径,用于记录 lsyncd 的运行日志;
logfile = "/var/log/lsyncd/lsyncd.log",statusFile: 状态文件路径,用于记录 lsyncd 的状态信息;
statusFile = "/var/log/lsyncd/lsyncd.status",statusInterval: 设置写入状态文件的间隔时间,以秒为单位,默认 10s;
statusInterval = 20,nodaemon: 设置 lsyncd 以守护进程模式运行 true/false;
nodaemon = true,inotifyMode: 指定 inotify 事件模式;
inotifyMode = "CloseWrite or Modify"maxProcesses:限制并发的进程数;
maxProcesses = 1delay:设置同步的延迟时间(秒);
delay = 15
(2) sync 表
sync 表用于定义同步任务。
default(必需)
指定要使用的同步模式,常用的同步模式有 default.rsync 和 default.direct。
default.rsyncdefault.rsync: 使用 rsync 进行同步;
default.direct: 直接复制文件,不使用 rsync;
source(必需)
定义源目录的路径。
source = "/path/to/source"target(必需)
定义目标目录的路径,可以是本地路径或远程路径。
target = "/path/to/target"delay
设置同步延迟时间(以秒为单位),表示在检测到文件更改后等待多长时间再进行同步。
delay = 10exclude
指定要排除的文件或目录的模式列表。
exclude = { "*.tmp", "*.log", "cache/", "temp/" }excludeFrom
指定一个包含要排除文件和目录列表的文件路径。
excludeFrom = "/path/to/exclude-list.txt"rsync
指定 rsync 相关的配置参数。
rsync = {
binary = "/usr/bin/rsync", -- rsync 可执行文件路径
archive = true, -- 归档模式(保留权限、时间戳等)
compress = false, -- 不压缩数据
delete = true, -- 删除目标目录中不在源目录中的文件
verbose = true -- 显示详细输出
}init
初始化同步时执行的脚本。
init = function(event)
os.execute("sh /path/to/scripts/init_script.sh")
return false -- 阻止默认的 init 同步
endcollect
在收集完所有变化但尚未开始同步操作时执行的脚本。
collect = function(event)
os.execute("sh /path/to/scripts/collect_sync.sh")
endaction
定义在执行同步操作时的自定义行为。
action = function(inlet)
local result = Rsync(inlet, true) -- 执行 rsync 操作
os.execute("sh /path/to/scripts/post_sync.sh")
return result
end
完整示例
settings {
logfile = "/var/log/lsyncd/lsyncd.log",
statusFile = "/var/log/lsyncd/lsyncd.status",
statusInterval = 10
}
sync {
default.rsync,
source = "/path/to/source",
target = "/path/to/target",
delay = 10,
exclude = { "*.tmp", "*.log", "cache/", "temp/" },
excludeFrom = "/path/to/exclude-list.txt",
rsync = {
binary = "/usr/bin/rsync", -- rsync 可执行文件路径
archive = true, -- 归档模式(保留权限、时间戳等)
compress = false, -- 不压缩数据
delete = true, -- 删除目标目录中不在源目录中的文件
verbose = true -- 显示详细输出
},
init = function(event)
os.execute("sh /path/to/scripts/init_script.sh")
return false -- 阻止默认的 init 同步
end,
collect = function(event)
os.execute("sh /path/to/scripts/collect_sync.sh")
end,
action = function(inlet)
local result = Rsync(inlet, true) -- 执行 rsync 操作
os.execute("sh /path/to/scripts/post_sync.sh")
return result
end
}
更多设置,请查看 lysyncd 官方页面;
5. 启动和管理 lsyncd 服务
启动 lsyncd:
sudo systemctl start lsyncd开机自启:
sudo systemctl enable lsyncd检查状态:
sudo systemctl status lsyncd查看日志:
配置文件配置,默认 Linux 在 syslog 打印日志;
tail -f /var/log/lsyncd/lsyncd.log
6. 10+ lsyncd 示例
6.1 命令行:实时同步目录&文件
6.1.1 运行时参数说明
-help: 显示帮助信息
lsyncd -help-version: 显示 lsyncd 版本信息
lsyncd -version-nodaemon: 以非守护进程模式运行 lsyncd,便于调试
lsyncd -nodaemon /path/to/config.lua-log Exec, -log Minimal: 设置日志级别
lsyncd -log Exec /path/to/config.lua
lsyncd -log Minimal /path/to/config.lua-rsync [source] [target]: 直接从命令行启动 lsyncd,使用 rsync 模式同步源和目标目录
lsyncd -rsync /source/ /target/
6.1.2 用例说明
示例环境:
root@jpzhang-dev:/home/workspace/linux# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.6 LTS
Release: 20.04
Codename: focal
使用 lsyncd rsync 同步 localhost 上的目录:
-rsync [source] [target]: 直接从命令行启动 lsyncd,并使用 rsync 模式同步源和目标目录。
root@jpzhang-dev:/home/workspace/linux# ls
source target
root@jpzhang-dev:/home/workspace/linux# lsyncd -rsync /home/workspace/linux/source/ /home/workspace/linux/target/
11:20:35 Normal: --- Startup, daemonizing ---
root@jpzhang-dev:/home/workspace/linux# ps -aux | grep lsyncd
root 903394 0.0 0.0 4508 2152 ? Ss 16:57 0:00 lsyncd -rsync /home/workspace/linux/source/ /home/workspace/linux/target
root@jpzhang-dev:/home/workspace/linux# echo 'Hello world!!!' > ./source/jpzhang.txt
root@jpzhang-dev:/home/workspace/linux# echo '========' >> ./source/jpzhang.txt
【注意】
source & target 需要配置绝对路径;
默认通过 syslog 输出日志;
lsyncd 进程进入后台,作为守护进程运行,也可以 添加 -nodaemon 参数,以非守护进程模式运行 lsyncd,便于调试。
root@jpzhang-dev:/home/workspace/linux# lsyncd -nodaemon -rsync /home/workspace/linux/source/ /home/workspace/linux/target
17:46:25 Normal: --- Startup ---
17:46:25 Normal: recursive startup rsync: /home/workspace/linux/source/ -> /home/workspace/linux/target/
17:46:25 Normal: Startup of /home/workspace/linux/source/ -> /home/workspace/linux/target/ finished.
17:48:16 Normal: Calling rsync with filter-list of new/modified files/dirs
/jpzhang.txt
/
17:48:16 Normal: Finished a list after exitcode: 0
source 内容变更:
root@jpzhang-dev:/home/workspace/linux# echo 'edit content~~' >> ./source/jpzhang.txt
root@jpzhang-dev:/home/workspace/linux# cat target/jpzhang.txt
Hello world!!!
========
edit content~~
要跨主机同步文件和目录
(1)使用: rsync 模式
root@jpzhang-dev:/home/workspace/linux# lsyncd -nodaemon -rsync /home/workspace/linux/source/ linux-dev:/home/tmp/target
17:52:10 Normal: --- Startup ---
17:52:10 Normal: recursive startup rsync: /home/workspace/linux/source/ -> linux-dev:/home/tmp/target/
17:52:11 Normal: Startup of /home/workspace/linux/source/ -> linux-dev:/home/tmp/target/ finished.
17:53:09 Normal: Calling rsync with filter-list of new/modified files/dirs
/jpzhang.txt
/
17:53:10 Normal: Finished a list after exitcode: 0
source 内容变更:
root@jpzhang-dev:/home/workspace/linux# echo 'To sync files and directories across hosts' >> ./source/jpzhang.txt
Linux-dev:
root@zhangjianpeng:/home/tmp/target# cat jpzhang.txt
Hello world!!!
========
edit content~~
To sync files and directories across hosts
【注意】
/etc/host: 添加域名映射;
host1(源) ->host2(目标):无密访问;
(2)使用:rsyncssh 模式
root@jpzhang-dev:/home/workspace/linux# lsyncd -nodaemon -rsyncssh /home/workspace/linux/source/ linux-dev /home/tmp/target
17:58:53 Normal: --- Startup ---
17:58:53 Normal: recursive startup rsync: /home/workspace/linux/source/ -> linux-dev:/home/tmp/target/
17:58:54 Normal: Startup of "/home/workspace/linux/source/" finished: 0
6.2 使用 default.direct 同步本地目录和文件
lsyncd 的 default.direct 模式使用的是 cp、rm 和 mv 命令进行文件的复制、删除和移动操作,这与 rsync 模式的不同之处在于其不依赖于 rsync 工具。这种模式适用于在本地文件系统之间进行简单同步,或者在不需要使用 rsync 提供的高级选项和功能的情况下使用,不适用于跨网络同步,因为 cp、rm 和 mv 都是本地文件操作命令。
以下是一个使用 default.direct 模式的 lsyncd 配置文件示例:
/etc/lsyncd/lsyncd.conf.lua:
settings {
logfile = "/var/log/lsyncd/lsyncd.log", -- 指定日志文件路径
statusFile = "/var/log/lsyncd/lsyncd.status", -- 指定状态文件路径
statusInterval = 10, -- 每 10 秒写入一次状态文件
inotifyMode = "CloseWrite or Modify" -- 设置 inotify 事件模式
}
sync {
default.direct, -- 使用 default.direct 模式进行同步
source = "/home/workspace/linux/source/", -- 本地源目录路径
target = "/home/workspace/linux/target", -- 本地目标目录路径
delay = 5, -- 设置文件系统事件到实际同步操作之间的延迟时间
excludeFrom = "/home/workspace/linux/exclude-list.txt", -- 排除的文件或目录列表
maxProcesses = 1 -- 限制同时运行的同步进程数
}
重启 lsyncd:
systemctl restart lsyncd
查看日志:
root@jpzhang-dev:~# tail -f /var/log/lsyncd/lsyncd.log
Tue Jul 30 23:56:55 2024 Normal: --- Startup, daemonizing ---
Tue Jul 30 23:56:55 2024 Normal: recursive startup rsync: /home/workspace/linux/source/ -> linux-dev:/home/tmp/target/
Tue Jul 30 23:56:56 2024 Normal: Startup of /home/workspace/linux/source/ -> linux-dev:/home/tmp/target/ finished.
6.3 使用 default.rsync 将本地主机上的源文件和目录同步到另一台目标主机上
default.rsync 模式使用 rsync 工具进行同步,可以在本地或通过网络同步目录。rsync 提供了高级选项,如差异同步、压缩和删除目标中不在源中的文件。
修改默认配置:/etc/lsyncd/lsyncd.conf.lua
root@jpzhang-dev:/home/workspace/linux/source# cat /etc/lsyncd/lsyncd.conf.lua
settings {
logfile = "/var/log/lsyncd/lsyncd.log",
statusFile = "/var/log/lsyncd/lsyncd.status",
statusInterval = 10,
inotifyMode = "CloseWrite or Modify",
}
sync {
default.rsync,
source = "/home/workspace/linux/source/",
target = "linux-dev:/home/tmp/target",
delay = 5,
maxProcesses = 1
}
重启 rsync:systemctl restart lsyncd
6.4 使用 default.rsyncssh 将本地主机上的源目录和文件同步到不同的目标主机上
lsyncd 还可以配置使用 ssh 命令在目标主机移动文件或目录,这样可以避免重复传输相同的文件。
原理:当文件发生变化时,lsyncd 会生成一个 rsync 进程,通过 ssh 命令连接到目标主机。在目标主机上,文件或目录会被本地移动(使用 mv 命令),而不是被删除并重新传输。这种方法可以有效减少网络传输量,提高同步效率。
root@jpzhang-dev:/home/workspace/linux/source# cat /etc/lsyncd/lsyncd.conf.lua
settings {
logfile = "/var/log/lsyncd/lsyncd.log",
statusFile = "/var/log/lsyncd/lsyncd.status",
statusInterval = 10,
inotifyMode = "CloseWrite or Modify",
}
sync {
default.rsyncssh,
source = "/home/workspace/linux/source/",
target = "linux-dev:/home/tmp/target",
delay = 5,
maxProcesses = 1
}
6.5 使用 lsyncd 为目录启用压缩和递归功能
同步文件时启用压缩和递归功能。
archive = true:递归同步并保留文件属性;
compress = false:不压缩数据,减少 CPU 负担(可以根据需要设置为 true);
root@jpzhang-dev:/home//workspace/linux/source# cat /etc/lsyncd/lsyncd.conf.lua
settings {
logfile = "/var/log/lsyncd/lsyncd.log",
statusFile = "/var/log/lsyncd/lsyncd.status",
statusInterval = 10,
inotifyMode = "CloseWrite or Modify",
}
sync {
default.rsync,
source = "/home/workspace/linux/source/",
target = "linux-dev:/home/tmp/target",
delay = 5,
maxProcesses = 1,
rsync = {
archive = true,
compress = true
}
}
6.6 同步到多个目标目录
在 Linux 中使用 lsyncd 从一个源目录同步到多个目标目录,可以通过两种主要方法实现:创建单独的同步任务,或者使用 for 循环动态生成同步任务。
以下是两种方法的详细说明和示例配置。
方法一:创建单独的同步任务
通过在配置文件中为每个目标目录创建单独的同步任务,可以明确地定义每个同步任务的参数和行为。这种方法适用于需要对每个同步任务进行特定配置的情况。
root@jpzhang-dev:/home/workspace/linux# cat /etc/lsyncd/lsyncd.conf.lua
settings {
logfile = "/var/log/lsyncd/lsyncd.log",
statusFile = "/var/log/lsyncd/lsyncd.status",
statusInterval = 10,
inotifyMode = "CloseWrite or Modify",
}
sync {
default.rsync,
source = "/home/workspace/linux/source/",
target = "/home/workspace/linux/target",
delay = 5,
}
sync {
default.rsync,
source = "/home/workspace/linux/source/",
target = "/home/workspace/linux/target2",
delay = 5,
}
sync {
default.rsync,
source = "/home/workspace/linux/source/",
target = "linux-dev:/home/tmp/target",
delay = 5,
}
方法二:使用 for 循环动态生成同步任务
通过使用 Lua 语言中的 for 循环,可以动态生成多个同步任务。这种方法适用于目标目录较多且配置相似的情况,简化配置文件的编写和维护。
root@jpzhang-dev:/home/workspace/linux# cat /etc/lsyncd/lsyncd.conf.lua
settings {
logfile = "/var/log/lsyncd/lsyncd.log",
statusFile = "/var/log/lsyncd/lsyncd.status",
statusInterval = 10,
inotifyMode = "CloseWrite or Modify",
}
targets = {
"/home/workspace/linux/target",
"/home/workspace/linux/target2",
"linux-dev:/home/tmp/target",
}
for _, target in ipairs( targets )
do
sync{ default.rsync, source='/home/workspace/linux/source/', target=target }
end
重启: systemctl restart lsyncd日志输出: less /var/log/lsyncd/lsyncd.log
... ...
Tue Jul 30 23:59:07 2024 Normal: Finished a list after exitcode: 0
Wed Jul 31 10:46:04 2024 Normal: --- TERM signal, fading ---
Wed Jul 31 10:46:04 2024 Normal: --- Startup, daemonizing ---
Wed Jul 31 10:46:04 2024 Normal: recursive startup rsync: /home/workspace/linux/source/ -> /home/workspace/linux/target/
Wed Jul 31 10:46:04 2024 Normal: recursive startup rsync: /home/workspace/linux/source/ -> /home/workspace/linux/target2/
Wed Jul 31 10:46:04 2024 Normal: recursive startup rsync: /home/workspace/linux/source/ -> linux-dev:/home/tmp/target/
Wed Jul 31 10:46:04 2024 Normal: Startup of /home/workspace/linux/source/ -> /home/workspace/linux/target2/ finished.
Wed Jul 31 10:46:04 2024 Normal: Startup of /home/workspace/linux/source/ -> /home/workspace/linux/target/ finished.
Wed Jul 31 10:46:05 2024 Normal: Startup of /home/workspace/linux/source/ -> linux-dev:/home/tmp/target/ finished.
6.7 在 rsync 操作前后执行脚本
在 lsyncd 中,你可以配置在 rsync 操作前后执行脚本,
示例:源和目标同步完成,执行 “target1_status.sh” 脚本,打印 “Completed sync in target”,可用于检查目录同步退出状态。
root@jpzhang-dev:/home/workspace/linux# cat /etc/lsyncd/lsyncd.conf.lua
settings {
logfile = "/var/log/lsyncd/lsyncd.log",
statusFile = "/var/log/lsyncd/lsyncd.status",
statusInterval = 10,
inotifyMode = "CloseWrite or Modify",
}
sync {
default.rsync,
source = "/home/workspace/linux/source/",
target = "/home/workspace/linux/target",
delay = 5,
rsync = {
binary = "/home/workspace/linux/lsyncd/target1_status.sh",
},
}
target1_status.sh:
root@jpzhang-dev:/home/workspace/linux# cat lsyncd/target1_status.sh
#!/bin/bash
/usr/bin/rsync "$@"
result=$?
(
if [ $result -eq 0 ]; then
echo "`date`: Completed sync in target" >> /var/log/lsyncd/custom_scripts.log
fi
) >/dev/null 2>/dev/null </dev/null
exit $result
6.8 排除文件和目录
在 lsyncd 中,可以通过配置 exclude 和 excludeFrom 参数来排除特定的文件和目录。
exclude:用于排除指定的文件和目录,可以使用通配符来匹配文件和目录名称:
exclude = { "*.tmp", "*.log", "cache/", "temp/" }以上配置将排除所有以 .tmp 和 .log 结尾的文件,以及名为 cache/ 和 temp/ 的目录。
excludeFrom: 参数指定一个包含要排除文件和目录列表的文件路径,这个文件中的每一行都代表一个排除模式:
创建 exclude-list.txt 文,添加要排除的文件和目录模式:
# /path/to/exclude-list.txt
*.tmp
*.log
cache/
temp/然后在配置文件中引用这个文件:
excludeFrom = "/path/to/exclude-list.txt"
6.9 同步目录删除文件
默认情况下,Lsyncd 会删除目标目录中那些在源目录中已经不存在的文件,以保持目标目录与源目录的同步。这是确保同步完整性的基本操作。然而,用户可能会出于各种原因需要排除某些情况,因此 delete 选项在默认配置中通常是作为附加参数使用。
delete 选项的有效值包括:
delete = true:默认值,Lsyncd 会在目标目录中删除源目录中没有的内容,无论是在启动时还是正常运行时;
delete = false:不会删除目标目录中的任何文件,无论是启动时还是正常运行时(但可以重写);
delete = 'startup':Lsyncd 在启动时会删除目标目录中的文件,但在正常运行时不会删除;
delete = 'running':Lsyncd 在启动时不会删除目标目录中的文件,但在正常运行时会删除;
sync {
default.direct,
source = "/source",
target = "/target1",
delay = 10,
delete = false
}



