Cassandra - 单节点批量插入性能不佳 - table

Cassandra - poor performance with batch insert in single-node with single-table

上下文

我只有一个 Cassandra 节点,本地安装在我的 PC 上 Windows 10(Core i5、16GB 内存、SSD 驱动器)。

我创建了一个 table 这样的:

CREATE KEYSPACE covid19 WITH replication = {
    'class':              'SimpleStrategy',
    'replication_factor': '1'
};


CREATE TABLE covid19.cases (
    pesel       text,
    test_date   date,
    result      boolean,
    PRIMARY KEY ((pesel), test_date)
)
WITH CLUSTERING ORDER BY (test_date DESC);

pesel 是唯一的,一个人的 10 位数 ID。

然后我生成了 10000 行样本数据,看起来像这样:

INSERT INTO cases (pesel, test_date, result) VALUES ('0000000001', '2020-03-10', true);
INSERT INTO cases (pesel, test_date, result) VALUES ('0000000002', '2020-03-10', false);
INSERT INTO cases (pesel, test_date, result) VALUES ('0000000003', '2020-03-10', false);
INSERT INTO cases (pesel, test_date, result) VALUES ('0000000004', '2020-03-12', false);
INSERT INTO cases (pesel, test_date, result) VALUES ('0000000005', '2020-03-12', false);
INSERT INTO cases (pesel, test_date, result) VALUES ('0000000006', '2020-03-12', false);
...

最后,我使用 cqlsh 加载了数据:source 'cases.cql';

问题 1

加载 10 000 行需要 51 秒。这正常吗?

我期待 Cassandra 的插入速度超快,而这与没有事务的 SQLite 相当 (59s)。如果我在 SQLite 中用 BEGIN & COMMIT 包装插入,这需要不到一秒钟的时间。这给我们带来了另一个问题...

问题 2

批量插入。缓慢的批量插入。到单个分区,在单个节点上。

我用 BEGIN BATCHAPPLY BATCH; 包装了插入内容。在那之后,source 花了很长时间,我在超过 4 分钟标记后停止测量。

是的,我知道批量插入的错误用法。据我所知,如果需要插入到不同的分区,那么使用批量插入是一种反模式,这是有道理的。这里不是这种情况。

为什么批量插入在单个节点(因此是单个分区)上这么慢?

我在这里错过了什么?

Cassandra 不是 SQLite。它没有针对此用例进行优化(运行ning 在一台机器上)。它针对水平缩放进行了优化。您可以在本地 运行 它,但通常这仅用于测试。而且我不希望它以任何形式针对 运行ning 在 Windows.

上进行优化

https://blog.softwaremill.com/cassandra-writes-in-depth-6ea8d7581eb

查看 Cassandra 写入的工作方式

为了更详细一点,以下是每次插入都会发生的情况:

  1. 将行插入 memtable,这不仅仅是追加,因为它必须保持排序
  2. 向 CommitLog(磁盘上的文件)追加一行。这是一个追加,没有查找,但它仍然是一个磁盘操作。
  3. 在某些时候会有一些刷新操作。 Memtables 写在磁盘上,其他数据计算并附加到它们(索引,布隆过滤器)。删除所有提交日志文件。
  4. 您的客户端代码可能不是多线程的,因此需要一些时间来获取响应并发送另一个插入。

考虑到您 运行 在您的机器上(16GB!),memtable 可能小到足以触发 10000 行的多次刷新。也可能会开始一些压缩,这取决于你已经拥有的东西。

请注意,每个步骤至少涉及一次磁盘写入。台式机 SSD 不错,但不是那么好。

我检查了生产 Cassandra 集群;它得到 2000 writes/sec,写入的平均延迟小于 1 毫秒,同时还提供 2000 reads/sec 的平均延迟为 1.5 毫秒。但这发生在 Linux 服务器上,具有 60GB RAM 和 NVME SSD。

由于额外的协调工作,批次会更糟。批处理不会对您的设置有任何改进,只有 1 个节点没有什么可协调的。参见 https://medium.com/@foundev/cassandra-batch-loading-without-the-batch-keyword-40f00e35e23e