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字段说明:
| 行号 | 字段名 | 含义 |
|---|---|---|
| 1 | node | 当前持有执行权的节点名称 |
| 2 | timestamp | 最近一次心跳更新时间(毫秒时间戳) |
4. 工作流程
4.1 正常运行流程
当前节点启动定时任务后:
- 读取 SFTP 上的
ha.lock - 判断锁文件是否属于自己
- 判断时间戳是否过期
- 根据结果决定是否执行拉取任务
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.lock7. 超时机制
7.1 推荐参数
| 参数 | 推荐值 |
|---|---|
| 定时任务周期 | 30 秒 |
| 锁超时时间 | 90 秒 |
| 心跳更新时间 | 每次执行前 |
7.2 原则
必须满足:
text
timeout > interval * 2例如:
| interval | timeout |
|---|---|
| 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:
retry9. 异常处理
9.1 SFTP 不可用
处理:
- 不更新 timestamp
- 当前节点自动失效
- 其他节点接管
9.2 节点宕机
表现:
- timestamp 停止更新
结果:
- timeout 后自动切换
9.3 网络抖动
建议:
- timeout 设置大于 2~3 倍 interval
- 避免频繁切换
10. 总结
本方案通过:
- SFTP 共享锁文件
- 节点心跳
- 超时接管机制
实现了一个轻量级、高可用的 SFTP 文件拉取架构。
特点:
- 简单
- 易实现
- 易维护
- 适合大多数文件同步场景
核心原则:
text
只有持有有效锁的节点才能执行拉取任务。
锁过期后,其他节点自动接管。