同步SELECT + INSERT与INSERT之间的性能差异...如果不是CQL中的EXISTS?

v_k*_*hna 3 cql cassandra cql3

我有一个CQL表(cql 3,cassandra 2.0.*),它看起来像:

CREATE TABLE IF NOT EXISTS user_things (
   user_id bigint,
   thing_id bigint,
   created_at timeuuid,
  PRIMARY KEY (user_id, thing_id)
);
Run Code Online (Sandbox Code Playgroud)

我想做插件

INSERT INTO user_things (user_id, thing_id, created_at) VALUES (?, ?, now())
Run Code Online (Sandbox Code Playgroud)

但仅当行不存在时.

我可以在两个同步语句中执行此操作(首先是SELECT,如果SELECT没有返回行,则返回INSERT)或者我可以使用INSERT ... IF NOT EXISTS.

CQL文档状态"但是,请注意,使用IF NOT EXISTS将产生不可忽略的性能成本(内部,Paxos的将被使用),所以这应该谨慎使用."

我想知道是否有人做过基准测试,看看如果我们有很多这样的操作发生了什么更有效率?(说几百秒)

Jim*_*yer 6

这在很大程度上取决于您使用的拓扑结构.如果将其限制为本地数据中心(使用LOCAL_SERIAL)并使用较小的复制因子,则IF NOT EXISTS非常快.如果您尝试在多个数据中心使用它或使用更高的复制因子,那么它会显着减慢.有一张开放可以改善其性能,所以希望很快就会完成,因为它目前是一个过于昂贵的操作,有很多往返.

另一件会减慢IF NOT EXISTS的事情就是当你在群集行上使用它时.当您的表只有复合分区键而没有聚类列时,它似乎工作得最快.

如果你在写入路线之前读取,那么你还有其他问题要处理.首先你会有一个竞争条件,因为如果两个客户在同一时间读取,然后两个都决定写一个,你会得到一个覆盖另一个,这种方式使得读取毫无意义(请参阅此处的另一种方法) :碰撞检测.如果以某种方式你不介意竞争条件,并使用像ONE这样的低一致性来进行读写,那么它可能会胜过IF NOT EXISTS.

几乎你必须为你的系统和架构进行基准测试,以确定哪一个在你的情况下更快.

  • 是的,这就是我的意思。 (2认同)

Ale*_*er 0

虽然我自己没有做过基准测试,但我想这两个同步语句的运行速度会更快,因为简单来说,它没有做那么多。它执行两个精心设计的 CQL 查询,而另一种方法涉及节点之间至少 4 个通信“阶段”。

但是,如果您确实使用此方法,您是否能够保证这些查询以原子方式执行,并且在运行 SELECT 和运行 INSERT 之间的时间内不会出现具有相同 user_id 和 thing_id 的 INSERT?避免这种情况的需要通常是推动 Cassandra 和 Paxos 中使用轻量级事务的原因。