前言
干数据这行的,多少都被"同步"两个字坑过。
最常见的场景大概是这样:财务系统在Oracle里,订单在MySQL里,新业务上了金仓数据库,报表组还天天催着要数。怎么办,写脚本呗。定时导出、传文件、清洗、导入,一条链路一套脚本。头两年还能维护,等链路堆到十几条,已经没人说得清哪套脚本还活着、哪套早该进回收站了。
跑批的苦就更别提。所谓的"同步",其实是ETL批处理,凌晨业务一闲就开跑,天亮能跑完就算顺利。业务同事看到的永远是昨天的数。哪天夜里任务再挂一次,早上八点还没修利索,那个场面,懂的都懂。
压力最大的还得是迁移。老库换新库,存量几个TB,领导批的停机窗口就一个周末。导出导入的速度明摆着不够用,中途再出个岔子,回滚还是硬着头皮上?没人敢拍板。
这三件事表面不一样,病根是同一个:靠搬数据文件过日子。换个思路,文件不搬了,改搬数据库的变更日志,一大半问题就顺了。金仓数据库厂商电科金仓在这条路上有个专业产品,叫金仓异构数据同步软件Kingbase FlySync,圈子里一般喊它KFS。这篇就把它拆开聊聊,原理、能耐,还有落地时那些坑,都过一遍。
KFS是个啥
一句话,在不同数据平台之间干实时增量同步的软件。定位对标国外那款老牌同步工具,名字就不点了,做这行的都认识。
跑起来的环境里有三个角色。KFS源端,装在数据流出的那头,专职从数据库日志里抓变更。KFS目标端,装在数据流入那头,把变更一条条写进目标库。中间还有个KFSMC,Web版管理台,部署、监控、告警都在上面弄,一套KFSMC能同时带着多个源端和目标端。
顺带提醒个容易踩的点,KFS按物理实例算套数。A库B库往C库汇数据,就是两个源端一个目标端,三套。动手前先把这笔账算了,后面申请和部署都不抓瞎。
再交代下背景,免得有人觉得这东西没经过考验。KFS交付了5000多套,客户500多家,金融、电网、医疗、汽车行业的一批重量级单位都在用,属于被大项目反复锤过的,不是实验室玩具。
原理这块,其实不玄乎
KFS走的是增量日志解析这条路,整条链路就三步。
第一步,采集。源端直接读数据库的事务日志,Oracle那边叫Redo,金仓数据库这边叫WAL,把里面的增删改实时解析出来。这里有个关键细节,它只认已经提交的事务,回滚的没提交的一律不碰,脏数据进不来,资源也省。另外它是读日志,不是跑SQL去查数据,跟触发器方案、全表扫描方案完全两码事,生产库基本感觉不到它的存在。
第二步,落KUFL。KUFL全称Kingbase Unified Format Log,一份加密格式的中间文件。多这层图什么?各家数据库的日志格式差太远,中间兜个统一格式,异构的坎就平了。更重要的是数据先落盘再传,网络断了、目标端趴了,数据都稳稳躺在本地,恢复之后从断点接着走。断点续传数据不丢这话不是吹的。
第三步,加载。目标端从KUFL读变更,翻译成目标库自己的SQL去执行,回放严格照源端事务的提交顺序来,配上事务先后顺序检查、I/O顺序检查、日志全流程连续性检查三道关卡。能走JDBC的库都能当目标端,它数据源覆盖广,根子就在这。
链路整体长这样:源库日志→采集解析→KUFL文件→网络→目标端回放。两头解耦,中间断了能续。
光讲原理挺干,来点具体的。你在源端随手敲这么几行:
-- 建张新表,DDL也能同步CREATETABLEcrm_customer(id NUMBERPRIMARYKEY,name VARCHAR2(64),levelNUMBERDEFAULT1);-- 日常增改,实时流向目标端INSERTINTOcrm_customer(id,name)VALUES(1001,'张三');UPDATEcrm_customerSETlevel=3WHEREid=1001;-- 中途加个字段,目标端跟着改ALTERTABLEcrm_customerADD(phone VARCHAR2(20));建表、两条数据变更、加字段,几秒之内目标端按顺序全重演一遍。DML和DDL都跟得上,这是日志解析方案特别省心的地方。
能连哪些库,先看家底
选型第一件事永远是核对数据源清单,别的往后稍稍。KFS现在支持30多种,按类别归一下:
| 类别 | 源端(数据流出) | 目标端(数据流入) |
|---|---|---|
| 国外主流数据库 | Oracle、SQL Server、MySQL/MariaDB、DB2、Informix | Oracle、SQL Server、MySQL/MariaDB、DB2 |
| 国产数据库 | 金仓数据库KingbaseES、达梦、OceanBase、PolarDB、openGauss、Vastbase、Gbase8s、TDSQL、AntDB等 | 和源端基本一致,另支持Greenplum、Gbase8a这些分析型库 |
| 消息队列 | Kafka、RabbitMQ、RocketMQ | Kafka、RabbitMQ、RocketMQ、华为ROMA |
| 大数据/分析平台 | — | Hive、Hadoop、华为DWS、MRS数据湖、ClickHouse、ElasticSearch、MongoDB、星环ArgoDB |
| 其他 | 常见RDS云数据库 | SQL文件、ETL工具、StreamSets、FlinkCDC |
信创环境也全,鲲鹏、海光、飞腾、龙芯、申威到X86都有,操作系统麒麟、统信、欧拉、Windows、Linux、AIX都行。拓扑随意搭,一对一、一对多、多对一、级联、双向都支持。没想到的是,连网络隔离装置、单向光闸、防火墙这种环境都能穿,这本事后面讲案例你会看到多值钱。
数据类型没什么好操心的,字符数值日期不用提,大对象、无主键表、GIS空间数据都支持,序列、存储过程、视图、同义词、索引也都在覆盖范围里。
同步范围还能裁。不是所有表都值得搬,可以细到只同步某几个模式、某几张表、甚至某几个字段,正则一筛就行:
^crm_.*$ 只同步crm_开头的表 ^(t_|log_).* 临时表日志表这类,用排除规则跳过 sales\.\d{4}_.* sales模式下按年分表的那些表表一多就懂这功能多香了,几百张表的库,能砍掉一大半无用传输。
跟老ETL比一比
直接上表:
| 对比项 | 传统ETL批处理 | KFS实时同步 |
|---|---|---|
| 数据时效 | 小时到天级,业务永远看T+1 | 亚秒级,实测延时40毫秒 |
| 一致性 | 没有事务保证,窗口期容易错漏 | 按事务提交顺序回放,端到端一致 |
| 对生产库的影响 | 全表扫描拉数,CPU和I/O一顿猛冲 | 只读日志,某医院现场内存占用不到2GB |
| 带宽占用 | 全量来回搬 | 增量传输,4倍以上压缩,2M带宽就能跑容灾 |
| 数据校验 | 人工对账 | 内置比对加自动修复,不停机就能做 |
性能单独说两句。官方基准环境是X86、6核16G、SSD、千兆网,这套配置下Oracle源端解析118MB/s,目标端加载240MB/s往上,TPCC模型一天同步600GB还多,国外同类是460GB,差了三成。就算缩到1核2G的丐版配置,一天跑50GB也没问题。数字未必跟你家业务严丝合缝,量级摆在这,绝大多数场景够用。
实战:TB级迁移怎么做到不停机
这是KFS的看家本领。
动手前先把源库收拾利索。以Oracle为例,日志解析类工具有个绕不开的前提,归档和附加日志必须开:
SELECTlog_modeFROMv$database;-- 期望ARCHIVELOG,没开的话后面免谈ALTERDATABASEADDSUPPLEMENTAL LOGDATA;ALTERSYSTEM SWITCH LOGFILE;然后是迁移的编排,电科金仓固化成四步,工具分工很清楚:
第1步 KDMS 结构迁移 └ 表结构、索引、约束这些对象定义先过去 第2步 KDTS 全量迁移(SCN/LSN快照) └ 存量慢慢搬,业务照常跑 第3步 KFS 增量缓存(和第2步同时启动) └ 快照位点之后的Redo日志增量,先落在KFS本地 第4步 KFS 增量回放 └ 全量完成后加载增量,两端位点追平 └ 追平后暂停应用,JDBC改指新库,重启,收工SCN和LSN可以理解成日志流上的进度条刻度。这套流程的精髓在第2步第3步并行:全量爱跑多久跑多久,期间冒出来的新增量全被KFS截在本地,最后只追平一小段。停机窗口就从整个导出导入的时长,缩成了追平最后那段的时长,一般就是分钟级。
讲个真实项目。某直辖市一卡通,1.8亿用户,存量12.3TB,早高峰三小时涌进5900万笔交易,业务一秒不能停。最后12.3TB三天搬完,切换后每天500GB增量秒级同步,数据比对全程没停业务。还有一个超大型三甲医院的项目更重,8个院区加一个远郊医疗区,400多个系统,60TB起步的存量,做法是每个院区放KFS前置机就地采集,再统一汇聚进数仓,采集加转换的延时压在10秒以内。
对了,迁移还有个稳妥玩法叫双轨并行,不少人不知道。割接完先别急着让老库退休,让KFS把新库数据反向同步回去,两套并轨跑一阵子。新系统真不给力,随时切回去,数据一条不丢。等新库被验证得服服帖帖,老库再光荣退休。后悔药,说得就是它。
踩坑实录:没主键的表能把人逼疯
先泼盆冷水,日志同步不是万能的,它天生依赖主键或者唯一键来定位行。源端一条UPDATE,日志里记的是整行镜像,到目标端得还原成UPDATE … WHERE id = xxx。没主键的话,WHERE条件只能拿一堆列硬拼,拼不全,数据一重复,同步当场乱套。
某金融项目把这坑暴露得明明白白,5000多张表里1200多张没主键,入库效率被拖得没法看。现场的解法挺接地气,分类拆开:
含大对象的无主键表,或者日更删超过10万条的 → 筛出55张,走T+1定时同步,每天早上5:30跑 其余1100多张 → 照旧走实时链路 效果:实时链路延迟长期压在1秒以内 那55张表每天约70G变化量,5分钟跑完,速率约240MB/s我的体会是,工具给的是通解,落不落地看你裁不裁。上线前把无主键表和大对象表盘一遍,比上线之后救火舒服太多。
两边数据到底一不一样
同步跑通只是及格线,业务真正盯的是这个。
同步过程里先有三道检查兜着,事务顺序、I/O顺序、日志连续性,问题尽量拦在半路,不流到末端。事后有内置的比对模块,四种方式,全量详细比对、筛选过滤、抽样、MD5摘要(就是给每行数据算个指纹,指纹一样内容就一样),多线程并行,大数据量也扛得住。任务能立即跑、定时跑、按周期跑,差异明细在KFSMC界面直接看,省得自己写对账脚本。
发现不一致了怎么修?人工挑表做记录级修正可以,全自动修也行,全程不停业务。环境装不了图形界面的话,还有命令行版的校验修复工具兜底。真出岔子,邮件、短信、钉钉告警第一时间就到。
平时想自己粗核对一下也简单,两端各数一遍对总量:
SELECT'orders'AStable_name,COUNT(*)AScnt,MAX(update_time)ASlatest_changeFROMordersWHEREupdate_time>=TRUNC(SYSDATE);-- 金仓数据库侧换CURRENT_DATE,一个意思记录数对上不代表内容全一致,但对不上就肯定有事。平时拿这招扫一遍最省事,要精细化核对再上比对模块。
链路自己别先趴窝
同步链路一旦扛上容灾的担子,自己就不能是单点,不然等于拿漏了气的救生圈救人。KFS这边是KFS-HA多实例热备,备实例平时待命,主的挂了自动顶上,全程不用人碰。
部署有几个讲究。一个KFS-HA实例可以一对一盯一个同步实例,这叫合并部署,也可以看护一整条链路的源端加目标端,叫分离部署。两节点的玩法要额外给个能ping通的IP当虚拟IP,而且半数以上节点状态得正常,机制上等于自带了个小仲裁。上生产前建议先把图画出来,别嫌麻烦。
真实案例不缺。某国家级金融基础设施机构的业务平台,用KFS架了条跨1000公里的双活链路,两个中心实时互备。某省级公共资源交易平台也有意思,省中心对16个地市做一对多分发,中间是2M低带宽、高时延、还丢包的广域网,靠着传输压缩优化,2M照样把活干了。
上线前花五分钟做个连同性自查,能少翻一半的车:
forhostin10.0.0.1110.0.0.1210.0.0.13;doping-c3$host>/dev/null&&echo"$host通"||echo"$host不通,先查网络"donedf-h/data# KUFL落盘目录建议单独挂盘,空间留足日常运维的主战场在KFSMC。数据量、延迟、速率这些指标,按链路、按节点两个维度都能看,还能下钻到表级操作分析和性能耗时,哪张表拖后腿一眼就能瞅出来。另外KFS把RESTful、Thrift、JMX、Shell接口全开放了,银行、政务这种已经有统一监控大盘的,直接接进去就行,不用额外开发适配层,这点是真加分。
碎碎念
开头那三件事,数据孤岛、凌晨跑批、迁移窗口不够用,答案其实是同一个,把搬数据变成持续重放日志。
什么团队值得认真看看它?我觉得三类。要做国产化替换又不敢一步到位的,双轨并行就是给这场景生的。ETL时效拖累业务、天天被T+1数据恶心着的。还有手里库种杂、要跨隔离网络做分发汇聚的,政务、金融、医疗、能源这几个行业尤其对症。
工具终究是工具。上线前把表结构盘清楚,没主键的表重点照顾;实例数量提前算明白;比对校验放进日常巡检,别等出了事才想起来。这三件事做稳了,数据同步就能从天天救火变成没人想起。一条链路能让人想不起来,这活儿基本就算干成了。