一、项目概述与架构设计

1.1 项目目标

网站产生的数据(用户上传的图片、附件、静态文件等)首先保存到存储服务器上,然后通过lsyncd 实时监控并同步这些数据到备份服务器,实现数据的实时备份保护。

1.2 整体架构

  Web 服务器    ──NFS──▶  存储服务器(NFS)  ──lsyncd─▶    备份服务器    
  (网站应用)      挂载       (nfs01)          实时同步      (backup)     

  • Web 服务器:运行网站应用,将用户上传的文件通过 NFS 挂载写入存储服务器
  • 存储服务器(nfs01):提供 NFS 共享服务,存放网站数据,同时运行 lsyncd 监控数据变化
  • 备份服务器(backup):接收从存储服务器实时同步过来的数据,作为备份

1.3 核心组件原理

NFS 是一种分布式文件系统协议,允许客户端通过网络挂载远程目录,像访问本地磁盘一样读写远程文件,底层依赖 RPC 机制进行通信。

lsyncd 实际上是 Lua 语言封装了 inotify 和 rsync 工具,采用 Linux 内核的 inotify 触发机制监控本地目录的变化,然后通过 rsync 进行差异同步,达到实时效果。

1.4 实验环境规划

假设我们有三台服务器,全部使用 CentOS 7 / Rocky Linux 8/9(兼容 RHEL 系列):

角色 主机名 IP地址 说明
存储服务器 nfs01 192.168.10.10 NFS服务端 + lsyncd源端
备份服务器 backup 192.168.10.20 rsync目标端 + SSH免密接收
Web服务器 web01 192.168.10.30 NFS客户端

注意:正式部署前,三台服务器需关闭 SELinux(setenforce 0)和防火墙(或正确放行端口),这是常见故障的根源。

二、环境准备

2.1 三台服务器基础配置

# 1. 关闭 SELinux(临时+永久)
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config

# 2. 关闭 firewalld(内网环境;生产环境建议配置规则而非关闭)
systemctl stop firewalld
systemctl disable firewalld

# 3. 配置时间同步(NFS 对时间敏感)
yum install -y chrony
systemctl start chronyd
systemctl enable chronyd

# 4. 配置 hosts 文件(三台都做)
cat >> /etc/hosts << EOF
192.168.10.10  nfs01
192.168.10.20  backup
192.168.10.30  web01
EOF

三、存储服务器(nfs01)配置

3.1 安装 NFS 服务

# CentOS/RHEL 安装
yum install -y nfs-utils rpcbind

# 启动 rpcbind(必须先于 nfs 启动)
systemctl start rpcbind
systemctl enable rpcbind

# 启动 nfs 服务
systemctl start nfs-server
systemctl enable nfs-server

3.2 创建共享目录

# 创建数据存储目录
mkdir -p /data/nfs_share

# 创建 www 用户(与 web 服务器的运行用户保持一致)
useradd -u 1000 -s /sbin/nologin www

# 修改目录属主为 www
chown -R www:www /data/nfs_share
chmod 755 /data/nfs_share

3.3 配置 NFS 导出规则

编辑 /etc/exports 文件:

# 语法:<共享目录> <允许访问的客户端>(权限选项)
/data/nfs_share 192.168.10.0/24(rw,sync,no_root_squash,all_squash,anonuid=1000,anongid=1000)

参数详解:

参数 说明
rw 读写权限
sync 同步写入,数据安全性高
no_root_squash 保留 root 权限(与下面的 all_squash 冲突,这里可选)
all_squash 将所有访问用户映射为匿名用户
anonuid=1000,anongid=1000 匿名用户映射为 www 用户的 UID/GID

生产环境中,Web 服务器通常以 www 用户运行,配置 all_squash + anonuid/anongid 可以统一权限管理。

3.4 生效配置并验证

# 重新加载 exports 配置
exportfs -r

# 查看已导出的共享
showmount -e localhost

# 预期输出:
# Export list for localhost:
# /data/nfs_share 192.168.10.0/24

四、Web 服务器(web01)配置

4.1 安装 NFS 客户端

yum install -y nfs-utils

# 创建 www 用户(UID 与存储服务器保持一致)
useradd -u 1000 -s /sbin/nologin www

4.2 挂载 NFS 共享

# 创建挂载点
mkdir -p /data/web_upload

# 手动挂载
mount -t nfs 192.168.10.10:/data/nfs_share /data/web_upload

# 查看挂载状态
df -h | grep nfs

4.3 配置开机自动挂载

编辑 /etc/fstab,添加:

192.168.10.10:/data/nfs_share  /data/web_upload  nfs  defaults,_netdev  0  0

_netdev 参数至关重要:它告诉系统等待网络就绪后再挂载,避免开机时因网络未连通导致挂载失败、系统启动卡住。

4.4 测试写入

# 切换到 www 用户测试
su - www -s /bin/bash -c "touch /data/web_upload/test_from_web.txt"
ls -la /data/web_upload/

五、备份服务器(backup)配置

5.1 安装 rsync

yum install -y rsync

5.2 创建备份目录

mkdir -p /data/backup
chown -R root:root /data/backup

5.3 配置 SSH 免密登录(关键步骤)

这一步让存储服务器(nfs01)可以免密 SSH 连接到备份服务器:

在 nfs01 上执行:

# 生成 SSH 密钥(一路回车)
ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa

# 将公钥复制到 backup 服务器
ssh-copy-id root@192.168.10.20

验证免密登录:

ssh root@192.168.10.20 "echo 'SSH connection successful'"

重要:lsyncd 的 rsyncssh 模式依赖 SSH 免密登录,如果没有配置或配置错误,同步会静默失败。

六、存储服务器(nfs01)部署 lsyncd

6.1 安装 lsyncd

# CentOS 7 需要先安装 EPEL 源
yum install -y epel-release
yum install -y lsyncd

# 验证安装
lsyncd --version

6.2 创建 lsyncd 配置文件

编辑 /etc/lsyncd.conf(使用 Lua 语法):

-- 全局设置
settings {
    logfile = "/var/log/lsyncd/lsyncd.log",      -- 日志文件
    statusFile = "/var/log/lsyncd/lsyncd.status", -- 状态文件
    statusInterval = 10,                          -- 状态刷新间隔(秒)
    maxProcesses = 1,                             -- 最大并发进程数
    insist = true,                                -- 出错后继续运行
    nodaemon = false                              -- 后台运行
}

-- 同步任务配置
sync {
    default.rsyncssh,                             -- 使用 SSH 方式同步
    
    source = "/data/nfs_share",                   -- 监控的源目录
    host = "192.168.10.20",                       -- 目标主机 IP
    targetdir = "/data/backup",                   -- 目标目录
    
    -- 同步延迟(秒),累积多个事件后统一同步,避免频繁触发
    delay = 5,
    
    -- 排除不需要同步的文件
    exclude = {
        "*.tmp",
        "*.swp",
        "*.swx",
        ".git/",
        "*.log"
    },
    
    -- rsync 选项
    rsync = {
        binary = "/usr/bin/rsync",
        archive = true,                           -- 归档模式,保留文件属性
        compress = true,                          -- 传输时压缩
        verbose = true,                           -- 详细输出
        _extra = {
            "--delete",                           -- 删除目标端多余文件
            "--exclude=.git/"
        }
    },
    
    -- SSH 选项
    ssh = {
        port = 22,
        identityFile = "/root/.ssh/id_rsa"        -- 私钥路径
    }
}

配置要点说明:

参数 说明
default.rsyncssh 推荐使用 SSH 方式,加密传输更安全,且无需额外开放 rsync 端口
delay = 5 延迟 5 秒同步,让文件写完再批量处理,避免同步“半截文件”
maxProcesses = 1 限制并发进程,防止资源争抢
--delete 源端删除文件时目标端同步删除,保持两端一致

6.3 创建日志目录并启动

# 创建日志目录
mkdir -p /var/log/lsyncd

# 启动 lsyncd 服务
systemctl start lsyncd
systemctl enable lsyncd

# 查看服务状态
systemctl status lsyncd

6.4 验证同步

在 nfs01 上:

# 创建测试文件
cd /data/nfs_share
echo "hello world" > test_sync.txt
mkdir test_dir
echo "test file in dir" > test_dir/file.txt

等待 5-10 秒后,在 backup 上检查:

ls -la /data/backup/
cat /data/backup/test_sync.txt
ls -la /data/backup/test_dir/

如果看到文件同步过来了,说明项目部署成功。

七、常见故障排查手册

7.1 NFS 相关故障

故障 1:NFS 客户端挂载失败 mount.nfs: access denied

原因:NFS 服务端 exports 配置未生效,或客户端 IP 不在允许范围内。
# 服务端重新加载配置
解决:
exportfs -r

# 检查导出列表
showmount -e 192.168.10.10

故障 2:NFS 挂载后无法写入,提示 Permission denied

原因:权限映射问题,客户端用户的 UID/GID 与服务端不匹配。
解决:
# 方案一:服务端配置 all_squash + anonuid/anongid,统一映射
# 方案二:确保两端 www 用户的 UID 一致
id www  # 分别在两台服务器上执行,对比 UID

故障 3:开机挂载失败,系统启动卡住

原因:/etc/fstab 缺少 _netdev 参数。

解决:在 fstab 中添加 _netdev 参数。

7.2 lsyncd 相关故障

故障 4:lsyncd 启动后无同步,日志也没有报错

原因:配置只通过了语法校验,但不检查路径是否存在、权限是否足够、SSH 是否可达。lsyncd 会静默跳过失败的 sync 块。
解决:
# 1. 开启 Debug 日志
# 在 settings 块中添加:
log_level = "Debug"

# 2. 手动测试 rsync 连通性
rsync -avz -e ssh /data/nfs_share/ root@192.168.10.20:/data/backup/

# 3. 确保目标目录已存在(lsyncd 不会自动创建)
ssh root@192.168.10.20 "mkdir -p /data/backup"

# 4. 使用调试模式前台运行
lsyncd -nodaemon -log all /etc/lsyncd.conf

故障 5:lsyncd 只同步了目录结构,文件内容没有同步
原因:这是 lsyncd 的已知行为——初次启动时可能只同步目录结构。
解决:
# 先手动执行一次完整 rsync 同步
rsync -avz --delete /data/nfs_share/ root@192.168.10.20:/data/backup/

# 然后再启动 lsyncd 做增量实时同步
systemctl restart lsyncd

故障 6:inotify 事件丢失,同步延迟或漏同步

原因:Linux 系统默认的 inotify 监控上限(max_user_watches)太低,不足以支撑大量文件变化。
解决:
# 查看当前限制
cat /proc/sys/fs/inotify/max_user_watches

# 调高限制(建议至少 524288)
echo "fs.inotify.max_user_watches=524288" >> /etc/sysctl.conf
sysctl -p

故障 7:vim 编辑文件时产生 .swp 临时文件导致同步中断

原因:vim 的交换文件触发 inotify 事件,lsyncd 可能同步了不完整的临时文件。
解决:在 exclude 列表中排除 *.swp、*.swx、*.swm 等 vim 临时文件,同时设置合理的 delay 参数让文件写完再同步。

故障 8:systemd 启动 lsyncd 失败

原因:systemd 单元文件与新版本 lsyncd 参数不兼容。
解决:
# 检查 lsyncd 版本
lsyncd --version

# 修改 /usr/lib/systemd/system/lsyncd.service
# 将 ExecStart 中的 -pidfile 改为 --pidfile

7.3 综合排错思路

如果 nfs 服务端的 lsyncd 不能实时同步,按以下顺序排查:

  • 先手动测试 rsync:在 nfs 端直接执行 rsync 命令,看能否同步到 backup 端
  • 检查目录权限:目标端目录是否存在、权限是否正确
  • 检查 SSH 免密:能否免密登录,私钥路径是否正确
  • 检查 lsyncd 日志tail -f /var/log/lsyncd/lsyncd.log 观察是否有报错
  • 检查配置文件:源目录、目标 IP、目标路径是否写错

    八、总结

    这个项目完整串联了 NFS 网络存储 + lsyncd 实时同步 两大技术栈,核心要点回顾:

    环节 关键点
    NFS 服务端 exports 配置、权限映射、rpcbind 依赖
    NFS 客户端 fstab 挂载、_netdev 参数
    SSH 免密 密钥生成、公钥分发、权限验证
    lsyncd 配置 Lua 语法、delay 延迟、exclude 排除
    故障排查 日志优先、手动测试、权限检查

    Logo

    openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

    更多推荐