当我将批量插入仅发送到一个表时,每行作为唯一键具有条件(如果不存在),并且即使其中一行存在也存在问题。
我需要每行插入批次,而不是整批。 假设我的表“用户”只有一列“user_name”并包含“jhon”行,现在我正在尝试导入新用户:
BEGIN BATCH
INSERT INTO "users" ("user_name") VALUES ("jhon") IF NOT EXISTS;
INSERT INTO "users" ("user_name") VALUES ("mandy") IF NOT EXISTS;
APPLY BATCH;
它不会插入“mandy”,因为“jhon”存在,我该怎么办才能隔离它们?
我有很多行要插入大约100-200K所以我需要使用批处理。
谢谢!
答案 0 :(得分:2)
首先:您描述的内容记录为预期行为:
在Cassandra 2.0.6及更高版本中,您可以批量处理在Cassandra 2.0中作为轻量级事务引入的条件更新。只有对同一分区所做的更新才能包含在批处理中,因为底层Paxos实现在分区的粒度下工作。您可以将具有条件的更新分组,但是当批次中的单个语句使用条件时,将使用单个Paxos提议提交整个批次,就好像批处理中包含的所有条件都适用一样。
这基本上证实了:您的更新是针对不同的分区,因此只会使用一个Paxos提案,这意味着整个批次将成功,或者不会。
也就是说,对于Cassandra来说,批量并不意味着加速和批量加载 - 他们意味着要创建伪原子逻辑操作。来自http://docs.datastax.com/en/cql/3.1/cql/cql_using/useBatch.html:
经常错误地使用批次来尝试优化性能。未记录的批处理需要协调程序来管理插入,这会对协调程序节点造成沉重的负担。如果其他节点拥有分区密钥,则协调器节点需要处理网络跃点,导致传送效率低下。在对同一分区键进行更新时使用未记录的批次。
协调器节点可能还需要努力处理已记录的批处理,同时保持表之间的一致性。例如,在接收批处理时,协调器节点将批日志发送到另外两个节点。如果协调器发生故障,其他节点将重试该批处理。整个群集都会受到影响。使用已记录的批处理来同步表,如下例所示:
在您的架构中,每个INSERT都是一个不同的分区,这将在协调器上添加很多负载。
您可以使用具有异步执行的客户端运行200k插入,并且它们可以非常快地运行 - 可能与您通过批处理一样快(或更快)。