- 引言 — 一份五年之约的中期检查
- Accord 承诺了什么 — CEP-15 的目标
- 实际发布了什么 — 「季度 alpha」的真实面貌
- 语法 — BEGIN TRANSACTION 长什么样,以及一次性模型
- 模式与代价 — full、mixed_reads、off
- 迁移现有表的代价 — 迁移不是免费的
- 与此同时,5.x 里能用到什么 — SAI 与向量搜索的现实
- 那么,什么时候才该开始关心
- 结语
- 参考资料
引言 — 一份五年之约的中期检查
在 Cassandra 里,「事务」长期以来都是个半吊子的词。LWT(轻量级事务)是基于 Paxos 的 CAS,所以只能在单个 key 内起作用 — 用 Cassandra 文档自己的说法,"Paxos only supports a single key"。要把多个分区原子地绑在一起,只能靠应用层用 saga 或批处理去模拟。
提出改变这一点的方案是 CEP-15: General Purpose Transactions。用于跟踪的 JIRA CASSANDRA-17092 创建于 2021 年 10 月 30 日,直到 2025 年 1 月 21 日才被标记为「Fixed」关闭并合并进 trunk。随后,作为 2026 年 3 月 21 日的构建产物,6.0-alpha1 上线到了 Apache 官方仓库,4 月 3 日又在 dev 邮件列表上公布了发布消息。从提案到能跑起来的发布,整整四年半。截至本文写作的 2026 年 7 月中旬,6.0 依然只有 alpha1 这一个版本,生产线仍是 5.0.8(2026-04-16)。
所以现在正是值得梳理一下的时候 — 承诺了什么、实际发布了什么、文档里写明的限制是什么,以及你到底该从什么时候开始关心。
Accord 承诺了什么 — CEP-15 的目标
把 CEP-15 明确写出的目标原样搬过来,是这样的。
- 通用事务 — 数据库中任意的 key 组合都能一次性绑在一起
- strict-serializable 隔离级别
- 最优延迟 — 正常条件下,所有事务只需一次 WAN 往返
- 最优容错 — 少数副本故障不影响延迟与性能
- 可扩展性 — 不引入新的瓶颈
- 支持从 Paxos 的在线迁移
与现有系统的区别在于没有 leader。CEP 文档本身把先例分成了这几类 — FaunaDB、FoundationDB 用全局 leader(扩展性瓶颈),DynamoDB、CockroachDB、YugabyteDB 用事务日志与按 key 分配 leader 的复杂组合,而学术界的无 leader 方案(EPaxos 系)还从未真正用在实际数据库里。Accord 就是想把这第三条路径带进生产数据库的尝试。文档里也写明了长期计划 — 这项工作预计将在项目中取代 Paxos,过渡期内两个协议会共存,之后 Paxos 将被弃用。
有一点要留意。「一次 WAN 往返」是协议层面的说法,截至本文写作时,官方文档里任何地方都没有以毫秒为单位的正式基准测试数字。后面会看到,就连发布说明本身也还处于占位符状态。
实际发布了什么 — 「季度 alpha」的真实面貌
6.0-alpha1 的 CHANGES.txt 里,实际写着这几行。
6.0-alpha1
* General Purpose Transactions (Accord) [CEP-15] (CASSANDRA-17092)
* Automated Repair Inside Cassandra [CEP-37] (CASSANDRA-19918)
* ...(节选 — 此外还有 TCM、约束框架、UCS 并行压缩等多项)
来的不只是 Accord。NEWS.txt 的 6.0 新特性列表里列出了 CEP-21 事务性集群元数据(TCM)、CEP-37 自动修复调度器、CEP-42 约束框架,以及采用 JDK 21 与 Generational ZGC 作为默认 GC。因为 TCM 改变了升级流程本身,NEWS.txt 最上方附有一条警告,说它「需要与以往升级不同的运维步骤」。
不过要准确读懂这次发布的性质。4 月 3 日的公告是这么说的 — 这是 6.0 系列的季度(quarterly)alpha 发布,cassandra-6.0 分支尚未创建,本次发布不会启动 alpha 品质生命周期指南,季度 alpha 仅供开发与测试之用。看 2025 年 11 月的发布节奏提案讨论串,意图很明确 — 季度 alpha 只是「确认能构建、投票通过的某个特定日期的标签」,没有回补(backport),也没有支持。
正式周期紧接着就开始了。2026 年 4 月 9 日的讨论串讨论了拉出 cassandra-6.0 分支和 6.0-alpha2("this kicks off the alpha release lifecycle",即这将开启 alpha 发布生命周期),如今仓库里确实已经存在 cassandra-6.0 分支,trunk 也已转向 7.0 开发。但截至 7 月中旬,官方下载页面上 6.0 系列的构建产物只有 alpha1 这一个。没有 beta,也没有承诺的 GA 日期。
版本号背后还有段插曲。这个版本原本打算叫 5.1,但在 2024 年 12 月 dev 邮件列表的讨论「5.1 should be 6.0」 中,大家认为 TCM 和 Accord 是从根本上改变运维方式的一次代际更替,于是定下来把主版本号往上提。结果 5.1 没有发布,下一个版本变成了 6.0。
文档跟不上代码的迹象也一目了然。NEWS.txt 的 6.0 新特性小节里还留着「以下是占位符,很快会修正」这句话,而 Accord 本身在新特性列表里甚至连一条都没有。CQL 事务用户指南(transactions.adoc)在 trunk 上是有的,但 cassandra-6.0 分支上还没有。除非你打算亲自测试这个 alpha,否则在现阶段,读仓库里的一手文档,会比读博客和发布材料更准确。
语法 — BEGIN TRANSACTION 长什么样,以及一次性模型
trunk 的事务指南里的语法长这样。
BEGIN TRANSACTION
LET sender = (SELECT balance FROM accounts WHERE user_id = ?);
SELECT sender.balance; -- 返回结果只能写在修改语句之前
IF sender.balance >= 100 THEN
UPDATE accounts SET balance = balance - 100 WHERE user_id = ?;
UPDATE accounts SET balance = balance + 100 WHERE user_id = ?; -- 不同分区也可以
END IF
COMMIT TRANSACTION
跨越不同分区(乃至不同表)的读取-判断-写入,成为了一个原子单元。这是用 LWT 做不到的事。
关键在于,这不是交互式事务。它不是像 RDBMS 那样让 BEGIN 保持打开、在应用逻辑之间来回执行多条语句的模型,而是把整个事务当作一条语句一次性提交的一次性(one-shot)模型。内部文档(CQL on Accord)解释了原因 — 事务将要触碰的 key 集合必须在执行前全部声明好,执行过程中不能更改。这种预先声明,正是换来无 leader 依赖追踪能力所付出的代价。
把文档里明确写出的限制归纳一下,是这样的。
- LET 的 SELECT 必须恰好返回一行,必须用等号指定完整的分区 key,不能使用范围条件、多分区或聚合
- 事务块内不能使用计数器表、聚合函数、ORDER BY 和 GROUP BY、自定义 TTL/时间戳,以及范围 DELETE
- IF 条件只支持 AND(没有 OR),null 比较一律为假
- SET 子句里不能做行引用的算术运算 — 类似
SET balance = sender.balance - 100这样的写法不行,必须把算好的值当参数传进去 - 返回结果的 SELECT 必须写在修改语句之前,要看修改后的值,得在提交之后另外查询
文档里也有一份性能指南,而它的脚注老实地道出了这个功能的成熟度 — 建议 LET 从 5 个、分区从少于 3 个开始,同时自己也承认这「是一份建议性的指南,而非经验推导出的极限」。也就是说,项目本身也还没有基于实测的调优依据。
模式与代价 — full、mixed_reads、off
Accord 不是一开就全局生效,而是按表选择。在 cassandra.yaml 里打开 accord.enabled: true 之后,需要给每张表设置 transactional_mode。按运维指南,一共有三种模式。
off(默认值) — 和一直以来的 Cassandra 一样。SERIAL 走 Paxos,其余走最终一致性路径,事务语句会被拒绝。
full(推荐) — 所有读写都经过 Accord。因为 Accord 知道不存在非事务性的读者,所以可以使用单副本读取和异步提交,按文档的说法,WAN 往返从 2 次降到 1 次。作为交换,指定的一致性级别会被忽略。
mixed_reads — 写入走 Accord,非 SERIAL 读取走既有路径。这种情况下,既有读取需要能看到 Accord 的写入,所以必须以请求的一致性级别做同步提交,WAN 往返总共变成 2 次。文档自己也建议「大多数用户应该从 off 直接跳到 full」。
这里出现了一个多 DC 运维者必须知道的限制。Accord 支持的一致性级别,读取只有 ONE、QUORUM、SERIAL、ALL,写入只有 ANY、ONE、QUORUM、SERIAL、ALL,仅此而已。LOCAL 系列(LOCAL_QUORUM、LOCAL_ONE、LOCAL_SERIAL)以及 TWO、THREE 都不受支持,请求不受支持的级别会被拒绝。如果你的工作负载一直依赖 DC 本地延迟来跑多区域部署,现在的 Accord 根本没有办法表达这种需求。CEP-15 也只把 LOCAL_SERIAL 的替代方案(非全局操作模式)列为「未来目标」。此外,文档里还明确写着,就算把提交一致性级别设成 ONE,实际也会被悄悄按 QUORUM 执行。
在性能方面,文档也老实写下了一些代价。带 LIMIT 的分区范围读取,会按每个节点的命令存储(command store,默认值为可用处理器数量)个数被拆分执行,再在协调者(coordinator)处合并,因此内存和 CPU 会按比例被放大。分页是每页各自独立的事务,所以不保证整体结果的线性一致性(linearizability),分区范围读取也不会产生 strict-serializable 的结果。内部文档明确指出,范围事务比 key 事务的依赖追踪成本更高、冲突也更频繁。
迁移现有表的代价 — 迁移不是免费的
新建的表倒是简单,用 WITH transactional_mode = 'full' 建就行了,但已有的表得走一遍在线迁移。原因很有意思 — Accord 在事务恢复时需要重放读取,所以读取必须是确定性的,而非 SERIAL 的写入会破坏这种确定性。因此,迁移分为两个阶段。
- ALTER 之后的第一阶段 — 非 SERIAL 写入走 Accord(以请求的一致性级别做同步提交),SERIAL 仍留在 Paxos 上。需要跑一次数据修复(全量或增量),Accord 才能安全地读取已有数据。
- 第二阶段 — 所有操作都走 Accord。不过,每个 key 都要先做一次 Paxos key 修复,至少会多出一次 WAN 往返,而且因为 Paxos 的写入只有在 QUORUM 时才可见,所以 Accord 读取时也得用 QUORUM。迁移完成需要全量修复和 Paxos 修复两者都做 — 增量修复不行,因为它无法包含 Paxos 修复所传播的数据。
触发修复没有自动化机制。按文档所说,如果你本来就在定期跑兼容的修复,迁移迟早会完成;否则就得用 nodetool consensus_admin finish-migration 直接推进。触碰到仍在迁移中的范围的请求,因为要在两套系统之间来回,至少会多付出一次 WAN 往返。值得庆幸的是,回退路径(从 full 到 off)也有文档记载 — 只需一个阶段,做完 Accord 修复后回到 Paxos。
从运维角度总结一下:迁移期间延迟会上升,全量修复这项繁重的工作是必需的,而编排这一切的责任在你身上(6.0 的 CEP-37 自动修复能在多大程度上减轻这个负担,目前还没有实测案例)。
与此同时,5.x 里能用到什么 — SAI 与向量搜索的现实
在 Accord 还停留在 alpha 阶段的这段时间里,5.0(2024-09-05 GA)引入的 SAI 和向量搜索已经以 GA 状态运行了将近两年。这一块,只要把预期设对就好。
关于 SAI(Storage-Attached Indexing),官方 FAQ 自己就划清了界限 — SAI 不是企业级搜索引擎,本质上是一个过滤引擎。字符串运算符只有等号和 CONTAINS 系列,不支持 LIKE。索引的磁盘开销相对未索引数据有 20~35% 的记录,如果在一条查询里用 AND 组合三个以上的 SAI 索引,也只有两个会被当作索引处理,其余的会退化为后过滤。没有分区 key 的查询依然是 scatter-gather,文档也直接警告,高基数列在最坏情况下可能变成整个集群的全表扫描。这就是为什么 SAI 是对数据建模基本原则(以分区 key 为中心的设计)的补充,而不是替代。
向量搜索基于 JVector(DiskANN 系列的 ANN 库),VECTOR 类型最多支持 8K(2 的 13 次方)维,ANN 查询的 LIMIT 必须在 1,000 以下。相似度函数有余弦(默认)、内积、欧氏距离三种,文档记下的一个陷阱值得记住 — 内积更快(按文档的说法快 50%),但如果对未归一化的嵌入使用内积,会悄无声息地产生毫无意义的结果。索引选项一旦创建就不能更改,只能先删除再重建。与其说它能替代专用的向量数据库,不如说它更适合作为一个选项 — 当你想把嵌入放在已经存在于 Cassandra 里的数据旁边时使用。各引擎之间的对比,我在2026 年数据库引擎深度对比一文里写过。
那么,什么时候才该开始关心
如果你现在就在生产环境用。 留在 5.0.x。因为 4.0 会随 6.0 发布而终止支持、4.1 会随 7.0 而终止支持(按官方下载页面),转向 5.0 的升级压力已经是现实存在的了。请提前记下一点:6.0 的升级计划里包含 TCM 迁移这项独立的运维步骤。
值得去测试 Accord 的情况。 因为要在多个分区上模拟 LWT 而堆积了大量 saga/批处理代码的工作负载,以及能接受单区域或全局 QUORUM 延迟画像的场景。如果是这样的团队,值得提前用这个 alpha 版本量一量自己工作负载的冲突模式。只是要记住,季度 alpha 没有支持也没有回补。
目前还不用操心的情况。 用 LOCAL_QUORUM 跑多 DC 的工作负载(没有办法表达这种需求)、依赖计数器表的工作负载(用不了事务)、期待 RDBMS 式交互事务的迁移(它是一次性模型),以及所有想看基准测试数字再做决定的情况 — 反正官方数字还没有,没什么可看的。
结语
总结一下。Accord 是一个雄心勃勃的设计 — 无 leader、多分区、strict-serializable 事务 — 它 2021 年提出的方案,直到 2026 年才以可运行的形式落地。代码已经进了 6.0-alpha1,但那个 alpha 更接近「确认能构建的日期标签」,发布说明还是占位符,性能方面除了协议的往返次数之外,也没有任何官方资料能多说什么。语法上的一次性模型、LOCAL 一致性级别的缺失,以及需要全量修复的迁移 — 这三点是当下实实在在的边界。
反过来说,这也是一个难得的时期 — 做判断所需的第一手资料全都公开着。仅凭 CHANGES.txt、仓库内文档和 dev 邮件列表,就能拼出这么大一幅图景。等到 beta 发布、基准测试数字开始出现时,我会再回来检查一遍 — 在那之前,关于这个功能的任何决策,建议直接读上面这些文档,而不是看发布会的幻灯片。
参考资料
- CEP-15: General Purpose Transactions — Apache Cassandra Wiki
- CASSANDRA-17092 — CEP-15: Accord Beta (JIRA,2021-10-30 创建 / 2025-01-21 Fixed)
- [RELEASE] Apache Cassandra 6.0-alpha1 released — dev 邮件列表公告 (2026-04-03)
- 季度 alpha / 发布节奏提案讨论串 (2025-11)
- Branch cassandra-6.0 and 6.0-alpha2 — dev 邮件列表 (2026-04-09)
- [DISCUSS] 5.1 should be 6.0 — dev 邮件列表 (2024-12-10)
- 6.0-alpha1 官方构建产物 (archive.apache.org, 2026-03-21)
- cassandra-6.0 CHANGES.txt · NEWS.txt
- Accord Transactions 用户指南 (trunk)
- Onboarding to Accord — 运维指南 (cassandra-6.0)
- CQL on Accord — 内部设计文档 (cassandra-6.0)
- SAI FAQ (cassandra-5.0) · 向量搜索数据建模 (cassandra-5.0)
- Apache Cassandra 发布 / EOL 状态 — endoflife.date · 官方下载页面
현재 단락 (1/72)
在 Cassandra 里,「事务」长期以来都是个半吊子的词。LWT(轻量级事务)是基于 Paxos 的 CAS,所以只能在单个 key 内起作用 — 用 [Cassandra 文档自己的说法](ht...