土法炼钢兴趣小组的算法知识备份

【图数据库内核】高可用边界:primary / secondary、书签因果一致与只读滞后

文章导航

分类入口
databasegraph
标签入口
#graph-database#neo4j#clustering#causal-consistency#bookmark#primary#secondary#raft#ha#read-replica

目录

11 篇在单库事务上谈隔离与锁。上了集群之后,读者最容易混的三件事是:写安全靠什么、读扩展副本会不会立刻看见提交、以及「因果一致」是否等于更强的隔离级别。本篇只钉内核语义边界——不写种子、备份、跨机房安装步骤。

本文是「图数据库内核」系列第 12 篇(共 16 篇)。→ 系列目录

篇目 核心内容
第 11 篇 · 事务与锁 单机 read-committed 与锁表
第 12 篇 · HA 边界 拓扑角色、复制、书签、路由
第 13 篇 · TinkerPop / JanusGraph 外置存储上的图层

版本锚定:Operations Manual(2026.07 / current)Introduction: Neo4j clustering architectureLeadership, routing, and load balancing;Driver 手册 Bookmarks(因果链用法)。产品文档称 clustering;4.x 口中的 Causal Cluster / Core / Read Replica 在 5.x 叙事里拆成 server 池 + 每库 primary/secondary 拓扑。本篇沿用手册现行术语,并保留「因果一致」作为一致性模型名。Enterprise Edition。不粘贴本机 SHOW SERVERS / 路由表输出。


一、先分清:服务器 ≠ 数据库角色

手册 Overview:集群是一组服务器跑多个数据库;服务器提供算力与存储,数据库各自有独立拓扑,拓扑由 primarysecondary(读扩展)组成。

关键句:

flowchart LR
  subgraph servers ["Server pool"]
    S1["Server 1"]
    S2["Server 2"]
    S3["Server 3"]
    S4["Server 4"]
  end
  subgraph dbA ["Database A topology"]
    P1["primary"]
    P2["primary"]
    P3["primary"]
    Sec["secondary"]
  end
  S1 --- P1
  S2 --- P2
  S3 --- P3
  S4 --- Sec

运维动作(ENABLE SERVERALTER DATABASE … TOPOLOGY)改变的是分配与约束;本系列关心的是:一次 COMMIT 在哪类副本上变成「可安全读」。


二、Primary:写路径、Raft 与多数

2.1 谁能写

Leadership, routing, and load balancing:一致性与安全靠 Raft;Leader 给底层日志定序,Follower 复制 Leader 状态。对 Neo4j 而言,写由当前该库的 Leader(即 writer)排序。每个数据库是逻辑上独立的 Raft 组——一台服务器可以对库 X 当 Leader、对库 Y 当 Follower。

2.2 容错心智:\(M = 2F + 1\)

手册用 \(M = 2F + 1\):要容忍 \(F\) 个 primary 故障,需要 \(M\) 个 primary。常见落点:

拓扑 写可用性直觉 备注
1 primary 无写容错;盘坏则耐久性也丢 延迟最低档
3 primaries 多数部署:可丢 1 个仍写 手册默认推荐档
5 primaries 可丢 2 个仍写 写需联系更多成员,延迟上升
上限 11 手册允许但不推荐堆满 写延迟与协调成本

要区分三档「丢失」难度(手册从易到难):写可用性读可用性耐久性。Primary 挂了太多时库会变成 read-only(不能再处理写)。

与第 11 篇的交叠:锁与隔离仍发生在执行该事务的成员上;集群多数确认的是提交日志的安全复制,不是把全图锁表广播成全局 Serializable。


三、Secondary:异步追赶与只读扩展

Secondary 是从 primary 经 transaction log shipping 异步复制的库副本:周期性向上游成员拉取新事务。职责是放大只读查询——手册称其像图数据的 cache,可跑任意只读查询与过程。

边界事实:

  1. 丢 secondary 不影响库可用性与 primary 容错;只减吞吐。
  2. 不保证立刻可见最新提交:按自己的节奏 pull,可能暂时落后;「最近提交的事务未必马上在 secondary 上可见」。
  3. Secondary 提供某种耐久性缓冲(已提交数据可在别处仍有拷贝),但不能单独当作写安全的多数——写安全在 primary Raft 侧。

读扩展的默认产品叙事:路由表把读导向 reader,让 writer 专注写(见第五节)。这对第 05 / 09 篇意味着:同一条 Expand 计划在 secondary 上跑时,吃的是该副本本地的 page cache 与 store——拓扑角色改变的是「数据新鲜度与路由」,不是邻接布局算法本身。


四、因果一致:书签如何改写「提交可见」

4.1 模型

手册 Causal consistency:因果一致保证因果相关操作在系统各实例上以相同顺序被看到;对客户端即 read-your-writes——不论连到哪台实例,都能至少读到自己写过的内容。例子:创建账号的写,在同一用户随后登录读时必须已在。

实现把手是 bookmark

  1. 事务执行后,客户端可拿到 bookmark(表示库的某一状态);
  2. 后续事务带上该 bookmark;
  3. 集群只让已处理过该书签事务所对应状态的服务器执行下一事务——形成 causal chain

其余路由由集群与 Driver 的 topology 协作完成:写进 primary,读可落到 secondary。

4.2 与第 11 篇隔离的差一层

第 11 篇(单事务语义) 本篇(跨成员可见性)
默认隔离 read-committed;遍历可被并发改 因上集群而自动升为 Serializable
自己刚提交的写 同连接/同成员上通常立刻可见 跨会话、跨 secondary 时靠 bookmark 保证
Lost update / 索引 scan 异常 仍存在 仍存在;复制不消除
死锁 写路径上的瞬时错误 仍在处理写的 primary/writer 上发生

Driver 手册补充(用法级):同一 session 内 bookmark 多由驱动维护,因果链默认成立;跨 session / 与 execute_query 混用时才显式管 bookmark。只有需要跨事务因果时才该付等待成本——bookmark 等待会拖延迟。

工程判断:把「RC 下路径中段被改写」和「secondary 尚未追赶到 bookmark」当成两类 bug。前者靠锁或重试;后者靠因果链或接受最终可见。

sequenceDiagram
  participant App
  participant Writer as Primary writer
  participant Sec as Secondary
  App->>Writer: WRITE txn
  Writer-->>App: commit + bookmark B
  App->>Sec: READ with bookmark B
  Note over Sec: wait until caught up to B
  Sec-->>App: read-your-writes

五、路由:客户端表、服务端转发、读写分流

5.1 Client-side routing

Driver 向集群要 routing table(也可用 dbms.routing.getRoutingTable()):按库列出 writers / readers / routers。通常一个 writer;默认配置下 writer 不在 readers 列表里,以便写节点专注写负载。Driver 用 neo4j:// 做路由;bolt:// 直连指定主机、不做路由

5.2 Server-side routing

写落到非 Leader 成员时,若开启 dbms.routing.enabled 等配置,可由服务器内部把查询转到能写的成员。这是对「连错角色」的补救,不是第二种隔离模型。

5.3 与内核代价的关系


六、刻意不展开的边界

话题 本篇立场
安装、seed、备份恢复、跨 DC 配方 运维手册;不写步骤
Aura 拓扑与定价 产品边界;不写
Composite database(5.x 取代 4.x Fabric 代理叙事) 多图联邦 / 分片访问入口;不存储数据;不替代单库 HA;跨 constituent 的锁与全局隔离不在本系列内核主线
多库 system 库的 primary/secondary 有独立配置轴;只记「也有拓扑,但用服务器配置而非 CREATE DATABASE 拓扑」
图数据水平分片算法 Composite / 应用分片;非 store format 主题

系列 PLAN 已写明:复制集 / Fabric(现 Composite)分布式查询全书不做——本篇只够回答「单图提交可见如何跨副本」。


七、争论与开放问题

  1. 多数同步 primary vs 异步 secondary:A 侧用 Raft 多数换写安全与可预测耐久;B 侧用 secondary 换读 QPS,接受滞后。因果书签是两者之间的客户端契约,不是把 secondary 提升成同步投票者。
  2. 「集群 = 更强一致」误解:产品卖的是容错 + 读扩展 + 可选因果链;默认隔离仍是第 11 篇的 RC。把 HA 当 Serializable 替代品会误诊 lost update。
  3. 开放问题:bookmark 等待与 secondary 追赶延迟在幂律热点写下的可观测性;多库各自 Raft 组时客户端会话跨库的因果组合;Composite 查询下「部分图已见写、部分未见」的应用层协议——手册给了机制零件,生产惯例仍分散。

谱系:因果一致词汇接分布式一致性模型谱系(Lamport 因果序以降);工程落地把手是 bookmark + 路由表,而不是应用自己轮询「是否复制完」。Raft 定序侧与站内 TiKV RaftStore 同属「日志定序再应用」家族,但 Neo4j 的 secondary catch-up 与 TiFlash learner 叙事不要一一对号——角色与产品边界不同。


八、来源与实验台账(本篇)

结论 等级 来源
四特性:可扩展、容错、可运维、因果一致;server/db 解耦;primary/secondary 定义 A Ops Manual Clustering introduction(2026.07 / current)
Writer 同步多数确认;secondary 异步 log shipping 与滞后;容错公式与推荐个数 A 同上
Raft Leader/Follower、每库独立 Raft 组、client/server routing、neo4j:// vs bolt:// A Leadership, routing, and load balancing
Session 内外 bookmark 行为与性能提示 A Neo4j Driver 手册 Bookmarks
Composite 取代 4.x Fabric、不存数据 A Ops Manual Composite databases concepts
本机集群拓扑 / 路由表实测 未跑 不贴伪造输出

九、小结

  1. 角色在库副本上,不在服务器皮肤上;写安全看 primary 多数,读扩展看 secondary。
  2. Secondary 异步追赶:默认可滞后;bookmark 因果链才是跨成员 read-your-writes 的产品契约。
  3. 集群不升级隔离级别:第 11 篇的 RC / 锁 / 死锁故事仍在写路径成员上成立。
  4. 下一篇:离开原生 store,看 TinkerPop / JanusGraph 把图层架在外置存储上时,邻接与事务边界如何改写。

系列目录 · 上一篇:事务与锁 · 下一篇:TinkerPop / JanusGraph

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。


By .