我只有一个Cassandra节点,在Windows 10(Core i5、16GB ram,SSD驱动器)的PC上本地安装。
我创建了一个这样的表:
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。
然后我生成了1万行样本数据,看起来像这样:
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';
要加载10000行,需要51秒。那正常吗?
我期望对Cassandra的插入速度非常快,而这与SQLite 无事务处理(59s)相当。如果我在SQLite中用BEGIN
和COMMIT
包装插入,这将花费不到一秒钟的时间。这给我们带来了另一个问题...
批量插入。批量插入速度慢。对于单个分区,在单个节点上。
我用BEGIN BATCH
和APPLY BATCH;
包装了插入物。之后,source
用了很长时间,经过4分钟标记后,我停止了测量。
是,我知道批量插入的用法错误。据我了解,如果批量插入需要将其插入不同的分区,则使用批量插入是一种反模式,这很有意义。这里不是这种情况。
为什么批处理在单个节点(因此是单个分区)上的插入速度如此之慢?
我在这里想念什么?
Cassandra不是SQLite。尚未针对此用例(在单台计算机上运行)进行优化。针对水平缩放进行了优化。您可以在本地运行它,但通常仅用于测试。而且我不希望它能以任何形式针对Windows进行优化。
[参见Cassandra的写在https://blog.softwaremill.com/cassandra-writes-in-depth-6ea8d7581eb上如何工作
要了解更多细节,这是您每次插入时的情况:
考虑到您是在计算机上运行此文件(16GB!),memtable可能足够小,可以触发10000行的多次刷新。也可能会开始进行一些压缩,具体取决于您已有的压缩能力。
注意,每个步骤至少涉及一次磁盘写入。台式机固态硬盘虽然不错,但效果不佳。
我检查了一个生产Cassandra集群;它获得2000次写入/秒,平均写入延迟小于1毫秒,同时还提供2000次读取/秒,平均延迟为1.5毫秒。但这会在具有60GB RAM和NVME SSD的Linux服务器上发生。
由于进行额外的协调工作,批次将变得更糟。批处理不会对您的设置有任何改善,只有1个节点没有要配合的地方。参见https://medium.com/@foundev/cassandra-batch-loading-without-the-batch-keyword-40f00e35e23e