2

Cassandra 对更新和集群密钥的处理如何交互?

  • Cassandra 在写入后从不真正更新记录,它使用墓碑将旧版本标记为已删除,并同时记录旧版本和新版本,直到旧版本最终被内务处理过程删除:一种垃圾收集形式。
  • 集群键是使用一些魔术来实现的,该魔术将数据记录在只有一个分区键的“真实”记录中。

让我感到震惊的是,这两个功能可能相互作用不好,导致产生过多的垃圾。

考虑这个模式:

 CREATE TABLE t (
    p int,
    c int,
    d string,
    PRIMARY KEY ((p), c),
 );

执行以下插入后:

 INSERT INTO t (p, c, d) VALUE (1, 1, "text-1");
 INSERT INTO t (p, c, d) VALUE (1, 2, "text-2");

是否有一个带有墓碑标记的记录保存(1, 1, "text-1")数据和一个新记录保存数据(1, 1, "text-1")(1, 2, "text-2")数据?也就是说,第二次插入是否被实现为对分区键 ( p) 为 1 的“真实”记录的更新?

4

2 回答 2

2

你的假设是不正确的。在您的架构中,p是分区(或“行”)键,并且c是集群列。Cassandra 是列式存储,因此写入本质上是附加到分区的稀疏有序列的集合。可以通过创建复合行键和列名来实现额外的嵌套,在您的情况下,这将转换为如下所示的存储模型:

Row Key: 1 =>
  1:d => "text-1"
  2:d => "text-2" 

如果要插入另一个分区键,如下所示:

INSERT INTO t (p, c, d) VALUE (2, 1, "text-1");

您的存储模型如下所示:

Row Key: 1 =>
  1:d => "text-1"
  2:d => "text-2" 
Row Key: 2 =>
  1:d => "text-1"

因此,您可以观察到这些列值(1:d2:d等)是独立处理的。假设您随后删除了这些值之一:

DELETE FROM t WHERE p = 1 AND c = 1;

你的结果是:

Row Key: 1 =>
  1:d => "text-1" + [tombstone]
  2:d => "text-2" 
Row Key: 2 =>
  1:d => "text-1"

其中墓碑将具有更大的时间戳,因此“覆盖”原始值,直到压缩清除它。何时发生这种情况取决于许多因素( 的值gc_grace_seconds、压缩策略、工作负载等)。

于 2015-10-30T16:47:20.303 回答
0

据我了解,Cassandra 不会在插入/更新(upsert)时删除记录,它只是将新信息记录为写入并且不会创建墓碑。读取信息时,它将利用时间戳来确定哪些数据是最新的。旧记录在压缩过程中被删除,而墓碑将一直存在,直到宽限期到期(默认 10 天),以帮助保持删除的一致性,以免它们复活。

于 2015-10-30T15:21:15.803 回答