一、介绍
Lsyncd (Live Syncing Daemon) 轻量级本地与远程实时同步解决方案,遵循 GPL-2.0 license。
Lsyncd 使用文件系统事件接口(inotify 或 fsevents)来监视本地文件和目录的更改,并在短时内汇总合并事件,然后启动一个或多个进程将更改同步到远程文件系统,默认同步方式是 rsync 模式。
优点:
- 实时同步(单向):lsyncd 通过监控文件系统事件(inotify 或 fsevents),可以在文件变化时触发同步;
- 基于 rsync:使用 rsync 进行实际的文件传输,继承 rsync 高效性和灵活性;
- 自动化:配置好,lsyncd 可以自动监控和同步文件变化;
- 灵活性:通过 Lua 脚本配置,定制同步行为;
缺点:
- 复杂性:配置文件高级用法可能对刚接触用户来说有些复杂;
- 资源消耗:实时监控和同步可能会消耗一定的系统资源,特别是在有大量文件变化的情况下;
- 延迟问题:尽管是实时同步,但对于非常频繁的变化,可能会有轻微的延迟;
使用场景:
- 日志文件同步:在需要实时同步日志文件到远程服务器进行分析时,lsyncd 非常有用;
- 实时备份:适用于需要实时备份重要数据的场景;
- Web 服务器文件同步:在多台 Web 服务器之间同步静态文件,确保所有服务器上的文件保持一致。
作为 rsync 的替代方案,lsyncd 可以通过 rsync+ssh 模式提高同步效率,例如,重命名文件/目录或者移动位置(普通 rsync 通过删除旧文件然后重新传输整个文件来执行移动)。
原理:
lsyncd (Live Syncing Daemon) 是一个轻量级的同步守护进程,它内部结合了 inotify(监控文件变化)和 rsync(远程同步),并支持将短时间内的多个文件变化合并后一起同步,效率很高。
lsyncd 通过 inotify 机制持续监控 source 目录。只有当 source 里的文件发生了新增、修改或删除,它才会触发 rsync 把变化同步到 target。
二、安装与使用
相关机器:
- 可以互通网络
- 已安装 rsync
- 已配置免密 SSH 登录(强烈建议)
2.1、安装
sudo apt install lsyncd rsync ssh -y
sudo systemctl start lsyncd
sudo systemctl enable lsyncd
日志:tail -f /var/log/lsyncd/lsyncd.log
lsyncd -version
rsync --version
ssh -V

2.2、配置 lsyncd
lsyncd 使用 Lua 配置文件,通常位于 /etc/lsyncd/lsyncd.conf.lua,也可以通过以下方式查看路径:
查看:systemctl status lsyncd

查看:/etc/init.d/lsyncd

默认配置路径:/etc/lsyncd/lsyncd.conf.lua,如果不存在则新建,或者从 /usr/share/doc/lsyncd*/examples 提供的示例中拷贝一份进行修改。

例如,下面配置:
Lua
-- settings 表用于定义全局设置
settings {
logfile = "/var/log/lsyncd/lsyncd.log", -- 指定日志文件路径, 用于记录 lsyncd 的运行日志
statusFile = "/var/log/lsyncd-status.log", -- 指定状态文件路径, 用于记录 lsyncd 的状态信息
inotifyMode = "CloseWrite or Modify", -- 指定 inotify 事件模式。默认是CloseWrite,还可以是Modify或CloseWrite or Modify
statusInterval = 20, -- 每 20 秒写入一次状态文件
maxProcesses = 1, -- 限制并发的进程数
delay = 15, -- 设置同步的延迟时间(秒)。若在sync中设置,这里可不设置
nodaemon = false -- 是否以前台运行, false:后台守护进程,true:前台调试运行
}
-- sync 表用于定义同步任务
sync {
default.rsync, -- 指定要使用的同步模式,常用的有default.rsync(使用 rsync 进行同步) ;default.direct :本地目录间同步,使用cp、rm等命令完成差异文件备份;default.rsyncssh :同步到远程主机目录,rsync的ssh模式,需要使用key来认证
source = "/path/to/source/", -- 定义源目录的路径,使用绝对路径
target = "user@remote_host:/path/to/destination/", -- 定义目标目录的路径,可以是本地路径或远程路径
delay = 5, -- 等待rsync同步延时时间,默认15秒(最大累计到1000个不可合并的事件)
exclude = { "*.tmp", "*.log", "cache/", "temp/" }, -- 指定要排除的文件或目录的模式列表。相对于source的相对路径
excludeFrom = "/path/to/exclude-list.txt", -- 指定一个包含要排除文件和目录列表的文件路径
delete = true, -- 为了保持target与souce完全同步,Lsyncd默认会delete = true来允许同步删除。它除了false,还有startup、running值
rsync = {
binary = "/usr/bin/rsync", -- rsync 可执行文件路径
archive = true, -- 等同于 -a 参数,保留文件属性
compress = true, -- 传输时压缩
verbose = true -- 显示详细输出
}
}
这里的 delay 参数很关键,它能有效防止因文件高频变动而频繁触发同步带来的性能损耗**。**

三、案例说明
Lua
settings {
logfile = "/var/log/lsyncd/lsyncd.log",
statusFile = "/var/log/lsyncd-status.log",
inotifyMode = "CloseWrite or Modify",
maxProcesses = 8
}
-- I. 本地目录同步,direct:cp/rm/mv。 适用:500+万文件,变动不大
sync {
default.direct,
source = "/tmp/src",
target = "/tmp/dest",
delay = 1
maxProcesses = 1
}
-- II. 本地目录同步,rsync模式:rsync
sync {
default.rsync,
source = "/tmp/src",
target = "/tmp/dest1",
excludeFrom = "/etc/rsyncd.d/rsync_exclude.lst",
rsync = {
binary = "/usr/bin/rsync",
archive = true,
compress = true,
bwlimit = 2000
}
}
-- III. 远程目录同步,rsync模式 + rsyncd daemon
sync {
default.rsync,
source = "/tmp/src",
target = "syncuser@172.29.88.223::module1",
delete = "running",
exclude = { ".*", ".tmp" },
delay = 30,
init = false,
rsync = {
binary = "/usr/bin/rsync",
archive = true,
compress = true,
verbose = true,
password_file = "/etc/rsyncd.d/rsync.pwd",
_extra = {"--bwlimit=200"}
}
}
-- IV. 远程目录同步,rsync模式 + ssh shell
sync {
default.rsync,
source = "/tmp/src",
target = "root@172.29.88.223:/remote/dest", -- 上面target,注意如果是普通用户,必须拥有写权限
maxDelays = 5,
delay = 30,
-- init = true,
rsync = {
binary = "/usr/bin/rsync",
archive = true,
compress = true,
bwlimit = 2000
-- rsh = "/usr/bin/ssh -p 22 -o StrictHostKeyChecking=no"
-- 如果要指定其它端口,请用上面的rsh
}
}
-- V. 远程目录同步,rsync模式 + rsyncssh,效果与上面相同
sync {
default.rsyncssh,
source = "/tmp/src2",
host = "172.29.88.223",
targetdir = "/remote/dir",
excludeFrom = "/etc/rsyncd.d/rsync_exclude.lst",
delay = 2,
rsync = {
binary = "/usr/bin/rsync",
archive = true,
compress = true,
verbose = true,
_extra = {"--bwlimit=2000"},
},
ssh = {
port = 22
}
}
四、配置 SSH 免密登录
lsyncd 会频繁调用 rsync,而 rsync 常通过 ssh 连接远端。为了避免每次都输入密码,需要配置 SSH key
python
# 安装ssh-keygen和ssh-copy-id
apt install openssh-client
# 生成本地 SSH 密钥(如果已有可跳过)
ssh-keygen -t rsa -b 4096 -N "" -f ~/.ssh/id_rsa
# 将公钥复制到远程主机,(将本机的/root/.ssh/id_rsa.pub公钥复制到远程主机的/root/.ssh/authorized_keys文件)
ssh-copy-id gc@10.68.250.14
# 测试免密登录
ssh gc@10.68.250.14 "echo success"

五、实测
5.1、本地同步
配置:/etc/lsyncd/lsyncd.conf.lua
Lua
-- settings 表用于定义全局设置
settings {
logfile = "/var/log/lsyncd/lsyncd.log",
statusFile = "/var/log/lsyncd-status.log",
inotifyMode = "CloseWrite or Modify",
statusInterval = 20,
maxProcesses = 1,
nodaemon = false
}
-- sync 表用于定义同步任务
sync {
default.rsync,
source = "/home/gc/lsyncd/source/",
target = "gc@10.68.250.13:/home/gc/lsyncd/dest/",
delay = 5,
delete = true,
rsync = {
binary = "/usr/bin/rsync",
archive = true,
compress = true,
verbose = true
}
}
先建议前台运行检查配置是否正确: lsyncd -nodaemon /etc/lsyncd/lsyncd.conf.lua

在/home/gc/lsyncd/source/新建个test.py文件:

在/home/gc/lsyncd/source/下删除文件tiny-graphrag.zip:

修改在/home/gc/lsyncd/source/test.py:

修改在/home/gc/lsyncd/dest/test.py:
无输出

配置正确后后台运行 : lsyncd /etc/lsyncd/lsyncd.conf.lua
5.2、跨机器同步
配置:/etc/lsyncd/lsyncd.conf.lua
Lua
-- settings 表用于定义全局设置
settings {
logfile = "/var/log/lsyncd/lsyncd.log",
statusFile = "/var/log/lsyncd-status.log",
inotifyMode = "CloseWrite or Modify",
statusInterval = 20,
maxProcesses = 1,
nodaemon = false
}
-- sync 表用于定义同步任务
sync {
default.rsync,
source = "/home/gc/lsyncd/source/",
target = "gc@10.68.250.14:/home/gc/lsyncd/dest/",
delay = 5,
delete = true,
rsync = {
binary = "/usr/bin/rsync",
archive = true,
compress = true,
verbose = true
}
}
先建议前台运行检查配置是否正确: lsyncd -nodaemon /etc/lsyncd/lsyncd.conf.lua

报错1:

原因: rsync 权限不足:目标端用户 gc@10.68.250.13 对 /home/gc/lsyncd/dest/ 目录没有写权限
方案:
sudo chown gc:gc /home/gc/lsyncd/dest # 将目录所有者改为 gc
注意事项
问1:这个大文件夹里的数据也在持续的更新, rsync 命令行手动全量同步会出问题吗?
**答:**会有问题。如果在持续写入的目录上执行 rsync 手动全量同步,很可能导致同步结果不一致、数据丢失或重复同步。
rsync 执行全量同步通常分两步:
- 扫描阶段:遍历源目录,构建文件列表(包括文件名、大小、mtime 等元数据)。这一步可能耗时较长,尤其是大目录。
- 传输阶段:根据扫描结果,逐个文件比对并传输。
问题根源:从扫描开始到传输结束,源目录一直在变化。rsync 不会对文件系统做"原子快照",因此会错过或错误处理扫描过程中发生的变更。
手动 rsync + 后续 Lsyncd 仅适用于源目录在 rsync 期间完全静止的场景(例如停机维护、数据库备份完成后的导出目录)。如果数据持续更新,不要使用这种组合。
最佳方案:直接使用 Lsyncd 的 init = true(原生支持动态数据)
Lsyncd 设计之初就考虑了这种场景。当设置 init = true 时:
- Lsyncd 启动后立即注册 inotify 监听,所以后续所有事件都不会丢失。
- 然后Lsyncd 执行一次 rsync 全量同步(相当于手动 rsync 的作用)。
- 在全量同步过程中,inotify 持续收集新的文件事件,存入队列。
- 全量同步完成后,Lsyncd 会再次处理队列中累积的事件,把刚刚同步期间发生变化的部分再同步一次
问2:default.direct 、default.rsync、default.rsyncssh,这三种同步模式的核心区别
Lsyncd 提供的三种核心同步模式 default.direct、default.rsync 和 default.rsyncssh,本质区别在于底层传输机制、适用场景(本地/远程)以及对文件属性的保留能力。

如何选择?
- 仅本地同步:优先 default.direct(足够快且简单)或 default.rsync(需要完整属性保留时)。
- 局域网内远程同步(信任网络):用 default.rsync,省去加密开销,速度快。
- 跨互联网远程同步:必须用 default.rsyncssh,保证数据安全。
- 需要断点续传/带宽限制/校验和:任何情况都选 rsync 系列(rsync 或 rsyncssh),因为 direct 不支持这些特性。
性能

lsyncd -nodaemon /etc/lsyncd/lsyncd.conf.lua
数据解读:

top -o %MEM # 按内存百分比降序
top -o %CPU # 按 CPU 使用率降序

首次全量同步后,cpu利用率就下来了
同时监控 lsyncd 和所有 rsync 进程
top -p (pgrep -x "lsyncd\|rsync" \| tr '\\n' ',' \| sed 's/,//')

没有数据传输时:
