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

Does add new value/update existing value in map in cassandra create tombstones?

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

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

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

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

是否会更新旧值以映射(如果 2009 键之前在映射中存在)是否会为旧值或任何其他类型的墓碑创建墓碑?

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

这意味着将在 read-time 检索 2009 年的旧值和新值,并且 Cassandra 将 filter-out 除了最近的以外的所有值。此外,根据自第一次写入 teams 以来经过的时间,旧值和新值完全有可能写入不同的 SSTable 文件,这意味着 read/reconciliation 过程将花费更长的时间.

因此虽然这不会创建墓碑,但它会产生类似的效果,因为大量废弃数据(从 in-place writes/updates)到相同的值会导致性能随着时间的推移变慢。

它不会创建逻辑删除,因为您正在使用 + 更新 集合。如果您改为创建一个新集合(在本例中为映射),则会创建墓碑,如下所示:

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

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

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

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

$CASSANDRA_HOME/bin/nodetool cfstats keyspace.table