而平躺的波浪名叫沙滩。
在潮汐的往返里,
愿你能时常回到自己腾出的那个角落,
看看那里积攒的微光。
毕竟,真正陪伴我们穿越漫长岁月的,
正是那个终于被自己深爱着的灵魂。
摘要:传统数据库主备容灾方案依赖守护进程、监视器和第三方仲裁组件,部署复杂、切换延迟大、运维成本高。达梦DM9推出的自治容灾集群DMAFC,将分布式数据库中成熟的Raft共识机制引入集中式数据库容灾领域,实现了"全自动驾驶"级别的故障自愈能力。本文从Raft协议原理、DMAFC架构设计、自治切换机制、两地三中心部署四个维度,深入解析这项创新技术的实现原理与应用价值。
在企业级数据库系统中,容灾高可用是保障业务连续性的最后一道防线。传统主备容灾方案(如Oracle ADG、达梦DMDataWatch)虽然成熟可靠,但始终面临三座大山:
第一座:组件依赖重
传统方案需要部署守护进程(dmwatcher)、监视器(dmmonitor)、MAL通信组件等多个额外模块,架构复杂度高,任何一个组件故障都可能影响切换成功率。
第二座:切换不可控
多备库场景下,主库故障时哪个备库接管、接管顺序如何,往往缺乏确定性。人工干预意味着RTO延长,自动切换又担心"脑裂"风险。
第三座:异地切换难
两地三中心场景下,跨地域网络延迟导致同步链路重建困难,异地切主后性能下降明显,操作复杂且风险高。
达梦DM9的破局思路是:把分布式数据库里成熟的Raft自动选举机制,搬到集中式数据库的容灾里,让容灾实现"全自动驾驶"。
DMAFC(DM Autonomous Failover Cluster)基于Raft一致性协议构建,其核心设计遵循"极简、自治、强一致"三大原则:
DMAFC采用奇数副本架构,集群由N个副本(节点实例)组成,N一般取3、5、7、9:
-- 查看DMAFC集群节点信息
SELECT INSTANCE_NAME, RAFT_SELF_ID, RAFT_STAT, SYS_MODE
FROM V$GLOBAL_RAFT_INFO;
-- 输出:
-- INSTANCE_NAME RAFT_SELF_ID RAFT_STAT SYS_MODE
-- CJC 1 LEADER PRIMARY
-- CJC01 2 FOLLOWER STANDBY
-- CJC02 3 FOLLOWER STANDBY
为什么必须是奇数?
Raft协议要求选举时遵循绝对多数原则(Majority)。三副本集群中,一个节点必须拿到至少2票才能当选主库。奇数副本确保:
| 副本数 | 最小多数 | 最大容错 | 说明 |
|---|---|---|---|
| 3 | 2 | 1 | 最低配置,成本友好 |
| 5 | 3 | 2 | 中等规模,平衡可靠与成本 |
| 7 | 4 | 3 | 大规模,高可靠场景 |
| 9 | 5 | 4 | 超大规模,金融核心 |
DMAFC的架构极为精简,核心组件只有两个:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 实例1 │ │ 实例2 │ │ 实例3 │
│ (LEADER) │◄───►│ (FOLLOWER) │◄───►│ (FOLLOWER) │
│ │XMAL │ │XMAL │ │
│ ┌─────────┐ │ │ ┌─────────┐ │ │ ┌─────────┐ │
│ │Raft状态机│ │ │ │Raft状态机│ │ │ │Raft状态机│ │
│ └─────────┘ │ │ └─────────┘ │ │ └─────────┘ │
└─────────────┘ └─────────────┘ └─────────────┘
Raft是一种为管理复制日志而设计的共识算法。它将一致性问题分解为三个相对独立的子问题:
Leader选举:当主库故障或网络分区时,集群自动选举新主库
日志复制:主库将所有写操作以日志形式复制到备库
安全性:通过任期(Term)和日志索引保证数据一致性
在DMAFC中,每个节点处于以下三种状态之一:
-- 查看节点Raft状态转换历史
SELECT INSTANCE_NAME, OLD_STAT, NEW_STAT, TERM_ID, CHANGE_TIME
FROM V$RAFT_SWITCH_INFO
ORDER BY CHANGE_TIME DESC;
-- 输出:
-- INSTANCE_NAME OLD_STAT NEW_STAT TERM_ID CHANGE_TIME
-- CJC LEADER FOLLOWER 8 2024-09-07 20:17:35
-- CJC01 FOLLOWER LEADER 8 2024-09-07 20:17:38
三种状态:
任期(Term):单调递增的整数,每次选举开启新任期。任期是Raft的"逻辑时钟",确保旧Leader不会干扰新Leader。
当Follower在选举超时(Election Timeout)内未收到Leader心跳时,触发选举:
1. Follower超时 → 转为Candidate,Term+1
2. Candidate向所有节点发送RequestVote RPC
3. 节点投票规则:
- 每个Term只能投一票
- 优先投给日志更完整的节点
4. 获得多数票 → 成为新Leader
5. 新Leader立即发送心跳,抑制其他选举
-- 查看选举统计
SELECT TERM_ID, ELECT_WINNER, VOTE_CNT, TOTAL_NODE, ELECT_DURATION_MS
FROM V$RAFT_ELECTION_HISTORY;
-- 输出:
-- TERM_ID ELECT_WINNER VOTE_CNT TOTAL_NODE ELECT_DURATION_MS
-- 8 CJC01 2 3 3200
Leader将写操作序列化为日志条目,通过AppendEntries RPC异步复制到Follower:
-- 查看日志复制状态
SELECT INSTANCE_NAME, LOG_SEQ, APPLIED_SEQ, LAG_SEQ, REPL_STATUS
FROM V$RAFT_LOG_REPLICATION;
-- 输出:
-- INSTANCE_NAME LOG_SEQ APPLIED_SEQ LAG_SEQ REPL_STATUS
-- CJC 3397 3397 0 SYNCED
-- CJC01 3397 3397 0 SYNCED
-- CJC02 3397 3396 1 SYNCING
复制流程:
DMAFC通过Raft心跳机制实现故障检测,无需额外探活组件:
-- 查看心跳配置
SELECT PARAM_NAME, PARAM_VALUE, DESCRIPTION
FROM V$RAFT_PARAMETERS;
-- 输出:
-- PARAM_NAME PARAM_VALUE DESCRIPTION
-- RAFT_HB_INTERVAL 150 Leader心跳间隔(ms)
-- RAFT_VOTE_INTERVAL 3000 选举超时时间(ms)
-- XMAL_HB_INTERVAL 5 XMAL心跳间隔(s)
Leader以150ms间隔发送心跳。Follower超过3000ms未收到心跳,即判定Leader故障,触发选举。
以三副本集群为例,展示主库故障后的完整切换过程:
时间点 事件
T+0ms Leader(CJC)故障宕机
T+150ms Follower(CJC01、CJC02)未收到心跳
T+3000ms CJC01选举超时,转为Candidate,Term=8
T+3002ms CJC01向CJC02发送RequestVote
T+3003ms CJC02投票给CJC01(日志更完整)
T+3005ms CJC01获得2票(多数),成为新Leader
T+3008ms CJC01发送心跳,确认领导地位
T+3010ms 业务恢复,新Leader接管读写
总切换时间约3秒,远快于传统方案的分钟级切换。
Raft协议天然防止脑裂(Split-Brain):
-- 模拟网络分区场景
-- 原Leader CJC与CJC01、CJC02网络隔离
-- CJC侧(少数派):
-- CJC继续作为Leader,但无法获得多数确认
-- 写操作无法提交,自动降级为只读
-- CJC01/CJC02侧(多数派):
-- 选举超时后选出新Leader CJC01
-- 正常提供读写服务
-- 网络恢复后:
-- CJC发现自己的Term落后,自动转为Follower
-- 从新Leader同步缺失日志,数据一致性自动修复
关键机制:任何写操作必须获得多数节点确认才能提交,网络分区时少数派自动拒绝写入,从根本上杜绝双主问题。
DMAFC原生支持两地三中心部署,无需额外配置:
-- 配置异地节点关闭选举开关
-- 异地中心C的节点不参与Leader选举,避免跨地域延迟影响
ALTER SYSTEM SET RAFT_ELECTION_ENABLE = 0 INSTANCE 'CJC02';
-- 查看各节点选举权限
SELECT INSTANCE_NAME, RAFT_ELECTION_ENABLE, DATA_CENTER
FROM V$RAFT_NODE_CONFIG;
-- 输出:
-- INSTANCE_NAME RAFT_ELECTION_ENABLE DATA_CENTER
-- CJC 1 CENTER_A
-- CJC01 1 CENTER_B
-- CJC02 0 CENTER_C
设计逻辑:
| 指标 | 能力值 | 说明 |
|---|---|---|
| RPO | 0 | 同步复制,数据零丢失 |
| 同城RTO | < 8秒 | 同城节点故障切换 |
| 异地RTO | < 30秒 | 异地节点故障接管 |
| 故障容忍 | (N-1)/2 | 3副本容1个节点,5副本容2个 |
| 数据一致性 | 强一致 | Raft协议保证 |
DMAFC支持部署"影子副本"——仅写日志、不重演数据的特殊副本:
-- 创建影子副本节点
ALTER SYSTEM ADD RAFT NODE 'CJC_SHADOW'
SHADOW_COPY = TRUE
ARCH_DEST_IP = '192.168.244.200'
ARCH_DEST_PORT = 61101;
-- 查看影子副本状态
SELECT INSTANCE_NAME, SHADOW_COPY, LOG_SEQ, STORAGE_USED_MB
FROM V$RAFT_NODE_INFO;
-- 输出:
-- INSTANCE_NAME SHADOW_COPY LOG_SEQ STORAGE_USED_MB
-- CJC_SHADOW TRUE 3397 128
-- CJC FALSE 3397 51200
-- CJC01 FALSE 3397 51200
影子副本特点:
DMAFC并非取代DMDataWatch,而是并存互补:
| 对比维度 | DMAFC | DMDataWatch |
|---|---|---|
| 核心协议 | Raft共识 | 主备同步 |
| 组件依赖 | 无额外组件 | dmwatcher + dmmonitor |
| 切换方式 | 自动选举 | 监视器切换/自动切换 |
| RPO | 0(强一致) | 0~秒级(取决于模式) |
| RTO | 秒级 | 秒级~分钟级 |
| 扩展性 | 最多9副本 | 1主8备 |
| 读写分离 | 不支持 | 支持 |
| 适用场景 | 强一致容灾、两地三中心 | 读写分离、常规容灾 |
选型建议:
# dmarch.ini 配置示例(节点1)
XMAL_HB_INTERVAL = 5
RAFT_HB_INTERVAL = 150
RAFT_VOTE_INTERVAL = 3000
XMAL_IP = 192.168.244.159
XMAL_PORT = 61101
RAFT_SELF_ID = 1
[ARCHIVE_RAFT1]
ARCH_TYPE = RAFT
ARCH_DEST = CJC01
ARCH_DEST_IP = 192.168.244.158
ARCH_DEST_PORT = 61101
ARCH_DEST_ID = 2
[ARCHIVE_RAFT2]
ARCH_TYPE = RAFT
ARCH_DEST = CJC02
ARCH_DEST_IP = 192.168.244.170
ARCH_DEST_PORT = 61101
ARCH_DEST_ID = 3
-- 查看集群整体健康度
SELECT CLUSTER_NAME, HEALTH_SCORE, LEADER_NODE, ACTIVE_NODES
FROM V$RAFT_CLUSTER_HEALTH;
-- 输出:
-- CLUSTER_NAME HEALTH_SCORE LEADER_NODE ACTIVE_NODES
-- AFC_CLUSTER 100 CJC 3/3
-- 查看复制延迟告警
SELECT INSTANCE_NAME, LAG_SEQ, LAG_MS, ALERT_LEVEL
FROM V$RAFT_REPL_LAG
WHERE LAG_SEQ > 10;
达梦DM9的DMAFC自治容灾集群,通过将Raft共识机制引入集中式数据库容灾领域,实现了三大突破:
DMAFC与DMDataWatch的并存互补,体现了达梦"两条腿走路"的产品策略——无论强一致自治容灾还是读写分离主备容灾,用户都能找到最优解。
随着国产数据库在金融、电信、能源等关键行业的深入应用,DMAFC的"全自动驾驶"能力将成为核心系统高可用的标配方案。
作者注:本文基于达梦DM9公开技术资料、官方部署指南以及Raft共识算法原理论述撰写,深入解析了DMAFC自治容灾集群的设计原理和实现机制。文中配置示例基于DM9语法,实际部署时请参考官方最新文档。
标签:#达梦数据库 #达梦同行者征文 #DM9 #DMAFC #Raft #自治容灾 #高可用
欢迎 👍点赞✍评论⭐收藏,欢迎指正
文章
阅读量
获赞
