电科金仓同城双中心灾备:一次真实环境部署记录
目录
背景
去年我们接了一个城商行的核心账务系统改造项目,行方明确要求:
-
同城双中心,RPO=0
-
主中心挂掉,备中心必须在 1 分钟内接管
-
不能出现脑裂,也不能因为网络抖动误切换
-
对生产业务的性能影响要尽量小
之前他们用的是异步复制,主中心掉电就会丢几分钟的数据,这在金融系统里是不可接受的。我们评估后决定用 电科金仓的物理日志流复制 来做这个方案。

架构怎么搭
最终架构是 3+3+1:
-
生产中心:3 个节点(1 主 + 2 备)
-
同城灾备中心:3 个节点(1 同步备 + 2 异步备)
-
一个独立的仲裁节点(Witness),不存数据,只参与投票
这样有两个好处:
-
中心内部用本地高速网络同步,延迟低,RPO=0。
-
中心之间只有一条同步链路,不会因为跨中心网络抖动导致频繁切换。
拓扑大概是这样:

[生产中心]
Primary (R/W) <---sync---> Local Sync Standby
|
+---- async ----> Local Async Standby
跨中心链路(单条)
Primary ---sync---> 灾备中心 Sync Standby
[灾备中心]
Sync Standby <--- async ---> Async Standby1
--- async ---> Async Standby2
[仲裁节点]
Witness(独立服务器)
物理日志同步为什么快
很多人问,为什么不用逻辑复制?原因很简单:
逻辑复制要把 WAL 转成 SQL 再在备库执行,解析、排序、回放都耗 CPU,而且容易因为大事务卡住。
电科金仓的物理日志同步是直接把 WAL 块发过去,备库只要写盘、重放,不需要解析 SQL,性能能高出 10 倍左右。
在我们的压测里,64 并发 TPC-C 模式下,跨中心同步对主库的事务延迟只增加了不到 5%。

关键配置(实盘代码)
下面是我们在生产中心主库的 kingbase.conf里的部分配置(IP 和路径已脱敏):
listen_addresses = '*'
port = 54321
wal_level = replica
max_wal_senders = 10
max_replication_slots = 6
wal_keep_size = 1024
full_page_writes = on
synchronous_standby_names = 'ANY 1 (local_sync, dr_sync)'
synchronous_commit = on
hot_standby = on
wal_sender_timeout = 60000
archive_mode = on
archive_command = 'cp %p /kesdata/archive/%f'
sys_hba.conf里加上复制账号权限:
host replication repuser 192.168.10.0/24 md5
host replication repuser 192.168.20.0/24 md5
重载配置:
sys_ctl reload -D /kesdata/kingbase/data
备库初始化
在同城灾备中心的同步备库上,我们用 sys_basebackup拉基线:
su - kingbase
rm -rf /kesdata/kingbase/data/*
sys_basebackup \
-h 192.168.10.11 \
-U repuser \
-D /kesdata/kingbase/data \
-Fp -Xs -P -R \
--application-name=dr_sync
-R会自动生成 standby.signal和 primary_conninfo,省了很多手工活。
备库 kingbase.conf里要确认:
hot_standby = on
primary_conninfo = 'host=192.168.10.11 port=54321 user=repuser password=xxxx application_name=dr_sync'
启动:
sys_ctl start -D /kesdata/kingbase/data
验证同步状态
主库上执行:
SELECT pid, application_name, client_addr, state, sync_state
FROM pg_stat_replication;
看到 sync_state里有 sync,说明 RPO=0 链路已经生效。
自动切换是怎么跑的
电科金仓内置的 HA 模块会每 3 秒发一次心跳,如果连续 3 次没收到某个节点的响应,就认为它失联了。
仲裁节点和剩下的存活节点会投票,票数过半才会选新主,防止脑裂。
比如生产中心整体断电:
-
Witness + 灾备中心节点投票,达成 Quorum
-
灾备中心的同步备确认自己有最新的 WAL
-
自动执行
sys_ctl promote -
VIP 漂移到新主,应用重连(RTO 实测 38 秒)
应用侧怎么接
我们用的是官方 JDBC 驱动,支持自动寻主和读写分离:
String url = "jdbc:kingbase8://192.168.10.11:54321,192.168.20.11:54321/TELLER_DB?"
+ "USEDISPATCH=true"
+ "&SLAVE_ADD=192.168.10.12,192.168.10.13,192.168.20.12"
+ "&SLAVE_PORT=54321,54321,54321"
+ "&autoSwitch=true";
写请求固定走主库,读请求按权重分到备库。主库故障后,驱动会自动换到新主,业务基本无感知。
日常运维经验
- 延迟监控
SELECT application_name,
pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), received_lsn)) AS recv_lag,
pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn)) AS replay_lag
FROM pg_stat_replication;
-
演练流程
-
拔掉主中心主库网线
-
看 HA 日志,确认自动 promote
-
跑几笔真实交易,验证数据一致性
-
恢复主中心,检查自动加入集群
-
如有需要,手动 switchover 回原主
-
-
调优点
-
跨中心链路用万兆,RTT 最好 ≤ 5 ms
-
备库用 NVMe SSD,不然 WAL 回放容易成为瓶颈
-
Witness 节点一定要放在第三机房或独立网络位置
-
小结


这次改造后,行方的核心账务系统在多次演练中都做到了 RPO=0、RTO<60 秒,而且没有出现过脑裂。
物理日志同步的性能优势很明显,对业务几乎没有额外负担。
对我们来说,最大的收获是:架构简单、链路少、自动化程度高,这才是真正能在生产环境长期稳定运行的关键。
最后,电科金仓的技术支持响应速度也值得点赞,有一次我们凌晨3点遇到个疑难问题,电话打过去15分钟就拉群解决了。这种服务态度,至少让我们团队觉得选对了。

浙公网安备 33010602011771号