Cassandra分页遍历ResultSet及使用Reactive Streams时,并发修改是否影响结果?
Cassandra分页遍历与并发修改的可见性问题
直接说结论:分页遍历ResultSet时,并发插入/删除操作是否会体现在查询结果里,核心取决于查询的一致性级别,以及你用的分页机制——包括Reactive Streams接口的底层逻辑。
1. 一致性级别是核心决定因素
Cassandra没有全局的查询快照,每次分页请求都是独立的读操作:
- 如果你用的是
QUORUM/LOCAL_QUORUM这类高一致性级别:每次分页请求都会去读取满足一致性要求的最新已提交数据。也就是说,分页过程中完成的写入操作,只要符合一致性规则,后续的分页页就会看到这些修改。 - 如果你用的是
ONE/LOCAL_ONE这类低一致性级别:结果是不确定的——可能读到旧数据,也可能读到新数据,完全看你读取的副本有没有同步完最新的写入。
2. Reactive Streams接口的本质
Java Driver的Reactive Streams实现,只是把分页请求包装成了异步流式操作,底层还是依赖Cassandra的PagingState机制,所以遵循上面的一致性规则:
- 它不会给你创建一个固定的快照,流式推送的每一页数据,都是实时从集群读取的。所以在流处理过程中,只要新写入的操作同步到了符合一致性要求的副本,后续的流元素就会包含这些修改。
- 举个例子:你发起了一个Reactive查询,开始读取第一页数据;这时候另一个操作插入了一条符合查询条件的记录,当流请求第二页时,如果一致性级别是QUORUM,且这条插入已经同步到足够多的副本,第二页就会包含这条新记录。
3. 特殊场景的额外影响
如果你的查询用到了ALLOW_FILTERING,或者是基于聚类键的范围查询,情况会更复杂:
- Cassandra可能会跨多个节点扫描数据,分页过程中如果某节点还没被扫描到,此时在该节点上的修改就会被后续的分页请求读到;如果是已经扫描过的节点,修改不会影响已经返回的结果。
4. 如何让分页结果不受并发修改影响
Cassandra本身不支持全局快照查询,但可以通过这些方式规避:
- 在应用层加版本号:查询时带上“版本≤查询发起时的版本”的条件,过滤掉之后的修改。
- 用轻量级事务:比如结合
IF EXISTS/IF NOT EXISTS,但只适用于单分区的场景。 - 物化视图:针对查询创建
FROZEN的物化视图,把查询结果固定下来,但会增加存储和写入成本,只适合读多写少的场景。
内容的提问来源于stack exchange,提问作者pdxleif
相关产品推荐
相关产品推荐

