前言

最近公司做双活, 一套应用部署在异地的两个机房, 其中, 存放归档文件的 nas 也是两套, 两套 nas 需要双向同步.

如果是 单向数据同步 的话, 有两种方法:

  • 方法 1: 可以采用 inotify + rsync 实现. 实现示例
  • 方法 2: 也可以用 lsyncd 实现, lsyncd 封装了 inotify + rsync, 本质上和 方法1 一样.

rsync 是专门做单向同步(从源同步到目标)的, 但是不具备 冲突检测 和 变更协调的能力, 因此不能做 双向数据同步. 经过一番搜索, 我找到一个可以 实现双向数据同步的工具 — Syncthing.

Syncthing 是一个开源的 文件同步工具。它能在两台或多台计算机之间实时同步文件,并安全地防止他人窥探。

这篇文章介绍一下 Syncthing 的使用.

介绍

Syncthing 中有两个术语: (device)设备文件夹(folder).

设备 就是安装了 Syncthing 程序的计算机, 设备 分为:

  • 本地设备(local device)
  • 远程设备(remote device)

Syncthing 会给每个 设备 分配一个 设备ID, 我们可以把 本地设备 和 远程设备 通过 设备ID 建立双向连接.

每个设备上可以配置多个 文件夹, 每个文件夹有一个 文件夹ID. 把 一个文件夹 在 两个设备 之间分享, 就能实现 文件夹 下的 文件 实时双向数据同步. 当然, 也可以在多个设备之间分享同一个文件夹.


Syncthing 默认采用 P2P(peer-to-peer 点对点) 的方式同步, 如果 P2P 无法直连, 会自动使用 Syncthing 的中继服务器(relay server) 转发.

Syncthing GUI 首页非常简洁:

Syncthing主页

Syncthing: 我的上海设备截图

作用是把 上海服务器上的 /data 目录 和 本地电脑(/Users/chenxing/data) 以及 杭州服务器(/backup) 做同步.
举例来说, 如果 在 上海服务器的 /data 下添加一个 文件, 会立刻同步到 本地电脑 和 杭州服务器(可能有几秒延迟, 取决于配置和网速); 在 本地电脑 的 /Users/chenxing/data 下添加一个 文件, 也会立刻同步到其他两个设备.

本地电脑 设备 GUI:
本地电脑gui

安装和运行

安装

前往 官网下载页面 下载, Linux, Windows, macOS 都支持.
我用的是 Linux 版本, 下载后是一个 syncthing-linux-amd64-v2.0.3.tar.gz 压缩文件, 安装:

tar -zxvf syncthing-linux-amd64-v2.0.3.tar.gz
cd syncthing-linux-amd64-v2.0.3
sudo cp syncthing /usr/local/bin/

运行

方式1: 简单运行

syncthing
# 完整写法
syncthing serve

方式2: 通过 nohup 放在后台运行

nohup syncthing --no-browser --log-file=/var/log/syncthing/sync.log --log-max-size=10485760 --log-max-old-files=5 2>&1 > /dev/null &

方式3: 作为 系统服务(systemd) 运行

sudo vim /etc/systemd/system/syncthing.service

内容示例:

[Unit]
Description=Syncthing Service
After=network.target

[Service]
ExecStart=syncthing --no-browser --log-file=/var/log/syncthing/sync.log --log-max-size=10485760 --log-max-old-files=5
Restart=on-failure
User=your-user-name
WorkingDirectory=/home/your-user-name

[Install]
WantedBy=multi-user.target

重新加载并启用:

sudo systemctl daemon-reload
# 开机自启
sudo systemctl enable syncthing
sudo systemctl start syncthing

查看状态或日志:

systemctl status syncthing
journalctl -u syncthing -f

配置

登录远程设备(命令行 或 GUI) 查看 设备ID.

命令行:

syncthing cli show system | grep "myID"

GUI(默认是 http://127.0.0.1:8384/) 上点击 “Actions” -> “Show ID” 查看.

备注:
syncthing 命令支持多个层级的子命令, 可以用 -h 选项查看每一个/层命令的用法.
GUI 支持的操作, 命令行都可以做.

本地设备配置

登录本地设备(命令行 或 GUI), 按照以下步骤:

  1. 添加远程设备, 输入远程设备ID, 会给 远程设备发送 设备连接请求
  2. 添加文件夹, 配置需要共享的目录
  3. 共享文件夹(添加/编辑文件夹时), 会给 远程设备发送 文件夹共享请求

远程设备配置

登录远程设备(命令行 或 GUI), 按照以下步骤:

  1. 接受设备连接请求
  2. 接受文件夹共享请求, 配置一个目录接收同步的文件

高级配置

高级配置包括了 Syncthing 的一切配置(GUI 配置, 设备, 文件夹, 各种开关等).

GUI 上打开 “Actions” -> “Advanced” 可以看到 高级配置 页面.

也可以在 命令行 中打开配置文件:

vim ~/.local/state/syncthing/config.xml

一些常见配置:
gui 配置:

<gui enabled="true" tls="false" sendBasicAuthPrompt="false">
    <!-- 可以把 `127.0.0.1` 改成 `0.0.0.0` 以允许通过其他 ip 访问.  -->
    <address>127.0.0.1:8384</address>
    <!-- ... -->
</gui>

options 配置:

<options>
    <!-- 是否通过 Syncthing 官方全局发现服务器(Global Discovery Server) 实现 跨网络设备发现 -->
    <globalAnnounceEnabled>true</globalAnnounceEnabled>
    <!-- 是控制设备在 P2P 直连失败时,是否通过 Syncthing 中继服务器(Relay Server)转发数据 -->
    <relaysEnabled>true</relaysEnabled>
    <!-- 设置为 0 表示 禁用 Syncthing 软件本身的自动版本升级 -->
    <autoUpgradeIntervalH>0</autoUpgradeIntervalH>
    <!-- ... -->
</options>

上面只是举几个例子, 全量的设置请参考 Syncthing Configuration.