每个 POST 请求执行多次插入

问题描述

我们有一个场景,对于下面的架构,在 Cassandra 中,每个插入都发生在给定 id_2 的每个 id_1

CREATE      TABLE  IF    NOT    EXISTS my_table (
  id_1                   UUID,id_2                   UUID,textDetails            TEXT,PRIMARY KEY (id_1,id_2)
);

单个 POST 请求正文包含多个 id_2 值的详细信息。这会在单个表上触发每个单个 POST 请求的多个插入。

每个 INSERT 查询的执行如下所示:

insertQueryString = "INSERT INTO my_table (id_1,id_2,textDetails) " + "VALUES (?,?,?) IF NOT EXISTS"
    cassandra.Session.Query(insertQueryString,id1,id2,myTextDetails).Exec();

1

Cassandra 是否确保每个 POST 请求在单个表上多次插入的数据一致性?每个 POST 请求都在 Go 例程(线程)上处理。后续的 GET 请求应确保检索一致的数据(通过 POST 插入)

使用 BATCH 语句在暂存和生产中存在“批量过大”问题。 https://github.com/RBMHTechnology/eventuate/issues/166

2

我们有两个数据中心(用于 Cassandra),每个数据中心有 3 个副本节点。

查询操作(POST请求)和就绪查询操作(GET请求)需要设置什么一致性级别,以保证完全一致

解决方法

这里有多个问题:

  • 应使用批处理 very carefully in Cassandra - 仅当您将数据插入同一分区时。如果您将数据插入到多个分区中,那么最好使用并行执行的 separate queries(但您可以为每个分区键收集多个条目并对其进行批处理)。
  • 您正在使用 IF NOT EXISTS 并且它是针对同一个分区完成的 - 因此它会导致多个节点之间的冲突(请参阅 lightweight transactions 上的文档),并且它需要从磁盘读取数据,因此它大大增加了节点的负载。但是您真的需要仅在该行不存在的情况下才插入数据吗?如果行已经存在,有什么问题?在执行 INSERT 时覆盖 Cassandra 中的数据更容易,因为它不需要从磁盘读取数据。

关于一致性级别 - QUORUM(或 LWT 的 SERIAL)将为您提供强一致性,但代价是延迟增加(因为您需要等待另一个 DC 的答复),并且缺乏容错能力 - 如果您输了另一个 DC,那么您的所有查询都将失败。在大多数情况下,LOCAL_QUORUM 就足够了(在 LWT 的情况下为 LOCAL_SERIAL),它将提供容错能力。我建议阅读this whitepaper,了解在 Cassandra 之上构建容错应用程序的最佳实践。