OceanBaseVS金仓:选型别只听“分布式“,先把延迟和复杂SQL这两笔账算清

0 阅读9分钟

前言

上周帮一个朋友单位把关信创选型,OceanBase 跟金仓二选一。两边都来了人,PPT 厚厚一沓,会开了一下午,没吵出结果。

推 OB 的说,人家银行核心都跑过了,分布式多牛。推金仓的说,我们在政企市场干了二十多年,图的就是稳。

回来的路上我一直在琢磨,两边吵的其实全是名词。什么 Paxos,什么共享存储,听着热闹,落不了地。真到落地,纠结的就两件事:延迟差多少?复杂 SQL 谁接得住?

这两块我刚好都踩过坑,写出来给后面的人参考。丑话说在前面,多少带点个人倾向,但不忽悠人。

一、先看骨架

OceanBase(下面简称 OB)是原生分布式。表进去先切分区,分区往一堆服务器上撒,每个分区默认存三份,副本之间靠 Paxos 投票选主、同步日志。没有中心节点这一说,坏一台,多数派里挑个副本顶上,服务接着跑。

金仓(KES)走集中式。一个实例把数据全管了,缓冲区、锁、事务、优化器,全在一个进程里转。要高可用就上主备,备库拉日志追主库。要求再高点,上共享存储集群,好几个实例读写同一份数据,一台倒了另一台秒级接管。数据从头到尾就一份。

对比项OceanBase金仓数据库 KES
架构形态原生分布式,分区打散多机集中式单实例,集群另配
数据副本每分区默认三副本,数据存三份主备各一份;共享存储集群全局一份
写事务提交Paxos 多数派确认,跨分区加两阶段提交本地日志刷盘即返回
高可用副本自动选主,RPO=0主备切换或共享存储多活接管
扩展方式加服务器即水平扩容纵向升配为主,集群分担读压力

路线本身分不出高低,合不合适的事。但骨架差这么多,后面延迟和 SQL 的账,算法就完全是两码事了。

二、延迟:一条 COMMIT 要走多少路

拿条最普通的转账来看:

BEGIN;
UPDATE account SET balance = balance - 100 WHERE acct_no = '622200001';
UPDATE account SET balance = balance + 100 WHERE acct_no = '622200002';
COMMIT;

先看金仓。COMMIT 一到,两条变更日志(WAL)写本地盘,刷盘,回客户端一句"好了"。没有网络什么事。SSD 上这一步一般 1ms 都不到。

就这么点事。

主备要是配了同步复制呢?多等备库一跳,也就一跳。而且异步、同步、极致安全几个档随便挑,想拿多少延迟换多少安全,自己定。

换到 OB 上,同样的 COMMIT 就绕了。两条 UPDATE 各落在分区的 leader 上,日志要发给同分区另外两份副本,多数派(三份里的两份)确认落盘,事务才算提交。这一跳跨服务器,多数时候还跨机房。要是事务碰巧跨了分区(上面那例子俩账号的分区八成不在一起,太常见了),还得走两阶段提交,协调、准备、提交,网络又跑两趟。

肯定有人不服:同城机房往返也就零点几毫秒,单笔还是毫秒级,无感。

行,这话没错,OB 在银行核心跑得动是真的。但一笔业务逻辑往往是几十条短事务串出来的。每条差零点几毫秒,乘上事务数,乘上并发,高峰期一拉开就不是小数了。对账、清结算这种延迟敏感的活儿,这笔账建议真拿计算器按一按。

那到底差多少?看机房,看分区设计,看业务模型,没有通用数字。谁跟你拍胸脯报一个固定数,你反倒要留个心眼。

三、复杂 SQL

延迟是事务型的账。报表的账,得看 SQL 执行器。

我摆一条典型报表 SQL,三表关联、嵌套子查询、窗口函数全有:

-- 各区域近30天的客户消费榜:谁贡献了头部销售额
SELECT *
  FROM (
    SELECT r.region_name,
           c.cust_name,
           SUM(o.amount) AS total_amt,
           ROW_NUMBER() OVER (PARTITION BY r.region_name
                              ORDER BY SUM(o.amount) DESC) AS rn
      FROM orders o
      JOIN customer c ON o.cust_id = c.cust_id
      JOIN region   r ON c.region_id = r.region_id
     WHERE o.pay_time >= CURRENT_DATE - INTERVAL '30 day'
       AND o.amount > (
               SELECT AVG(amount) * 0.1   -- 滤掉零头小额订单
                 FROM orders
            )
     GROUP BY r.region_name, c.cust_name
) t
 WHERE rn <= 20;

金仓跑这条,数据全在本地。优化器先改写,嵌套子查询提出来,一次算完,回头再比对。然后排计划:扫表走哪个索引?两步关联用 Hash Join 还是 Nest Loop?窗口函数按区域排?全在单机的内存和磁盘里转。整个计划从头翻到尾,找不出一步"把数据传给别的机器":

EXPLAIN ANALYZE <上面那条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 轻轻松松。这个量级还去交网络税,就有点冤了。

金仓单机内部也在挖潜。并行查询让大报表吃满多核,配置不复杂:

-- 并行查询总开关
SET enable_parallel_query = on;
-- 单个查询计划允许拉起的并行工作进程数
SET max_parallel_workers_per_gather = 4;
-- 全局并行工作进程池(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 跑一遍就知道了。