冗余功能说明与常见问题
DarraRT 为高可用工厂场景提供三层冗余能力。本页分两部分:
- Part A — 冗余功能说明: 讲清楚 DarraRT 支持哪些冗余、怎么搭
- Part B — 常见问题 Q&A: 现场最常被问的运维问题
Part A — 冗余功能说明
支持的三种冗余
| 层级 | 冗余类型 | 应用场景 | 切换速度 |
|---|---|---|---|
| 控制器级 | 主机冗余 (1+1 / 1+N) | PLC 主控整体宕机容错 | 心跳丢失 <300ms |
| 网络级 | EtherCAT 电缆冗余 (Ring) | 总线断线自动切备用路径 | <100μs, 不丢包 |
| I/O 级 | I/O 冗余 (模块级) | 关键 I/O 单点故障容错 | 投票 FB 周期 |
三种可同时启用, 也可单独使用。大多数项目只需要主机冗余 + 环网冗余。
架构概览
组件职责
| 组件 | 主机 | 备机 | 职责 |
|---|---|---|---|
| DarraRT_PLC.sys | 扫描+输出 | 只扫描不输出 | 运行 PLC 程序 |
| DarraRT_Eth.sys | 主动收发 | 被动监听 | EtherCAT 通讯 |
| Service | Active | Standby | 状态协调 + 授权 |
| 同步链路 | 周期发送 RETAIN 快照 | 周期接收并应用 | 保证切换时变量一致 |
主机冗余 (1+1 热备)
心跳机制
┌─────────────┐ ┌─────────────┐
│ Primary │ ─── Heartbeat @10Hz ───► │ Standby │
│ (Active) │ ◄── ACK @10Hz ────────── │ (Standby) │
└─────────────┘ └─────────────┘
T = 100 ms
- 发送周期: 默认 10 Hz (100 ms), 可配 5-50 Hz
- 判定宕机: 连续 3 次无响应 → 300 ms 触发切换
- 切换阈值: 可在 IDE 冗余配置中调 (1-10 次)
状态同步内容
| 类型 | 同步周期 | 典型大小 | 说明 |
|---|---|---|---|
| RETAIN 变量 | 1 ms | 4-64 KB | 保留变量, 断电也保留 |
| PERSISTENT 变量 | 100 ms | 1-16 KB | 持久变量, 不会被 PLC 程序复位 |
| DB 块快照 | 10 ms | 16-256 KB | 用户定义的 DataBlock |
| 定时器/计数器状态 | 1 ms | <1 KB | TON/CTU 的内部计数 |
同步延迟目标: <50ms (10G 直连网卡可做到 <5ms)。
切换触发方式
| 触发 | 判定依据 | 切换延迟 |
|---|---|---|
| 心跳丢失 | 连续 3 次无响应 | 300 ms |
| 主机 WDT 超时 | 主机看门狗未喂狗 | 硬件看门狗 1-5 s |
| 主机进程退出 | Service 进程异常退出 | <100ms |
| 主动切换 | 工程师手动触发 (维护前) | <50ms |
| 投票仲裁 | 3 节点集群中 2 票同意 | 仲裁一轮 (500 ms) |
脑裂处理 (Split-Brain)
"脑裂"指同步链路断开但两台 PLC 都正常, 导致两台都认为自己是主机, 同时输出造成现场危险。
方案一: 仲裁盘 (Quorum Disk)
Primary PLC ──┐
├──► [共享存储, SAN/NFS]
Standby PLC ──┘ └── 只有拿锁的才允许输出
- 共享一块 SAN / NFS 磁盘, 用 SCSI-3 Persistent Reservation 或文件锁
- 两台 PLC 启动时竞争锁, 拿到锁的才允许对 EtherCAT 输出
- 同步链路断 → 备机发现拿不到锁 → 主动降级为 Standby, 不切换
方案二: 第三方 Witness 节点
Primary PLC ─┐
│ ┌── Witness 节点
Standby PLC ─┤──────────────────┤ (小机/NAS/云服务器)
│ └── 仲裁投票
- 第三台廉价设备做见证者, 主备机通过不同路径都能 ping 通 Witness
- 主备机 + Witness 共 3 票, 多数派 (2 票) 决定谁做主
- 同步链路断但双方都能连 Witness → 原主机继续做主, 备机保持 Standby
方案三: 最后一次成功时间戳 (简单但不严谨)
比较双方最后一次"成功写 EtherCAT"的时间, 较新者做主。仅适合非安全关键场景。
EtherCAT 电缆冗余 (环网)
原理
正常情况帧从 LAN2 出, 依次穿过所有从站, 从最后一个从站回到 LAN3 (此口叫 Redundancy Port)。
主站 LAN2 ──→ S0 ──→ S1 ──→ S2 ──→ S3
╲
╲ LAN3
主站 LAN3 ←─────────────────────────────╱
任意一根电缆断开:
╳断点
主站 LAN2 ──→ S0 ──→ S1 S2 ──→ S3
╲
╲ LAN3
主站 LAN3 ←───────────────── S2 ←──────╱
- LAN2 继续驱动 S0, S1 (前半段, 从站内部 Loop Close)
- LAN3 反向驱动 S3, S2 (后半段)
- 所有从站照常响应
- 切换时间
<100μs(一个总线周期内完成) - 不丢包: 主站发现 WKC 下降时帧已由反向补齐
前提
- 主站 PC 必须有两个 Intel NIC (LAN2 + LAN3)
- 从站支持 EtherCAT 冗余 (绝大多数现代 ESC 都支持)
- 物理拓扑首尾相连形成闭环
不支持的拓扑
| 拓扑 | 支持? | 原因 |
|---|---|---|
| 菊花链 (开环) | 否 | 最后一个从站后无回路 |
| 星型分支 (EK1122 分支) | 部分 | 分支点故障仍影响下游 |
| 双层环网 | 否 | DarraRT 主站只支持单环 |
I/O 冗余 (模块级)
关键 I/O 单点故障容错方案: 同一信号挂两个 I/O 站, 用冗余 FB 做投票或热切。
传感器 ──┬── IO Station A (主)
└── IO Station B (备)
│
┌─────┴─────┐
│ Redund FB │ → PLC 内部变量
└───────────┘
2oo2 / 2oo3 投票
| 模式 | 输入处理 | 输出处理 |
|---|---|---|
| 1oo2 (热备) | 优先主站, 主站故障切备站 | 两站都写, 以主站为准 |
| 2oo2 (一致) | 两站数据必须相同, 否则报错 | 两站同步输出, 不一致报警 |
| 2oo3 (多数) | 三站多数票决定 | 三站同步输出, 少数服从多数 |
I/O 冗余需要在工程配置中指定冗余对, 并引用 RedundSignal_* 功能块。
Service 冗余 (单机多实例)
次要场景: 单台机器上运行多个 Service 实例做负载均衡, 不涉及物理冗余, 仅为避免单进程崩溃。
| 实例 | 角色 |
|---|---|
| Service_A | HMI + OPC UA |
| Service_B | Modbus + MQTT |
| Service_C | SDK/REST API |
通过共享 GlobalIO Section 互通数据。某个实例崩溃不影响其他。此模式下没有硬件冗余, 不适合主控制回路。
硬件要求
| 项 | 主机冗余最低 | 推荐 |
|---|---|---|
| 主备机型号 | 尽量一致 | 完全一致 (CPU/内存/网卡) |
| 电源 | 各自独立 220V | 各配独立 UPS |
| 同步链路网卡 | 千兆 | 10G SFP+ 直连 |
| 同步网线长度 | <10m | <3m 直连 |
| EtherCAT NIC | 单卡足够 | 每机两卡做环网 |
| 仲裁盘 (可选) | iSCSI 小容量 | 双控 SAN |
配置流程 (简述)
- 两台机器完全相同地安装 DarraRT 与同版本程序
- 各自配置独立管理 IP (如 192.168.0.10 和 192.168.0.11)
- 同步链路: 另一对网卡直连, 配点对点 IP (如 10.10.10.1 / 10.10.10.2)
- 在 IDE → 「冗余配置」中:
- 设主机标识 (Primary/Standby)
- 填对端同步链路 IP
- 选择仲裁方式 (无 / 仲裁盘 / Witness)
- 两台都点"启用冗余" → 主机进入 Active, 备机进入 Standby
- 测试手动切换一次, 观察输出是否抖动
详细向导见 冗余设置向导。
Part B — 常见问题 Q&A
Q1: 主机切换后备机输出是否会抖一下
A: 状态同步到位的情况下不抖。
关键条件: 同步延迟 < 一个扫描周期 (典型 1 ms)。满足时, 备机接管瞬间输出值与主机停机前完全一致, EtherCAT 从站察觉不到主站换人。
如果抖动, 排查:
| 症状 | 原因 |
|---|---|
| 阶跃 (输出跳变) | RETAIN 同步延迟 >1ms, 缩小同步包或换 10G 网卡 |
| 短暂死区 | 切换判定时间过长, 调小心跳阈值 |
| 周期性抖动 | 同步链路被其他流量占用, 改用专用直连 |
Q2: 脑裂怎么办, 两台都认为自己是主
A: 三种防护, 按工程重要性选一:
| 方案 | 成本 | 可靠性 |
|---|---|---|
| 仲裁盘 (SAN Persistent Reservation) | 中 | 高 |
| Witness 节点 (小机/NAS) | 低 | 中高 |
| 最后活跃时间戳 | 零 | 低 (不建议安全相关) |
在 IDE 冗余配置中选定仲裁方式, 系统会在检测到脑裂 (同步链路断但对方在线) 时按规则让一方自行降级。
安全关键场景必须用仲裁盘, 并配合现场硬联锁 (急停回路独立于 PLC)。
Q3: 主备同步用多大带宽
A: 取决于 RETAIN / PERSISTENT / DB 块总大小, 经验值:
| 同步变量总量 | 1 ms 周期带宽 | 推荐链路 |
|---|---|---|
<4 KB | <2 Mbps | 千兆即可 |
| 4-16 KB | 2-10 Mbps | 千兆即可 |
| 16-64 KB | 10-40 Mbps | 千兆接近上限 |
| 64-256 KB | 40-200 Mbps | 10G 必须 |
>256 KB | >200 Mbps | 建议按模块拆分, 减小同步量 |
减少同步量的办法:
- 把计算缓存类变量标记为普通 VAR (不同步)
- 只把切换后必须一致的状态标为 RETAIN
- 大数组分段同步 (增量同步, IDE 配置)
Q4: EtherCAT 环网断线后能自动切吗
A: 能。
- Ring 模式下, 任何位置断线, 主站在一个总线周期内发现 WKC 异常
- 主站立即从 LAN3 反向推帧, 两段合并扫描所有从站
- 典型切换
<100μs, 用户程序感知不到丢包 - 被切的从站会在
DiagData中报告"检测到回环闭合", 用于运维排查断点位置
注意: 只支持一次断点。如果环网上同时两处断开, 主站无法穿过任一段, 该段从站丢失通讯。
Q5: 冗余切换时 HMI 是否感知
A: 感知。
事件通知
HMI (JavaScript SDK) 可订阅切换事件:
darra.on('redundancy-switch', (evt) => {
console.log('角色变化:', evt.oldRole, '→', evt.newRole);
console.log('原因:', evt.reason); // heartbeat-lost / manual / wdt-timeout
console.log('切换耗时 ms:', evt.elapsedMs);
showBanner(`PLC ${evt.newMaster} 已接管`);
});
状态位
| 变量 | 类型 | 说明 |
|---|---|---|
SYS.Redund.Role | INT | 0=Disabled, 1=Active, 2=Standby |
SYS.Redund.Peer | BOOL | 对端是否在线 |
SYS.Redund.LastSwitchTime | DATETIME | 最近一次切换时间 |
SYS.Redund.SwitchCount | DWORD | 累计切换次数 |
HMI 可直接绑定这些系统变量做状态灯。
Q6: 备机升级固件时主机正常吗
A: 支持 Rolling Upgrade (滚动升级), 推荐步骤:
- 确认当前 Primary 在 A 机, Standby 在 B 机
- 先升级 B 机 (Standby): 停服务 → 升级 → 启服务 → 等待 Standby 重新同步
- 主动切换: A → Standby, B → Primary
- 确认业务正常运行
- 升级 A 机: 停服务 → 升级 → 启服务
- (可选) 再切换回来保持 A 为 Primary
升级期间全程有 Primary 在运行, 控制不中断。
两台版本不一致的窗口期不要超过几分钟。协议 ABI 不兼容的跨大版本升级 (如 v2.x → v3.x) 必须停机同时升级, 见升级指南。
Q7: 如何测试冗余, 生产前验证清单
A: 以下 12 项, 每项都需要观察切换时间、输出抖动、HMI 报警三个维度。
| # | 测试项 | 预期 |
|---|---|---|
| 1 | 手动在 IDE 点"主动切换" | <50ms, 无抖动 |
| 2 | 拔主机电源线 | 300-500ms 切换, 备机接管 |
| 3 | 拔主机 EtherCAT 主线 (LAN2) | 如有环网, 主机自愈; 无环网则切备机 |
| 4 | 拔主备机同步链路 | 触发脑裂保护, 按仲裁规则处理 |
| 5 | 关主机 Service 进程 (任务管理器 End Task) | <100ms 切换 |
| 6 | 主机 CPU 占满 (跑 prime95) | 心跳超时切换 |
| 7 | 主机内存满 (模拟泄漏) | 超过阈值后主动降级 |
| 8 | 主机磁盘满 (日志写不进) | 持久化失败报警, 不切换 |
| 9 | 拔环网一根电缆 | <100μs 切换, 不丢包 |
| 10 | 拔环网两根 (相邻) | 中间段从站失联, 其他正常 |
| 11 | 主机断电后恢复 | 原主机以 Standby 回归 |
| 12 | 24 小时稳态运行 | 无误切换, 同步延迟稳定 |
每项测试记录:
- 切换开始时间 (主机异常时刻)
- 切换结束时间 (备机输出接管时刻)
- 输出变量抖动幅度 (示波器实测)
- HMI 角色标识变化耗时
全部通过后才允许投产。
Q8: 冗余开启后授权是两台都要吗
A: 是的, 两台都需要相同版本的 Runtime 授权。
- 企业版有专门的"冗余对"定价, 按 1.8 倍单机价格买两台授权
- 主备切换后原主机若要作为 Standby 回归, 仍需自己授权有效
- 仲裁 Witness 节点不需要完整 Runtime 授权, 仅需 Witness 版 (免费或低价)
详见 授权许可。
Q9: 冗余对时延敏感, 是否需要专门的时间同步
A: 看场景。
| 场景 | 时间源 |
|---|---|
| 单纯冗余 (不涉及 EtherCAT DC) | 操作系统时钟即可 |
| 冗余 + EtherCAT DC 参考 | 主备都用同一个从站做 DC 参考, 切换时 DC 不重建 |
| 冗余 + 外部时钟源 (IRIG-B / PTP) | 两台都对同一 GrandMaster 同步 |
DC 参考源掉线时, DarraRT 会自动选次优从站, 切换期间可能有一次同步重建 (几毫秒), 不影响控制, 但日志会留记录, 运维需关注。
Q10: 备机能不能在不同物理位置 (异地容灾)
A: 不推荐, 原因:
- 同步链路延迟: 局域网
<1ms, 跨园区光纤<5ms, 跨城市10-50ms - 一个扫描周期 1 ms, 跨城市链路必然导致 RETAIN 同步滞后
- 脑裂检测不可靠 (中间链路不稳)
DarraRT 的主机冗余定位是同一控制柜内或同一机房内的高可用。
跨园区容灾请用不同控制回路实现 (上位机 MES 层统一协调), 不适合用 PLC 层冗余。
Q11: 冗余启动后日志量会增加多少
A: 默认级别 Info, 冗余功能大约增加:
| 项 | 每秒新增日志 | 每天 (86400s) |
|---|---|---|
| 心跳事件 | 1 条/s (汇总) | 86 KB |
| 同步统计 | 0.1 条/s | 8 KB |
| 切换事件 (正常 0 次) | 0 | 0 |
| Debug 级别 (诊断时) | 100 条/s | 大约 200 MB |
日志存在 %AppData%\DarraPLC\logs\service_*.log, 默认按天滚动, 保留 7 天。详见 常见问题 - 日志文件放哪。
Q12: 冗余切换会影响在线下载/在线更新吗
A: 会限制。
- 冗余启用期间, 在线下载必须先切到 Standby 做, 再切换、升级 Primary
- 不支持双机同时在线下载 (会触发同步校验不一致)
- 配方/参数修改可以在 Primary 上直接做, 通过 RETAIN 同步自动到 Standby
推荐流程:
Primary (A 运行) → 下载到 Standby (B) → 验证 → 切换 A↔B → 下载到原 Primary (A 现 Standby)