
前言上周帮一个朋友单位把关信创选型OceanBase 跟金仓二选一。两边都来了人PPT 厚厚一沓会开了一下午没吵出结果。推 OB 的说人家银行核心都跑过了分布式多牛。推金仓的说我们在政企市场干了二十多年图的就是稳。回来的路上我一直在琢磨两边吵的其实全是名词。什么 Paxos什么共享存储听着热闹落不了地。真到落地纠结的就两件事延迟差多少复杂 SQL 谁接得住这两块我刚好都踩过坑写出来给后面的人参考。丑话说在前面多少带点个人倾向但不忽悠人。一、先看骨架OceanBase下面简称 OB是原生分布式。表进去先切分区分区往一堆服务器上撒每个分区默认存三份副本之间靠 Paxos 投票选主、同步日志。没有中心节点这一说坏一台多数派里挑个副本顶上服务接着跑。金仓KES走集中式。一个实例把数据全管了缓冲区、锁、事务、优化器全在一个进程里转。要高可用就上主备备库拉日志追主库。要求再高点上共享存储集群好几个实例读写同一份数据一台倒了另一台秒级接管。数据从头到尾就一份。对比项OceanBase金仓数据库 KES架构形态原生分布式分区打散多机集中式单实例集群另配数据副本每分区默认三副本数据存三份主备各一份共享存储集群全局一份写事务提交Paxos 多数派确认跨分区加两阶段提交本地日志刷盘即返回高可用副本自动选主RPO0主备切换或共享存储多活接管扩展方式加服务器即水平扩容纵向升配为主集群分担读压力路线本身分不出高低合不合适的事。但骨架差这么多后面延迟和 SQL 的账算法就完全是两码事了。二、延迟一条 COMMIT 要走多少路拿条最普通的转账来看BEGIN;UPDATEaccountSETbalancebalance-100WHEREacct_no622200001;UPDATEaccountSETbalancebalance100WHEREacct_no622200002;COMMIT;先看金仓。COMMIT 一到两条变更日志WAL写本地盘刷盘回客户端一句好了。没有网络什么事。SSD 上这一步一般 1ms 都不到。就这么点事。主备要是配了同步复制呢多等备库一跳也就一跳。而且异步、同步、极致安全几个档随便挑想拿多少延迟换多少安全自己定。换到 OB 上同样的 COMMIT 就绕了。两条 UPDATE 各落在分区的 leader 上日志要发给同分区另外两份副本多数派三份里的两份确认落盘事务才算提交。这一跳跨服务器多数时候还跨机房。要是事务碰巧跨了分区上面那例子俩账号的分区八成不在一起太常见了还得走两阶段提交协调、准备、提交网络又跑两趟。肯定有人不服同城机房往返也就零点几毫秒单笔还是毫秒级无感。行这话没错OB 在银行核心跑得动是真的。但一笔业务逻辑往往是几十条短事务串出来的。每条差零点几毫秒乘上事务数乘上并发高峰期一拉开就不是小数了。对账、清结算这种延迟敏感的活儿这笔账建议真拿计算器按一按。那到底差多少看机房看分区设计看业务模型没有通用数字。谁跟你拍胸脯报一个固定数你反倒要留个心眼。三、复杂 SQL延迟是事务型的账。报表的账得看 SQL 执行器。我摆一条典型报表 SQL三表关联、嵌套子查询、窗口函数全有-- 各区域近30天的客户消费榜谁贡献了头部销售额SELECT*FROM(SELECTr.region_name,c.cust_name,SUM(o.amount)AStotal_amt,ROW_NUMBER()OVER(PARTITIONBYr.region_nameORDERBYSUM(o.amount)DESC)ASrnFROMorders oJOINcustomer cONo.cust_idc.cust_idJOINregion rONc.region_idr.region_idWHEREo.pay_timeCURRENT_DATE-INTERVAL30 dayANDo.amount(SELECTAVG(amount)*0.1-- 滤掉零头小额订单FROMorders)GROUPBYr.region_name,c.cust_name)tWHERErn20;金仓跑这条数据全在本地。优化器先改写嵌套子查询提出来一次算完回头再比对。然后排计划扫表走哪个索引两步关联用 Hash Join 还是 Nest Loop窗口函数按区域排全在单机的内存和磁盘里转。整个计划从头翻到尾找不出一步把数据传给别的机器EXPLAINANALYZE上面那条SQL;-- 计划形态节选示意-- Subquery Scan / WindowAgg ← 窗口函数计算-- Hash Join ← orders × customer-- Hash Join ← 再 × region-- Index Scan / Seq Scan-- InitPlan ← 嵌套子查询一次算完OB 跑先看分区键。orders、customer 分区策略对得上join 本地做。对不上呢现实里多数对不上。计划里就会冒出 EXCHANGE 算子数据先在节点间重分布再碰头。窗口函数更头疼。PARTITION BY 的键跟数据分布对不上同一个区域的行得先从各节点凑齐才能排序。SQL 越复杂、表越多数据在网上搬的次数越多。这个网络税交得肉疼。对比维度OceanBase金仓数据库 KES数据位置分区打散在多台服务器全部在本机多表关联分区对齐可本地join否则网络重分布本地 Hash/Merge Join无网络开销窗口函数分布键不齐需跨节点汇聚排序单机排序计算数据不动嵌套子查询优化器改写叠加分布式代价模型子查询提升改写纯单机代价并行执行跨节点分布式并行单机多核并行查询当然数据量真大到一台机器装不下那没得挑。OB 几十台机器一起扫单机追不上。但我接触的政企核心库数据量大多停在几百 GB 到几个 TB 这档单机 SSD 轻轻松松。这个量级还去交网络税就有点冤了。金仓单机内部也在挖潜。并行查询让大报表吃满多核配置不复杂-- 并行查询总开关SETenable_parallel_queryon;-- 单个查询计划允许拉起的并行工作进程数SETmax_parallel_workers_per_gather4;-- 全局并行工作进程池kingbase.conf 里改重启生效-- max_parallel_workers 16参数一开大表扫描、关联、聚合的计划里就有 Gather 节点了几个工作进程分头干干完汇合。官方给 V9R4C019 出过实测带标量子查询加多表关联的复杂查询100 并发下 TPS 提了大约 60%平均响应时间压到原来的十分之一。官方测试嘛条件你可以怀疑。但方向我觉得靠谱集中式在复杂 SQL 上的余地比很多人想的大。四、资源和运维两笔容易漏的账对了还有两笔账没算选型表上看不见账单上跑不掉。一笔是资源。OB 三副本起步一份数据实打实存三遍生产至少三台服务器。官方给的单机规格建议也不低内存还是预分配的。机器一到位业务跑多跑少大头先被吃掉。金仓主备两台起步数据就一份共享存储集群更是几个实例共用一份数据。同样承载数据量机柜里的密度差不少。另一笔是人力。OB 的 LSM-Tree 每天要做一次大合并内存增量刷成新基线合并窗口的资源波动得躲开业务高峰。你要是 DBA 团队就俩人想想这个窗口怎么排班吧。排障也费劲分区、副本、租户、合并一整套概念都得懂分布式 DBA 现在多紧俏去招聘网站搜一圈就有数了。金仓就好办了集中式那套运维心智 DBA 都熟日常无非备份、清理、维护索引培训便宜招人也容易。工具链省事迁移前 KDMS 做评估迁移中 KFS 做增量同步。官方公开的运营商案例里KFS 扛过日均 4.5TB 增量、秒级延迟这个有实锤。五、到底怎么选直接给结论。数据量单机装不下、并发要无限横着扩、多地多活是硬指标OB 对症。多副本的开销买扩展性和容灾值。反过来说数据量几个 TB 以内、事务短平快、报表 SQL 复杂、延迟敏感预算人手又都紧金仓更合身。没有共识的固有延迟不用交数据搬运的网络税两台机器就能高可用DBA 拿过来就用。一句话规模没到就上分布式等于提前交税规模到了还死守单机那是硬撑。先想明白自己站在哪个区间。六、动手前几句实在话先说第一条别全信评测我这篇也一样。拿自己真实的业务 SQL两边各搭一套环境跑一遍EXPLAIN 摊开看金仓的索引走没走对、并行拉没拉起来OB 的 EXCHANGE 多不多、重分布狠不狠。计划不会说谎人才会。还有压测一定用真实流量分布。玩具数据压出来的结论上线会被教做人。别问我怎么知道的。最后算总账。机器、存储、许可证、人力、培训按三年一起算。延迟低零点几毫秒值多少钱省两台服务器又值多少钱业务方自己会算。有时候我想那天会上要是有人直接把两边的 EXPLAIN 摊出来估计根本吵不了一下午。OceanBaseVS金仓这道题没有标准答案合不合你的业务自己的 SQL 跑一遍就知道了。