Cassandra 是否只在一个簇键中插入差异生成墓碑
Do Cassandra inserts differeing in only a cluster key generate tombstones
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 的 "real" 记录的更新来实现?
据我了解,Cassandra 不会删除 insert/update 上的记录(更新插入),它只是将新信息记录为写入,不会创建逻辑删除。读取信息时,它将利用时间戳来确定哪些数据是最新的。旧记录在压缩期间被删除,而逻辑删除将一直存在到宽限期到期(默认 10 天)以帮助保持删除的一致性,以便它们不会复活。
您的假设不正确。在您的模式中,p
是分区(或 "row")键,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"
其中墓碑会有更大的时间戳,因此 "cover" 原始值,直到压缩清除它。具体何时发生取决于许多因素([=19= 的值]、压缩策略、工作负载等)。
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 的 "real" 记录的更新来实现?
据我了解,Cassandra 不会删除 insert/update 上的记录(更新插入),它只是将新信息记录为写入,不会创建逻辑删除。读取信息时,它将利用时间戳来确定哪些数据是最新的。旧记录在压缩期间被删除,而逻辑删除将一直存在到宽限期到期(默认 10 天)以帮助保持删除的一致性,以便它们不会复活。
您的假设不正确。在您的模式中,p
是分区(或 "row")键,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"
其中墓碑会有更大的时间戳,因此 "cover" 原始值,直到压缩清除它。具体何时发生取决于许多因素([=19= 的值]、压缩策略、工作负载等)。