Skip to content

SFTP 服务HA(High Availability)高可用性配置说明

1. 文档目的

本文档畅链数据集成平台SFTP服务轻量级高可用(HA)方案配置,用于保证多个节点部署同一服务时:

  • 任意时刻仅有一个节点执行文件拉取任务
  • 主节点异常后,其他节点能够自动接管
  • 无需额外引入 ZooKeeper、Redis、数据库等中间件
  • 通过 SFTP 服务器上的共享状态文件实现主节点选举

2. 系统背景

SFTP服务功能:

  • 定时连接 SFTP 服务器
  • 从远程目录拉取文件到本地
  • 多节点部署(Active-Standby 模式)

目标:

  • 避免多个节点同时拉取同一个文件
  • 支持节点异常自动切换
  • 保证任务持续运行

3. HA 设计原理

3.1 核心思想

在 SFTP 服务器上创建一个共享状态文件:

text
ha.lock

文件内容:

plaintext
node-1
1747135200000

字段说明:

行号字段名含义
1node当前持有执行权的节点名称
2timestamp最近一次心跳更新时间(毫秒时间戳)

4. 工作流程

4.1 正常运行流程

当前节点启动定时任务后:

  1. 读取 SFTP 上的 ha.lock
  2. 判断锁文件是否属于自己
  3. 判断时间戳是否过期
  4. 根据结果决定是否执行拉取任务

4.2 当前节点是主节点

满足条件:

text
lock.node == currentNode

并且:

text
currentTime - lock.timestamp < timeout

则:

  • 当前节点继续执行任务
  • 更新 timestamp
  • 执行文件拉取

4.3 当前节点不是主节点

若:

text
lock.node != currentNode

并且锁未过期:

text
currentTime - lock.timestamp < timeout

则:

  • 当前节点不执行拉取
  • 等待下一次调度

4.4 主节点失效

若:

text
currentTime - lock.timestamp >= timeout

表示:

  • 当前持有节点已经失效
  • 可能宕机
  • 或网络异常

此时:

  • 当前节点尝试抢占锁
  • 将自己的 node 写入 lock 文件
  • 更新时间戳
  • 成为新的主节点

5. HA 时序图

text
+----------------+
| node-1         |
+----------------+
        |
        | 读取 ha.lock
        |
        v
+------------------------------+
| node == node-1 ?             |
+------------------------------+
        |
       YES
        |
        v
+------------------------------+
| timestamp 是否过期 ?         |
+------------------------------+
        |
       NO
        |
        v
更新 timestamp
执行 SFTP 拉取

------------------------------------------------

+----------------+
| node-2         |
+----------------+
        |
        | 读取 ha.lock
        |
        v
发现:
node=node-1

timestamp 已过期

        |
        v
写入:
node=node-2

更新时间戳

        |
        v
成为新主节点
执行拉取

6. 锁文件格式

6.1 文件路径建议

text
<pull file folder>/ha/ha.lock

或:

text
~/chinlink/ha/sftp-puller.lock

7. 超时机制

7.1 推荐参数

参数推荐值
定时任务周期30 秒
锁超时时间90 秒
心跳更新时间每次执行前

7.2 原则

必须满足:

text
timeout > interval * 2

例如:

intervaltimeout
30 秒90 秒
60 秒180 秒

避免网络抖动导致误切换。


8. 节点抢占流程

8.1 抢占逻辑

当锁过期时:

当前节点执行:

text
1. 重新读取 lock 文件
2. 再次确认已过期
3. 写入自己的 node
4. 更新时间戳
5. flush
6. 开始执行任务

8.2 双节点竞争问题

可能存在:

text
node-2
node-3

同时发现锁过期。

风险:

  • 两个节点同时写 lock
  • 短时间双主

8.3 解决方案

采用:

CAS(Compare-And-Set)思想

写入前再次校验:

text
if oldTimestamp == currentTimestamp:
    allow overwrite
else:
    retry

9. 异常处理

9.1 SFTP 不可用

处理:

  • 不更新 timestamp
  • 当前节点自动失效
  • 其他节点接管

9.2 节点宕机

表现:

  • timestamp 停止更新

结果:

  • timeout 后自动切换

9.3 网络抖动

建议:

  • timeout 设置大于 2~3 倍 interval
  • 避免频繁切换

10. 总结

本方案通过:

  • SFTP 共享锁文件
  • 节点心跳
  • 超时接管机制

实现了一个轻量级、高可用的 SFTP 文件拉取架构。

特点:

  • 简单
  • 易实现
  • 易维护
  • 适合大多数文件同步场景

核心原则:

text
只有持有有效锁的节点才能执行拉取任务。
锁过期后,其他节点自动接管。