Cassandra只在群集密钥中插入差异生成墓碑

时间:2015-10-30 14:04:56

标签: cassandra tombstone

Cassandra如何处理更新和群集密钥?

  • Cassandra一旦写完就永远不会真正更新记录,它会将旧版本标记为使用 tombstone 删除并记录旧版本和新版本,直到旧版本最终被内务处理过程删除:垃圾收集的形式。
  • 群集密钥是使用一些魔术来实现的,该魔法将数据记录在" real"具有分区密钥的记录。

令我印象深刻的是,这两个功能可能会相互影响很严重,导致产生过多的垃圾。

考虑这个架构:

 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?

的记录

2 个答案:

答案 0 :(得分: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的值,压缩策略,工作量等)。

答案 1 :(得分:0)

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