CockroachDB change feed设计解读

1 概述

CockroachDB支持行级别的实时数据流,可以写入kafka或者其他的存储服务,比如S3等。这类似与mysql的binlog。

2 设计

2.1 概览


CockroachDB change feed设计解读_第1张图片

2.2 流程图


CockroachDB change feed设计解读_第2张图片


如上图所示,我们可以看出cockroachDB change feed的整体思路是将feed process下放到range上,在事务提交的时候将已经完成的row收集起来,汇总写入kafka中。

其中有一些细节需要补充。

1. change feed会产生一个job,每一个job有一个唯一ID,我们可以使用这个ID暂停,中止,恢复一个job。

2. 用户可以提供一个时间戳(比如断点续传),这样cockroachDB就会从这个指定的时间戳开始继续后续的feed。

3. 默认情况下,cockroachDB会首先将table的快照按照feed发送,然后发送新增的feed。

4. range分裂或者合并的时候,会中止涉及到的range的range feed,产生一个特定的错误,这个错误会触发一次全新的range feed广播(有幂等保护),保证change feed覆盖所有的table range

5. cockroachDB只能保证至少一次捕获row change。因此会存在重复的row change。

6. change feed采用分布式任务模型,存储table数据的节点都会启动一个任务,各自独立将负责的span的数据发送到指定的sink。

7. change feed首先会处理table snapshot,然后向各个range注册range feed,对于snapshot与range feed之间产生的新的数据,range会在range feed注册时再处理一次range上的snapshot。

8. 只有range的lease holder才可以产生range feed。

2.3 限制

1. table只能有一个column family。

2. 网络抖动会造成change feed的不稳定

3. change feed会对性能造成一定的影响(5%~10%)。

4. 默认关闭change feed。

3 其他方案讨论

     3.1 异步消费rocksDB的WAL

      我认为之所以没有这样做,是因为一个roscksDB可能存储跨越多个table的数据,对这些数据进行解析和过滤成本太高,性能不能满足需求

      另外一个原因是需要修改rocksDB的源码,存在一定的技术风险

     3.2 异步消费raft log

      CockroachDB之所以没有通过异步消费raft log的原因我认为在于效率的考虑,具体原因有三个:

因为raft log中既包含了prepare的日志也包含了commit的日志,过滤无用的日志需要承担解析的代价,

另一个原因也类似,就是CockroachDB可以指定watch的范围,这种场景下消费raft log成本也比较高。

CockroachDB可以指定从某一个时间开始同步变更(这种就不需要消费table snapshot),使用raft log无法准确找到消费的点。

这是官方的设计说明文档

https://github.com/cockroachdb/cockroach/blob/master/docs/RFCS/20180501_change_data_capture.md

4 总结

cockroachDB的change feed是行级别的更新流,并不是事务级别的。这一点和tiDB不同。因为没有全局时钟,因此很难做到这一点。

cockroachDB采用分布式任务,各个节点只负责本节点上的range的change feed。

你可能感兴趣的:(CockroachDB change feed设计解读)