RAFT Sharding 装好后,我发现跨分片 JOIN 还是一坨

Oracle 26ai 的 Sharded Database 终于把复制协议从 GDS 那套黑盒换成了 RAFT,官方说法是"分布式共识复制,自动故障转移"。我搭了一套三节点的 shard 环境,写性能确实比 19c 的 Sharding 好了一截,但跨分片 JOIN 的延迟还是让人血压飙升。

7.1 RAFT 复制到底比旧版强在哪

旧版 Oracle Sharding 用 GDS(Global Data Services)做协调,Shard Director 是个单点瓶颈,所有跨分片事务都要过它。26ai 换成 RAFT 后,每个 shard 的副本集(通常是 3 副本)自己选 Leader,写请求走 Leader,读请求可以走 Follower,Shard Director 只负责路由,不参与共识。这相当于把协调层从"集中式"改成了"分布式",吞吐量上去了。

RAFT 的弱点是跨分片事务。RAFT 保证的是单个 shard 副本集内的强一致性,跨 shard 的事务仍然需要两阶段提交(2PC),只不过 Oracle 做了优化,叫"Consensus Commit"。简单说就是把 2PC 的 Prepare 阶段也走 RAFT 日志,减少一次网络往返。但再怎么优化,跨 shard 的 JOIN 还是要拉数据,网络延迟躲不掉。

7.2 实验:单分片 vs 跨分片查询对比

-- 建 Sharded Table(按 cust_id 分片)
CREATE SHARDED TABLE customers (
    cust_id NUMBER NOT NULL,
    cust_name VARCHAR2(100),
    region VARCHAR2(20),
    PRIMARY KEY (cust_id)
) TABLESPACE SET ts1
PARTITION BY CONSISTENT HASH (cust_id)
PARTITIONS AUTO;

-- 建 duplicated table(每个 shard 全量复制)
CREATE DUPLICATED TABLE products (
    prod_id NUMBER PRIMARY KEY,
    prod_name VARCHAR2(100),
    price NUMBER
);

-- 查询 1:单分片( cust_id 作为分片键)
SELECT * FROM customers WHERE cust_id = 12345;
-- P95 延迟:3ms(直接路由到对应 shard)

-- 查询 2:跨分片 JOIN(分片键不在过滤条件)
SELECT c.cust_name, p.prod_name, o.amount
FROM customers c
JOIN orders o ON c.cust_id = o.cust_id
JOIN products p ON o.prod_id = p.prod_id
WHERE p.prod_name = 'iPhone 26';
-- P95 延迟:450ms(Shard Director 拉取各 shard 数据做协调 JOIN)

450ms 的延迟对于 OLTP 来说是致命的。我们分析了下执行计划,发现 Shard Director 把各 shard 的结果集拉到协调节点做 HASH JOIN,中间数据量有 200 万行,网络传输占了 380ms。解决办法只有两个:一是把查询改成单分片路由(加 cust_id 过滤),二是把 products 表做成 duplicated table,但 duplicated table 的写入会慢一倍(要同步到所有 shard)。

结论:RAFT Sharding 适合"分片键即查询键"的场景,比如按用户 ID 分片的社交消息、按租户 ID 分片的 SaaS。如果业务里大量跨用户查询(比如运营后台的统计报表),Sharding 就是给自己找不痛快,还不如用 Exadata 或者单机大内存实例。


请使用浏览器的分享功能分享到微信等