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?
答案 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:d
,2: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天),以帮助保持删除的一致性,以便它们不会被复活。