lsyncd(Live Syncing Daemon)是提供实时文件同步的机制之一,当inotify检测到文件变化时,通过rsync将文件传送到目标服务器。

使用场景

lsyncd适用于,源服务器的文件变化缓慢时的文件同步。当源服务器的文件变化达到临界点(这里是指文件容量的变化),会导致同步失败等。关于使用场景,参考下面的lsyncd官网。

类似lsyncd,在Linux上做同步时使用的有DRBD(Distributed Replicated Block Device),二者区别如下。

lsyncd DRBD
传送单位 文件单位 块(block)单位
同步对象 实际项目上最多同步到过16台服务器 一般是2台之间的同步,最多4台
难度 简单 复杂,需要重新配置文件系统并定义挂载点
主要用途 少量文件的同步 数据库集群

lsyncd是文件单位的传输,而DRBD是块传输,这需要花费大量时间和精力来构建,包括重建文件系统和定义挂载点。相比之下lsyncd的实现相对简单。

DRBD一般用于两台主机之间的同步,而lsyncd可用于多台主机之间的同步。如果需要同步到多台主机,应该优先考虑lsyncd。

“数据库同步使用DRBD、GlusterFS或BindFS等集群软件,少量文件同步使用lsyncd”原则。

接下来安装和配置lsyncd。

配置lsyncd和rsync

2台主机为Rocky Linux 9.3,dns001为源服务器,dns002为目标服务器。这次实验里搭建的环境如下。

rsync是通过网络与其他主机进行通信并传输文件和目录。Rocky Linux9.3默认已安装rsync,确认结果如下。

[root@dns001 ~]# rpm -q rsync
rsync-3.2.3-19.el9.x86_64

[root@dns002 ~]# rpm -q rsync
rsync-3.2.3-19.el9.x86_64

目标服务器

在目标服务器上创建同步专用的OS用户(用户名为rsync),这样从源服务器无需密码(使用秘钥)登录到目标服务器。

[root@dns002 ~]# useradd rsync

rsync用户创建成功后,切换到rsync用户。

[root@dns002 rsync]# su - rsync

在rsync用户的主目录下,创建 .ssh 目录。后面会将创建的秘钥对保存到该目录。

[rsync@dns002 ~]$ mkdir -m700 ~/.ssh

创建秘钥对,并保存至在上面创建的 rsync 用户的主目录下的 .ssh 目录。

[rsync@dns002 ~]$ ssh-keygen -t rsa -m PEM -f ~/.ssh/id_rsa
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/rsync/.ssh/id_rsa
Your public key has been saved in /home/rsync/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:v/wxmv2/usb8UoeFK8Hg3UrPHhPHIH2vPZ4+ko+frss rsync@dns002.sys-blog.local
The key's randomart image is:
+---[RSA 3072]----+
|             .   |
|          . . o .|
|         . + o =.|
|          . = + =|
|        S  . = O |
|         .  o Ooo|
|          . =o+o+|
|         . =.Xo+.|
|          =.+E#X+|
+----[SHA256]-----+

确认创建的的秘钥对,

  • id_rsa : 私钥
  • id_rsa.pub : 公钥
[rsync@dns002 ~]$ ll ~/.ssh/
total 8
-rw-------. 1 rsync rsync 2455 Jan 13 05:58 id_rsa
-rw-r--r--. 1 rsync rsync  581 Jan 13 05:58 id_rsa.pub

将秘钥对里的公钥保存到 authorized_keys 文件。当使用SSH的公钥认证时,使用SSH进行连接的用户的公钥需要添加至 authorized_keys 文件。

[rsync@dns002 ~]$ cat ~/.ssh/id_rsa.pub > ~/.ssh/authorized_keys

而把私钥保存至源服务器的root用户的 .ssh 目录下。后面在源服务器上配置lsyncd时指定该秘钥登录目标服务器。

[root@dns002 rsync]# scp /home/rsync/.ssh/id_rsa root@dns001:/root/.ssh/rsync_id_rsa

同步用的rsync用户没有系统管理员权限,可能会因为权限问题导致失败,因此给rsync用户赋予晋升为系统管理员的权限。

使用vi命令开始编辑 /etc/sudoers.d/rsync 文件,添加下面的内容。

Defaults:rsync !requiretty
rsync ALL= NOPASSWD:/usr/bin/rsync

源服务器

首先确认从源服务器传送过来的秘钥是否存在,并且确认秘钥的属性为600。

[root@dns001 ~]# ll /root/.ssh/
total 4
-rw-------. 1 root root 2455 Jan 13 06:04 rsync_id_rsa

确认使用该私钥是否能无密码登录源服务器。如下图,无密码登录源服务器,成功。

接下来需要在源服务器安装lsyncd软件包。因为RockyLinux的默认repository上没有lsyncd软件包,安装 epel-release reposiotry。

[root@dns001 ~]# dnf install epel-release -y

执行dnf命令安装lsyncd软件包,这时候也会安装lua软件包。因为lsyncd是lua语言封装了inotify和rsync工具。

[root@dns001 ~]# dnf install lsyncd -y

作为一个合格的系统工程师,在修改原文件之前,必须取一个备份。

[root@dns001 ~]# cp -p /etc/lsyncd.conf /etc/lsyncd.conf.$(date +%Y%m%d)
[root@dns001 ~]# ll /etc/lsyncd*
-rw-r--r--. 1 root root 286 Jun  7  2022 /etc/lsyncd.conf
-rw-r--r--. 1 root root 286 Jun  7  2022 /etc/lsyncd.conf.20240113

使用 vi /etc/lsyncd.conf 文件之后添加下面的内容。

settings {
   logfile = "/var/log/lsyncd/lsyncd.log",
   maxDelays = 1
}

sync {
    default.rsync,
    source="/var/www/sys-blog",
    target="rsync@dns002:/var/www/sys-blog",
    delay = 0,
    rsync = {
        rsync_path = "sudo /usr/bin/rsync",
        archive = true,
        compress = true,
        acls = true,
        verbose = true,
        owner = true,
        group = true,
        perms = true,
        rsh = "/usr/bin/ssh -p 22 -i /root/.ssh/rsync_id_rsa -o StrictHostKeyChecking=no"
    }
}

lsyncd的配置完成之后,启动服务。

[root@dns001 ~]# systemctl restart lsyncd

确认同步状态

在源服务器创建1GB的文件之后,确认同步到目标服务器的状态。

源服务器上执行下面的命令创建1GB的文件。

dd if=/dev/zero of=/var/www/sys-blog/demo.$(date +%Y%m%d%H%M) bs=1M count=1024

执行后的如下,创建了1GB的测试同步的文件。

在目标服务器上确认同步的状态。文件大小为1,073,741,824字节的文件已同步至目标服务器。

因为是在VMware上的2台主机之间的实验,所以传送速度没的说(快)。

手动同步文件

lsyncd是检测到文件变更时,实时的执行rsync的服务。rsync是用于同步命令的工具。rsync也可用于在同一主机上复制,但在大多数情况下,用于不同主机之间的文件传送。当主机之间的同步失败时,有时我们需要手动进行同步。这时候使用rsync命令,rsync的语法如下。

# rsync <option> <source_dir> <user>@<host>:<directory>
# rsync <option> <user>@<host>:<directory> <target_dir>

rsync常用选项如下。

选项 内容
-a 和选项 -rlptgoD 一样。详细解释请查看手册的说明,一般情况下添加 -a 选项。
-v 显示传送的文件一览
-e 可指定remote shell。例如 “ssh -p 3022″可改变ssh的端口,”ssh -i id_rsa”指定SSH登录时的秘钥。
–progress 显示文件传送进度。当需要传送的文件较多时,能帮助我们掌握传送进度
–exclude 指定不进行传送的文件(指定排除文件)
–exclude-from 指定一个配置文件,该文件定义了从传输中排除的文件列表。
–dry-run 与 -v选项 结合使用时,会显示将要传输的文件列表,但不会实际传送这些文件。特别是在生产环境实际传送之前,使用该选项进行确认是个好习惯

开始传送之前使用 –dry-run选项,确认传送文件名。

[root@dns001 ~]# rsync -av -e "ssh -p 22" -e "ssh -i /root/.ssh/rsync_id_rsa" \
--dry-run /var/www/sys-blog rsync@dns002:/var/www/sys-blog

从执行结果可以确认到,sys-blog/demo.202401130936 文件将会被传送。

确认传送的文件,正确之后去掉 –dry-run选项进行传送。

[root@dns001 ~]# rsync -av -e "ssh -p 22" -e "ssh -i /root/.ssh/rsync_id_rsa" \
/var/www/sys-blog rsync@dns002:/var/www/sys-blog

执行文件传送的结果如下。

介绍了在Rocky Linux上使用lsyncd和rsync进行目录同步的方法及手动进行文件传送的方法。