在多语言设置中使用 cockroachdb 的 CQRS

CQRS with cockroachdb in polyglot setup

我正在考虑使用 cockroachdb 以具有 ACID 保证的第三范式写入数据。所以所有的写入都会被转移到 cockroachdb。

读取到Cassandra都可以是基于rowkey的point lookup。我相信这样的读取设置将消除对 redis 缓存的需求,因为 Cassandra 本身会提供快速读取。因此 Cassandra tables 将根据访问路径进行非规范化。

可能存在基于事件的同步,从 insert/update/delete inside cockroachdb 规范化模式到 insert/update/delete 再到 cassandra 非规范化模式。

问题 1 :

这种读/写分离是否适合使用 cockroachdb 的有效用例?目的是减少连接并实现快速读取和写入。 Cockroachdb 成为摄取事件源类数据的单一事实来源。而其他数据库,如 cassandra 和 elasticsearch 成为最终保持同步的查询预测。

问题 2 :

此设置是否适合需要自动完成 N 个报表的金融交易?根据我的理解,假设有 N SQL 语句在 cockroachdb 3NF 模式中以事务方式完成。在此之后,读取发生在 Cassandra/ElasticSearch,由于同步延迟,它还没有同步。在这种最终一致性场景中,如果用户发送另一个命令以从其他机器并行获得相同的结果,这将转到将在 cockroachdb 中查找的命令处理程序。我认为由于 CockroachDb 是 ACID 兼容的,我们将确保在查找 cockroachdb 后的命令验证步骤期间使命令无效。我相信这个 cockroachdb 会抛出乐观锁异常,因为一个写入相同 table 的事务已经在进行中。所以问题是 - 在这种情况下,我们是否也应该从 CockroachDB 而不是 Cassandra / ElasticSearch 读取?

问题 3

我想到的最后一个用例是让 cockroachdb 充当 spark 集群在聚合方面对 cassandra 的作用。我们可以在 cockroachdb 中进行聚合,它具有所有数据并存储在 cassandra 中的预聚合 tables 中。尽管 ElasticSearch 也能够进行聚合,但这里有一个问题 - 这个用例听起来是否也正确 w.r.t 使用 cockroachdb 而不是 elasticsearch 进行聚合?

作为一般准则,我建议从头开始设计系统,而不是从如此复杂的体系结构开始。如果您从 "single source of truth" 开始使用 CockroachDB,单独使用 CockroachDB 能走多远?您是否有只能通过缓存层来满足的性能要求? aggregation/reporting 需要单独的系统吗?如果答案是 "yes"、,那么 您可以开始考虑这些组件应该采用什么形式。

There could be event based sync from insert/update/delete inside cockroachdb normalized schema to insert/update/delete to cassandra denormalzied schema.

请注意,CockroachDB 尚无将更新流式传输到外部系统的好方法,因此这并不容易。

针对您的具体问题:

  1. 读取缓存可以是对系统的一个有价值的补充,但它也增加了很多复杂性,所以在您知道需要它之前不要引入它。您也可以对 SQL 数据库中的内容进行反规范化,并且 CockroachDB 的 interleaved tables 等功能可以减少对反规范化的需求。

  2. 您只对在事务中进入 CockroachDB 的读取有事务保证。这里的确切行为将取决于您的交易是如何编写的。例如,两个 "add a comment" 事务可以同时应用而不会相互冲突,具体取决于您的模式。您可能需要通过为事物提供适当的唯一 ID 或在事务开始时执行 SELECT 来防止这种情况,以确保数据库的状态符合您的预期。 (另外,不要对"optimistic lock exceptions"做太多假设。CockroachDB的并发是乐观和悲观模型的混合)

  3. 同样,这取决于。 ElasticSearch 可以做很多 CockroachDB 做不到的事情,而且 CockroachDB 还没有(还)做很多预聚合。但是 SQL 是一种非常灵活的聚合和报告语言,因此您可以在 CockroachDB 中做您需要的事情。