在 cassandra 的地图中添加新值/更新现有值是不是会创建墓碑?

Posted

技术标签:

【中文标题】在 cassandra 的地图中添加新值/更新现有值是不是会创建墓碑?【英文标题】:Does add new value/update existing value in map in cassandra create tombstones?在 cassandra 的地图中添加新值/更新现有值是否会创建墓碑? 【发布时间】:2020-11-25 22:40:09 【问题描述】:

我正在关注这个 datastax 页面:-https://docs.datastax.com/en/cql-oss/3.3/cql/cql_using/useInsertMap.html 以了解如何在 cassandra 中更新地图。但我怀疑这是否不会在以下情况下创建不需要的墓碑:-

    UPDATE cycling.cyclist_teams SET teams = teams + 2009 : 'DSB Bank - Nederland bloeit' WHERE id = 5b6962dd-3f90-4c93-8f61-eabfa4a803e

向地图添加新值(如果地图中不存在 2009)会创建任何墓碑吗?

    UPDATE cycling.cyclist_teams SET teams = teams + 2009 : 'DSB Bank - Nederland bloeit' WHERE id = 5b6962dd-3f90-4c93-8f61-eabfa4a803e2

将旧值更新到地图(如果地图中之前存在 2009 键)会为旧值或任何其他类型的墓碑创建墓碑吗?

【问题讨论】:

【参考方案1】:

它不会创建墓碑(不会删除或故意写入 null),但会“废弃”之前的值。

这意味着 2009 年的旧值和新值都将在读取时检索,并且 Cassandra 将过滤掉除最新值之外的所有值。此外,根据自第一次写入 teams 以来经过了多长时间,新旧值完全有可能被写入单独的 SSTable 文件,这意味着读取/协调过程将花费更长的时间。

因此,虽然这不会创建墓碑,但它会产生类似的效果,即大量过时的数据(来自就地写入/更新)到相同的值会导致性能随着时间的推移而变慢。

【讨论】:

所以简而言之,在地图中添加新值或更新现有值都不会创建墓碑? @Neer1009 正确。【参考方案2】:

它不会创建墓碑,因为您是 更新 集合 + 。如果您要创建一个新集合,则会创建 Tombstone,(在本例中为地图),如下所示:

UPDATE cycling.cyclist_teams SET teams = 2009 : 'DSB Bank - Nederland bloeit' WHERE id = 5b6962dd-3f90-4c93-8f61-eabfa4a803e2

Cassandra 始终以仅追加模式写入数据,唯一的区别在于,对于提交日志,它被追加到日志的末尾,而对于 memtable,它按照分区键和集群列的顺序写入。 Memtables 的数据会定期刷新到 SSTable 中。您的冲突数据最终可能会在 SSTable 中重复(具有冲突的值)。事实上,所有插入都是 upsert,除非您使用轻量级事务添加条件。

这两个值将在读取时从 a) 行缓存 (RAM)、b) 内存表 (RAM) 或 c)SSTable(HDD/SSD) 写入和检索,然后在发生冲突时将返回具有最新时间戳的数据回到司机那里。根据您的读取一致性级别 - 始终适用于 ANY 并且取决于 read_repair_chance 的其他一致性级别 - 副本内存表(RAM)中的旧值将被更新。旧的(过时的)值最终将在 SSTable(HDD/SSD) 压缩过程中被删除。

您可以试验然后检索表统计信息以查看是否有任何墓碑,方法是执行:

$CASSANDRA_HOME/bin/nodetool cfstats keyspace.table

【讨论】:

以上是关于在 cassandra 的地图中添加新值/更新现有值是不是会创建墓碑?的主要内容,如果未能解决你的问题,请参考以下文章

在 Cassandra 的现有集群(数据中心)中添加节点时面临的问题

在Cassandra中用新的键值对更新地图类型列,而不是完全覆盖地图。

即使原始模型中未指定新值,如何将新值添加到现有 MongoDB 数据库中

如何使用 Java Spring Boot 在不插入新值的情况下更新表中的现有值

将节点添加到现有 Cassandra 集群

将节点添加到 Cassandra 集群会导致现有节点上的 CPU 过载