想象你是一家正打算全国扩张的餐饮公司老板。巷口那家“独灶小馆”(单机数据库)已经装不下客流:一口灶、一位大厨,再多客人也只能排队,大厨一病,整店歇业。你听说了两种扩大规模的思路:CockroachDB 像“不垮食堂”——每家分店的店员都经过全能培训,共用一本“电子总台账”,任何一家倒下,其他分店立刻接管生意;YugabyteDB 像“伶鲸餐厅”——前厅服务生全部按著名餐饮学院(PostgreSQL)的标准培养,后厨则是统一备料的中央仓库,前厅只管点单,后厨只管出菜。选哪家加盟?要看你的客群讲什么“方言”(SQL 兼容)、要开几家店(多区域部署)、以及你最怕什么(丢数据还是迁移麻烦)。这篇文章就从这几张“试吃评分表”入手,带你看懂两家云原生分布式数据库的架构、兼容性与高可用策略,最终做出自己的选型决策。

岗位关联

对 AI 从业者而言,你的训练数据流水线、在线推理特征库迟早会面对“单点扛不住、故障丢数据”的瓶颈。读懂这两款代表作的架构权衡,就能在选型会上问出关键问题,为 AI 应用挑一个既高可用又可扩展的数据底座。

目录
  1. 可视化演示
  2. 架构演进:从独灶小馆到连锁集团
  3. CockroachDB架构:全能的“不垮食堂”
  4. YugabyteDB架构:分工明确的“伶鲸餐厅”
  5. SQL兼容:用顾客熟悉的方言点菜
  6. 多区域部署:跨城连锁的就近供货
  7. 选型决策:老板的加盟评分表
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

对比CockroachDB对等架构与YugabyteDB分层架构、展示Range/Tablet分片与Raft复制机制、以及多区域全球部署策略,切换模式查看不同维度对比。

本节配有交互动效(进入视口后自动加载,约 3KB)。

架构对比:对等vs分层 CRDB对等单体:每节点兼具SQL与存储 YB分层架构:TServer存储与Master管理分离 不同架构影响扩展性与运维复杂度 CRDB: Peer-to-Peer | YB: Tiered 架构选择决定扩展路径与运维模式

架构演进:从独灶小馆到连锁集团

想象你家巷口有家“独灶小馆”:就一口灶、一位大厨、一个收银台。生意一好,排队两小时——性能到顶了;大厨一感冒,全店歇业——单点故障。这就是传统单机数据库的日常:CPU、内存、磁盘就是那口灶的“火力上限”,想扩容只能换更大的灶(纵向扩展),可灶台再大也有物理极限。

为了让更多客人进门,餐饮业先想到“厨师抄菜谱”:把菜谱复制给几个徒弟,客人多了可以去徒弟那桌吃同样的菜(主从复制、读写分离),但写菜谱仍只能师父来,徒弟只能应付读。后来又想到“分桌”(分库分表):把菜单按菜系切给不同厨师,可切得不好就有人忙死有人闲死,而且跨桌拼菜(跨库 JOIN)几乎做不了。

云原生分布式数据库走的是“连锁集团”路线:把数据自动切成许多小份(分片),散布在很多普通服务器(节点)上;哪台机器负载高,数据就自动搬走(自动均衡);哪台机器坏掉,副本自动顶上(故障自愈)。它不依赖一台“超级大厨”,而是用一群普通厨师组成永不歇业的团队。这也是它与“分库分表中间件”的本质区别:分片、复制、事务都是引擎内置的,对 SQL 透明。

所以连锁集团的目标不是把某一家店开得更大,而是让每个档口都足够快、足够稳,还能随时补位。理解了这条“短板公式”,你就明白分布式数据库真正追求的不是单机更快,而是让最慢的节点也永不掉链子。

T总=max⁡k=1NtkT_{\text{总}} = \max_{k=1}^{N} t_k
这是一条“短板公式”:一组并行工作的节点,整体响应时间等于最慢的那个节点。哪怕 99 台都快,只要有 1 台卡住,这个请求就得等它。
  1. 认识 $N$(节点总数)$N$ 表示参与一份数据服务的节点数量,比如 3 副本集群中至少有 3 台机器同时开工。
    N\displaystyle N
  2. 理解 $t_k$(单个节点耗时)$t_k$ 是第 $k$ 个节点处理自己那份数据花费的时间。节点负载不同,$t_k$ 也各不相同,有的快有的慢。
    tk\displaystyle t_k
  3. 取最大值 $\max$$\max_{k=1}^{N}$ 表示从全部 $N$ 个节点中选出耗时最大的那个——它就是整个系统此刻的瓶颈。
    max⁡k=1N\displaystyle \max_{k=1}^{N}

CockroachDB架构:全能的“不垮食堂”

Cockroach 这个名字就是“蟑螂”,寓意怎么都打不死。它的每家分店(节点)都是全能店员:点单、备料、掌勺样样在行。最关键的是,所有分店共用一本“电子总台账”——每种原料都按“编号 + 状态”记录(Key-Value 存储),任何店员查同一个编号,得到的记录都一致。

CockroachDB 用 Go 语言写成,所有数据——不管是表、索引还是分区——最终都落在一个统一的、按键排序的分布式 Key-Value 存储里。它以约 64MB 为单位把数据切成许多 Range,每个 Range 默认保存 3 份副本,副本之间用 Raft 共识协议同步:写入必须得到多数副本确认才提交。读取由每个 Range 的“租约持有者”(Leaseholder)负责,它相当于分店的值班店长。SQL 层则是“翻译官”:把 SELECT、JOIN 翻译成对 KV 的读写操作,再根据 Key 范围路由到正确的 Range。

全能店员 + 总台账 + 投票制,构成了“不垮食堂”的生存哲学:任何分店突然消失,其余分店一合计(选举新 Leader)就能继续营业,账目一分不少。正因如此,CockroachDB 在跨机房灾难场景下以“不丢数据”著称。

Q=⌊N2⌋+1Q = \left\lfloor \frac{N}{2} \right\rfloor + 1
这是 Raft 的“法定人数”公式:3 副本时 $N=3$,多数派是 2。只要有 2 个副本确认,写入就可提交,同时最多能容忍 1 台宕机。
  1. 认识 $N$(副本总数)$N$ 指一个分片的数据被复制到了几个节点,默认是 3 副本,即 $N=3$。
    N\displaystyle N
  2. 计算半数 $\lfloor N/2 \rfloor$$\lfloor \cdot \rfloor$ 是向下取整,$3/2=1.5$ 取整后为 1,表示“不到一半”。
    ⌊N2⌋\displaystyle \left\lfloor \frac{N}{2} \right\rfloor
  3. 加一得到法定人数把半数加 1,得到严格超过一半的投票门槛,这是 Raft 判定写入成功的底线。
    Q=⌊N2⌋+1\displaystyle Q = \left\lfloor \frac{N}{2} \right\rfloor + 1

YugabyteDB架构:分工明确的“伶鲸餐厅”

“伶鲸餐厅”的聪明之处在于把前厅和后厨彻底分开:前厅服务生全部按一家著名餐饮学院(PostgreSQL)的教材培训,客人用熟悉的术语点单;后厨则有一套统一的“文档食谱”(DocDB),食材按文档式档案归档。前厅不懂后厨的仓库细节,后厨也不关心客人的口音。

YugabyteDB 用 C++ 编写,是典型的双层架构。上层是查询引擎:YSQL 直接基于 PostgreSQL 源码构建,提供 PG 的连线协议与大部分语法;另有 YCQL 提供 Cassandra 风格的宽表 API。下层是 DocDB 存储引擎:它在 RocksDB 之上扩展出文档模型,把一行数据按列组织成子文档。每个表按主键范围切成 tablet,每个 tablet 是一个独立的 Raft 小组,默认 3 副本。查询层负责 SQL 解析、优化与执行计划,存储层负责持久化、复制与分布式事务,两者通过 RPC 协作。

前厅专业(PG 语义原汁原味),后厨高效(文档存储善于压缩与扫描),各司其职——这正是 YugabyteDB“更懂 SQL”的结构根源:它不需要把每个 SQL 都翻译成 KV,而是让 PG 的成熟执行器直接跑在自己头上。

T查询=T解析+T优化+T执行T_{\text{查询}} = T_{\text{解析}} + T_{\text{优化}} + T_{\text{执行}}
一条 SQL 的响应时间可以拆成三段:把 SQL 文本变成语法树(解析)、把语法树变成高效执行计划(优化)、真正读取数据(执行)。层与层分离,让每一段都能独立优化。
  1. 解析耗时 $T_{\text{解析}}$前厅服务生把客人的口语点单写成标准订单——数据库把 SQL 文本解析成内部语法树。
    T解析\displaystyle T_{\text{解析}}
  2. 优化耗时 $T_{\text{优化}}$服务生判断是先上凉菜还是先上热菜——优化器决定走索引还是全表扫描,生成执行计划。
    T优化\displaystyle T_{\text{优化}}
  3. 执行耗时 $T_{\text{执行}}$后厨真正把菜端出来——执行器按计划读写 DocDB,聚合、排序、返回结果。
    T执行\displaystyle T_{\text{执行}}

SQL兼容:用顾客熟悉的方言点菜

客人来自天南海北:有的讲“川话”(MySQL 习惯),有的讲“粤语”(PostgreSQL 习惯)。“不垮食堂”选择在总台装一个“粤语翻译器”——它自己按 PG 的协议和语法接待,但内核是自研的;“伶鲸餐厅”则直接雇了一批 PG 学院毕业的服务生——内核就是 PG 本尊。

CockroachDB 的 SQL 层是自研的,它实现了 PostgreSQL 的连线协议(wire protocol)和大部分常用语法,用 Go 从零重写,兼容策略是“常用功能优先”,边缘特性(部分窗口函数、类型转换细节)取决于具体版本。YugabyteDB 的 YSQL 则把 PostgreSQL 源码“搬进”自己的查询层,继承了 PG 的解析器、优化器和执行器,因此 psql、pg_dump、JDBC/psycopg 驱动和常用扩展的迁移成本更低。但无论选哪家,从 MySQL 迁过来都要改写方言:自增主键改成 SERIAL/IDENTITY,反引号改成双引号,ON DUPLICATE KEY 改成 ON CONFLICT。

顾客点菜越顺畅,翻台率越高。选型前拿现有 SQL 跑一遍“点菜测试”,比看宣传册上印着“兼容 PostgreSQL”五个字有用得多——毕竟服务生会说粤语,不代表他会背粤语诗词。

兼容度=S支持S目标\text{兼容度} = \dfrac{S_{\text{支持}}}{S_{\text{目标}}}
兼容度不是 0 或 100%,而是一个比例:你的应用用到的 SQL 特性中有多少能被目标数据库原样支持。这个分子分母,只有拿真实业务 SQL 去测才知道。
  1. 分子 $S_{\text{支持}}$(支持的特性数)你的业务 SQL 里,目标数据库能正确执行的语法项数量,比如 UPSERT、JSONB、窗口函数。
    S支持\displaystyle S_{\text{支持}}
  2. 分母 $S_{\text{目标}}$(目标方言特性总数)完整 PostgreSQL 方言包含的全部语法项,这是一个“全量菜谱”。
    S目标\displaystyle S_{\text{目标}}
  3. 相除得到比例比值越接近 1,迁移越平滑;越小,意味着要改写的 SQL 越多、风险越高。
    S支持S目标\displaystyle \frac{S_{\text{支持}}}{S_{\text{目标}}}

多区域部署:跨城连锁的就近供货

连锁要开到全国,顾客最烦“菜从外地送”。有两种玩法:加盟店各自为政(多集群异步复制,各城市数据不完全同步);直营中央调度(一个全球大集群,副本按城市就近摆放,负责拍板的“店长”(Leaseholder/Leader)被派到离客人最近的分店)。但“就近”有物理极限——光速也救不了几千公里的距离。

CockroachDB 把部署策略做成了可配置项:区域表(regional table)让副本固定在特定区域,全局表(global table)牺牲写延迟换取各区域读都快;还有存活目标(survivability goals),控制整个区域故障还是单个可用区故障时服务不中断。它的“就近读”靠把 Leaseholder 放到读数区域实现,并支持 follower reads——用可容忍的陈旧读换更低的延迟。YugabyteDB 类似:通过优先可用区(preferred zones)控制 tablet leader 的位置,并提供 xCluster 异步复制用于跨云多集群容灾。强一致写必须凑齐多数派,跨区域时每一笔写都绕不开物理距离。

跨城生意的本质是选址:把“拍板的人”(Leader/Leaseholder)放到客人身边,多数派才能最快凑齐;把副本放得太远,再快的服务器也救不了网络延迟。

RTT≈2dcRTT \approx \dfrac{2d}{c}
往返延迟约等于“两倍距离 ÷ 光速”。北京到上海约 1200 公里,光纤中光速约 20 万公里/秒,一次往返的理论下限就有 12 毫秒——这是跨区域强一致写绕不过去的物理账。
  1. $d$(两地距离)客户端所在城市与数据所在城市之间的直线距离,比如北京到上海约 1200 公里。
    d\displaystyle d
  2. $c$(信号速度)光在光纤中的传播速度约每秒 20 万公里,不是真空中的 30 万,因为光纤折射会减速。
    c\displaystyle c
  3. 乘以 2(往返)请求要过去、确认要回来,一来一回就是两倍距离,所以是 $2d$。
    2d\displaystyle 2d

选型决策:老板的加盟评分表

老板要加盟,得先列权重:口味正宗(SQL 兼容)占 40%,抗揍(一致性)占 30%,出餐快(延迟)占 20%,加盟费与培训(运维生态)占 10%。两家都试吃打分,加权求和就是最终答案。没有“哪家更好”,只有“哪家更适合你的客群”。

关键差异盘点。事务模型:CockroachDB 默认可串行化隔离(serializable),用混合逻辑时钟为全局事务排序,跨区域提交后往往还要多等一个时间戳推进的往返,因此跨区写更慢;YugabyteDB 默认快照隔离(snapshot isolation),语义贴近 PostgreSQL 的常用模式,跨区写没有额外的全局时钟等待,但也提供可串行化选项。一致性:两者都是 Raft 强一致多副本复制,没有“谁更一致”的本质差别,差别在于默认隔离级别带来的跨区写成本和 PG 语义匹配度。生态:YSQL 内核就是 PG,扩展、迁移工具链更宽;CockroachDB 运维简单,单二进制部署,托管云服务成熟,PostGIS、CDC 等能力也有完整方案。

把“别人说好”翻译成“我的场景打分高”,答案自然浮现:追求极端强一致的全局事务与高可用,优先看 CockroachDB;追求 PG 生态平滑迁移、默认事务语义贴近传统业务,优先看 YugabyteDB。评分表一列,剩下的就是执行。

S总分=∑i=1nwixiS_{\text{总分}} = \sum_{i=1}^{n} w_i x_i
选型打分 = 把每一项得分乘以它在你心中的权重,再全部加起来。权重是“我要什么”,得分是“它给什么”,两者相乘才是有意义的总分。
  1. $x_i$(单项得分)对某项指标的打分,比如 SQL 兼容度打 8 分,运维省心度打 6 分。
    xi\displaystyle x_i
  2. $w_i$(指标权重)这个指标对你业务的重要性,所有权重加起来等于 1,比如兼容 40%、一致性 30%。
    wi\displaystyle w_i
  3. 求和 $\sum$逐项相乘后累加,得出一家数据库对你的综合适配分,分数高者胜出。
    ∑i=1nwixi\displaystyle \sum_{i=1}^{n} w_i x_i

AI 应用场景

金融支付系统的两地三中心改造

阶段:在线数据供给(账务流水、特征存储)

解决的问题:传统 MySQL 主从复制在主数据中心故障时会丢失最后一批未同步的账务记录(RPO 为分钟级),且无法水平扩展。分布式数据库用 Raft 多数派提交,让故障切换时不再丢数据。

具体案例:某支付公司把账务核心从 MySQL 主从迁移到 CockroachDB 的三区域集群,Raft 保证跨机房多数派确认后才提交,单分片吞吐提升约 4 倍,RPO 从分钟级降到 0,支付链路在机房级故障下自动切换。

电商大促的弹性扩容与多活

阶段:在线交易与推荐特征实时写入

解决的问题:手工分库分表扩容要停服搬数据,大促流量波峰难以预测;而原生分布式数据库加节点即扩容,数据自动重新均衡,无需改应用代码。

具体案例:某跨境电商采用 YugabyteDB 承载订单与购物车,大促前横向扩充节点池,数据自动均衡;同时把 AI 推荐所需的用户点击流实时特征写入同一集群,在线推理直接读最新数据。

从自建 PostgreSQL 平滑迁移到云原生

阶段:应用数据库基础设施

解决的问题:单机 PostgreSQL 读多写少、存储遇到瓶颈,而自建分库分表改造复杂、风险高。YugabyteDB 因内核即 PG,支持 pg_dump 导出导入,SQL 几乎零改造完成水平扩展。

具体案例:某 AI 公司的用户行为分析服务原本跑在单机 PostgreSQL 上,日活增长后查询延迟飙升;迁移到 YugabyteDB 后,YSQL 直接复用现有驱动与 ORM,查询自动路由到各 tablet,存储与并发能力随节点数线性增长。

Python 演示

python64 行
# -*- coding: utf-8 -*-"""mini_raft_compare.py: 模拟 Raft 多数派与分片热点, 辅助理解分布式选型"""import random  def quorum(n):    # Raft 法定多数: 超过一半才算数    return n // 2 + 1  def write_availability(replicas, fail_rate, trials=20000):    # 随机故障下, 写入能拿到多数确认的概率    ok = 0    for _ in range(trials):        alive = sum(            1 for _ in range(replicas) if random.random() > fail_rate        )        if alive >= quorum(replicas):            ok += 1    return ok / trials  def shard_tail_latency(keys, shards):    # 把 key 哈希到分片, 返回最热分片的负载占比    buckets = [0] * shards    for k in keys:        buckets[k % shards] += 1    total = len(keys)    return max(buckets) / total  def choose(weights, scores):    # 加权评分: 输出各方案的加权总分    return {        name: sum(w * s for w, s in zip(weights, sc))        for name, sc in scores.items()    }  def main():    random.seed(42)    print("== Raft 写入可用性模拟 ==")    for r in (3, 5):        for f in (0.1, 0.3):            print(f"replicas={r}, fail_rate={f}: "                  f"avail={write_availability(r, f):.4f}")     print("== 分片热点模拟 (简单取模哈希) ==")    keys = [random.randint(1, 20) for _ in range(10000)]    for shards in (10, 50):        hot = shard_tail_latency(keys, shards)        print(f"shards={shards}, 最热分片负载占比={hot:.3f}")     print("== 数据库选型加权评分 ==")    weights = (0.4, 0.3, 0.2, 0.1)  # 一致性, 生态, 性能, 成本    scores = {        "CockroachDB": (9, 7, 8, 6),        "YugabyteDB": (8, 9, 7, 7),    }    print(choose(weights, scores))  if __name__ == "__main__":    main()
目的:用三个小实验还原正文的核心概念——Raft 多数派怎样提高可用性、简单取模分片为何会产生热点、加权评分表如何帮我们选型。
  1. return n // 2 + 1计算 Raft 法定多数,3 副本时返回 2,5 副本时返回 3。
  2. alive >= quorum(replicas)存活副本数是否达到多数派,决定这次写入能不能提交。
  3. random.random() > fail_rate用均匀随机数模拟一台机器是否故障,fail_rate 越高越容易挂。
  4. buckets[k % shards] += 1模拟“取模哈希”路由:把 key 对分片数取余,映射到某个分片。
  5. max(buckets) / total最热分片承载的流量占比,占比越高说明倾斜越严重、短板越明显。
  6. sum(w * s for w, s in zip(weights, sc))加权求和:把一致性、生态、性能、成本四项得分分别乘权重后累加。
  7. random.seed(42)固定随机种子,让每次运行结果一致,便于复现实验结论。

常见误区

误区所谓云原生数据库,不就是把分库分表中间件内置到数据库里了吗?既然有了它,MyCat、ShardingSphere 这些中间件是不是该被淘汰了?

正解分库分表只是加在单机数据库外面的“路由层”,把一张表切成多份后,跨库 JOIN、全局事务、分布式一致性都被阉割了,还需要人工指定分片键。原生分布式数据库则让存储引擎从一开始就按“分片 + 共识”设计,分区对 SQL 完全透明,跨分片事务和自动再均衡是内在能力。就像把菜谱撕成十份分给十个厨师,和一本会自动重印的电子菜谱,是两种完全不同的东西。

为何常见:因为 MySQL 生态的分库分表中间件太普及,人们习惯用旧的思维框架去套新事物,以为分布式数据库只是中间件的“官方版”。

误区数据复制了三份,随便连哪台读都行,而且读到的一定是刚刚写入的最新值,否则还算什么强一致?

正解强一致读必须走 Raft 共识路径,从 Range 的 Leaseholder(或 Raft Leader)读;直接读普通 Follower 副本,可能拿到的是几毫秒甚至更早的陈旧数据,除非显式开启 follower reads 且应用能容忍短暂滞后。道理很简单:只有店长才知道最新菜价,普通店员可能还在看昨天打印的菜单。

为何常见:把“数据被复制了”等同于“所有副本线性一致”,忽略了读路径也要经过共识协议这一层。

误区YugabyteDB 的内核就是 PostgreSQL,所以现有 PG 应用可以零改动迁移;CockroachDB 也说兼容 PG,那肯定也差不多,随便迁。

正解YSQL 虽然基于 PG 源码,但分布式化会裁剪或改造一部分单机特性——部分函数、扩展、触发器行为、锁语义、序列并发行为都可能与原生 PG 不同,必须逐项验证。CockroachDB 是自研 SQL 层仿照 PG 协议,兼容以常用功能为主。迁移前一定要拿真实业务 SQL 和负载做兼容性测试。就像一个人会说粤语,不代表他懂所有粤语俚语和古诗词。

为何常见:厂商宣传“PG-compatible“,用户自动脑补成”100% 相同“,而忽略了”兼容”是一个需要量化测量的比例。

误区部署一个全球大集群,数据副本遍布各大洲,那么任何地点的用户读写都应该很快,因为数据哪儿都有。

正解强一致写必须由多数派副本确认,如果副本跨洲,每一笔写都至少包含一个洲际网络往返;读也受 Leaseholder 位置约束,不能随便挑最近的副本。想低延迟只有两条路:把数据和“拍板的人”放到用户附近,或者接受异步复制带来的数据滞后。中央厨房可以全球配送,但“就近提货”也得等货先从远方运来。

为何常见:直觉上“多副本 = 到处都是数据 = 到处都快”,忽略了共识协议多数派确认带来的物理延迟下限。

面试题

Q1. 分布式数据库相比单机数据库的核心优势是什么?

单选题 · easy

  • A.自动水平扩展并提升可用性← 正确答案
  • B.单条 SQL 查询速度一定更快
  • C.可以完全不创建任何索引
  • D.不需要考虑网络分区问题

答案:A。分布式数据库把数据切成许多分片分散到多台节点,负载高时加节点即可扩容,节点故障由副本自动接管,这是它相对单机的核心优势。B 错误:查询速度取决于执行计划与网络开销,不一定更快;C 错误:任何数据库都需要合理索引;D 错误:恰恰相反,分布式系统必须认真处理网络分区。

Q2. 在 Raft 共识下,3 副本集群最多可同时故障几台仍能正常写入?

单选题 · easy

  • A.最多 0 台
  • B.最多 1 台← 正确答案
  • C.最多 2 台
  • D.最多 3 台

答案:B。Raft 的法定人数是 ⌊3/2⌋+1=2,即写入只要得到 2 个副本确认就能提交,因此允许 1 台副本宕机;如果 2 台同时故障,存活副本不足 2,无法形成多数派,写入会被阻塞。这就像三人委员会投票,至少两人同意才能通过。

Q3. YugabyteDB 的 YSQL 查询引擎主要继承自哪个数据库?

单选题 · mid

  • A.MySQL
  • B.Oracle
  • C.PostgreSQL← 正确答案
  • D.MongoDB

答案:C。YSQL 直接基于 PostgreSQL 源码构建,继承了 PG 的解析器、优化器和执行器,所以它的 SQL 语义与生态工具最贴近原生 PG。MySQL 是另一套方言体系,Oracle 是闭源商业库,MongoDB 是文档数据库,都与 YSQL 的出身无关。

Q4. CockroachDB 底层使用哪种统一模型来存储所有数据?

单选题 · mid

  • A.文档模型
  • B.图模型
  • C.列式存储模型
  • D.排序键值对模型← 正确答案

答案:D。CockroachDB 的所有表、索引最终都被编码为“排序的 Key-Value”存入统一的 KV 存储,表的一行只是连续 Key 区间中的一小段。文档模型是 YugabyteDB DocDB 的特色,图模型是图数据库,列式存储是 OLAP 分析引擎的取向。

Q5. 关于 CockroachDB 的写入路径,下列说法正确的是?

单选题 · mid

  • A.写单个副本即可直接返回
  • B.必须多数副本确认才提交← 正确答案
  • C.必须全部副本确认才返回
  • D.写入只落到本地不复制

答案:B。CockroachDB 每个 Range 副本之间用 Raft 共识同步,写入只需多数派(3 副本时为 2 个)确认即可提交。A 错误:单副本确认无法形成多数派;C 错误:要求全部副本确认会大幅降低可用性,没有必要;D 错误:不复制就失去了高可用意义。

Q6. CockroachDB 默认提供的事务隔离级别是?

单选题 · hard

  • A.读未提交
  • B.读已提交
  • C.快照隔离
  • D.可串行化← 正确答案

答案:D。CockroachDB 默认使用可串行化(serializable)隔离,这是最强的隔离级别,配合混合逻辑时钟实现全局一致的快照。YugabyteDB 默认才是快照隔离(更贴近 PG 常用语义)。读未提交在主流分布式数据库中几乎不会作为默认值。

Q7. 多区域集群中,把哪个角色放到离用户最近的区域能有效降低读延迟?

单选题 · mid

  • A.全部的 Follower 副本
  • B.分片的租约持有者← 正确答案
  • C.冷备的历史数据节点
  • D.集群的元数据注册表

答案:B。读请求由 Range 的 Leaseholder(租约持有者)负责,它相当于“值班店长”,把它放到客户端附近,读延迟就低。Follower 副本多但可能陈旧;冷备节点和元数据服务都不参与常规读路径,放得再近也没用。

Q8. 相对手工分库分表,云原生分布式数据库的优势包括哪些?

多选题 · mid

  • A.跨分片事务原生支持← 正确答案
  • B.自动均衡与故障自愈← 正确答案
  • C.无需手工指定分片键← 正确答案
  • D.完全不需要任何人工运维

答案:ABC。分片、复制、事务都是引擎内置能力,跨分片事务透明、数据自动再均衡、副本自动切换,都是相对中间件方案的实质性优势。但 D 过于绝对:任何数据库都需要监控、升级、容量规划等运维工作,不存在“完全不需要运维”的系统。

Q9. 对两家数据库 SQL 兼容性的正确理解包括哪些?

多选题 · mid

  • A.CockroachDB 自研 PG 协议实现← 正确答案
  • B.YSQL 来源于 PostgreSQL 内核← 正确答案
  • C.兼容等于可零改动迁移
  • D.兼容度决定迁移成本← 正确答案

答案:ABD。CockroachDB 用 Go 自研 SQL 层并实现 PG 连线协议,YSQL 则直接基于 PG 源码,两者路线不同。兼容度是一个比例而非二值,业务 SQL 中不兼容的部分越多,改写成本越高。C 错误:兼容不等于 100%,分布式化会裁剪某些单机特性。

Q10. 一个 9 副本的 Raft 小组,至少需要几个副本存活才能正常写入?

单选题 · extreme

  • A.3 个
  • B.5 个← 正确答案
  • C.7 个
  • D.9 个

答案:B。法定多数 = ⌊9/2⌋+1 = 5,所以至少 5 个副本存活才能凑齐多数派完成写入,同时最多容忍 4 台故障。这里最常见的错误是直接用 9÷2 得到“4 或 5”不够严谨——必须向下取整后再加 1,保证多数严格超过半数。