【发布时间】:2015-03-02 19:15:27
【问题描述】:
Cassandra(第 2 版)支持哪些类型的墓碑?根据this它支持的文章(以CQL术语):
- 一行的特定列。
- 静态列。
- 分区键的所有行。
我是否遗漏了其他类型的墓碑?删除特定(CQL)行?是否有任何特殊的墓碑来支持删除集群键或类似的范围?在规划模式以避免过多的墓碑时,了解此信息很有用。
【问题讨论】:
标签: cassandra cassandra-2.0 tombstone
Cassandra(第 2 版)支持哪些类型的墓碑?根据this它支持的文章(以CQL术语):
我是否遗漏了其他类型的墓碑?删除特定(CQL)行?是否有任何特殊的墓碑来支持删除集群键或类似的范围?在规划模式以避免过多的墓碑时,了解此信息很有用。
【问题讨论】:
标签: cassandra cassandra-2.0 tombstone
墓碑是放置在指示删除的行中的标记。它们可以存在于不同的位置、列或列的范围内,或者整行。下面的例子展示了普通类型的墓碑(范围类型这里不涉及)。
在规划架构时,您根据正在执行的查询类型对表进行建模,而不是使用一张表,您可能会发现数据在许多表中重复。这些表经过优化以服务传入的读取和写入。下面的链接应该为您提供有关使用 Cassandra 进行数据建模的一些良好背景:
http://www.datastax.com/resources/data-modeling
我的例子:我创建了一个表并插入了一些数据,然后使用nodetool flush 生成了一些 sstables。使用sstable2json 工具,您可以看到已删除的行,如果它是一整行,它看起来与单列略有不同,但本质上它仍然只是一个标记:
这是包含所有数据的表格:
$ ~/dse-4.5.1/resources/cassandra/bin/sstable2json ./dse-data/results/ts1/results-ts1-jb-1-Data.db
[
{"key": "3136","columns": [["","",1417814256390000], ["col2","26",1417814256390000], ["col3","36",1417814256390000], ["id","id16",1417814256390000]]},
{"key": "3133","columns": [["","",1417814218246000], ["col2","23",1417814218246000], ["col3","33",1417814218246000], ["id","id13",1417814218246000]]},
{"key": "3135","columns": [["","",1417814244766000], ["col2","25",1417814244766000], ["col3","35",1417814244766000], ["id","id15",1417814244766000]]},
{"key": "3134","columns": [["","",1417814230711000], ["col2","24",1417814230711000], ["col3","34",1417814230711000], ["id","id14",1417814230711000]]},
{"key": "3132","columns": [["","",1417814207910000], ["col2","22",1417814207910000], ["col3","32",1417814207910000], ["id","id12",1417814207910000]]},
{"key": "3131","columns": [["","",1417814197094000], ["col2","21",1417814197094000], ["col3","31",1417814197094000], ["id","id11",1417814197094000]]},
{"key": "31","columns": [["","",1417814185270000], ["col2","2",1417814185270000], ["col3","3",1417814185270000], ["id","id1",1417814185270000]]}
]
这是cqlsh中的第一个删除:
cqlsh:results> delete from ts1 WHERE col1 = '1';
cqlsh:results> delete id from ts1 WHERE col1 = '11';
这是刷新后的结果 sstable:
[datastax@DSE3 ~]$ ~/dse-4.5.1/resources/cassandra/bin/sstable2json ./dse-data/results/ts1/results-ts1-jb-2-Data.db
[
{"key": "3131","columns": [["id","54822130",1417814320400000,"d"]]},
{"key": "31","metadata": {"deletionInfo": {"markedForDeleteAt":1417814302304000,"localDeletionTime":1417814302}},"columns": []}
]
这是 cqlsh 中的下一个删除:
cqlsh:results> delete col2 from ts1 WHERE col1 = '12';
这是刷新后的结果 sstable:
[datastax@DSE3 ~]$ ~/dse-4.5.1/resources/cassandra/bin/sstable2json ./dse-data/results/ts1/results-ts1-jb-3-Data.db
[
{"key": "3132","columns": [["col2","5482220b",1417814539434000,"d"]]}
]
当压缩发生时,所有这些 sstable 被合并到一个 sstable 中,然后删除的行仍然存在,但标记为删除,我们可以在运行压缩后再次看到这一点(查找带有时间戳的 d 标志) :
[datastax@DSE3 ~]$ ./dse-4.5.1/bin/nodetool compact
[datastax@DSE3 ~]$ ~/dse-4.5.1/resources/cassandra/bin/sstable2json ./dse-data/results/ts1/results-ts1-jb-4-Data.db
[
{"key": "3136","columns": [["","",1417814256390000], ["col2","26",1417814256390000], ["col3","36",1417814256390000], ["id","id16",1417814256390000]]},
{"key": "3133","columns": [["","",1417814218246000], ["col2","23",1417814218246000], ["col3","33",1417814218246000], ["id","id13",1417814218246000]]},
{"key": "3135","columns": [["","",1417814244766000], ["col2","25",1417814244766000], ["col3","35",1417814244766000], ["id","id15",1417814244766000]]},
{"key": "3134","columns": [["","",1417814230711000], ["col2","24",1417814230711000], ["col3","34",1417814230711000], ["id","id14",1417814230711000]]},
{"key": "3132","columns": [["","",1417814207910000], ["col2","5482220b",1417814539434000,"d"], ["col3","32",1417814207910000], ["id","id12",1417814207910000]]},
{"key": "3131","columns": [["","",1417814197094000], ["col2","21",1417814197094000], ["col3","31",1417814197094000], ["id","54822130",1417814320400000,"d"]]},
{"key": "31","metadata": {"deletionInfo": {"markedForDeleteAt":1417814302304000,"localDeletionTime":1417814302}},"columns": []}
]
现在这个表将保持这种状态,直到我们到达 gc_grace_seconds,然后在下一次压缩时,行实际上会消失,注意我们删除 gc_grace_seconds 然后运行压缩:
cqlsh> ALTER TABLE results.ts1 WITH gc_grace_seconds=500;
cqlsh> exit
[datastax@DSE3 ~]$ ./dse-4.5.1/bin/nodetool compact results;
[datastax@DSE3 ~]$ ./dse-4.5.1/resources/cassandra/bin/sstable2json ./dse-data/results/ts1/results-ts1-jb-5-Data.db
[
{"key": "3136","columns": [["","",1417814256390000], ["col2","26",1417814256390000], ["col3","36",1417814256390000], ["id","id16",1417814256390000]]},
{"key": "3133","columns": [["","",1417814218246000], ["col2","23",1417814218246000], ["col3","33",1417814218246000], ["id","id13",1417814218246000]]},
{"key": "3135","columns": [["","",1417814244766000], ["col2","25",1417814244766000], ["col3","35",1417814244766000], ["id","id15",1417814244766000]]},
{"key": "3134","columns": [["","",1417814230711000], ["col2","24",1417814230711000], ["col3","34",1417814230711000], ["id","id14",1417814230711000]]},
{"key": "3132","columns": [["","",1417814207910000], ["col3","32",1417814207910000], ["id","id12",1417814207910000]]},
{"key": "3131","columns": [["","",1417814197094000], ["col2","21",1417814197094000], ["col3","31",1417814197094000]]}
]
请注意键 31 的行以及键 3132 的行中的 col1 和键 3131 的行中的 id
为了清楚起见,我的表架构:
cqlsh:results> DESCRIBE TABLE ts1 ;
CREATE TABLE ts1 (
col1 text,
col2 text,
col3 text,
id text,
PRIMARY KEY ((col1))
) WITH
bloom_filter_fp_chance=0.010000 AND
caching='KEYS_ONLY' AND
comment='' AND
dclocal_read_repair_chance=0.100000 AND
gc_grace_seconds=864000 AND
index_interval=128 AND
read_repair_chance=0.000000 AND
replicate_on_write='true' AND
populate_io_cache_on_flush='false' AND
default_time_to_live=0 AND
speculative_retry='99.0PERCENTILE' AND
memtable_flush_period_in_ms=0 AND
compaction={'class': 'SizeTieredCompactionStrategy'} AND
compression={'sstable_compression': 'LZ4Compressor'};
作为脚注,sstable2json 输出中的墓碑标记如下:
e - 过期的 TTL
d - 删除值(墓碑)
t - 删除的值范围(范围墓碑)
【讨论】:
除了@markc 的答案之外,还有一个列范围墓碑,每当您使用集合时都会显示。我们有一个名为“tags”的set<text> 列,每当我们插入一行时,我们都会得到其中的一个(即使我们只是将它设置为 null,就像在本例中一样):
["1381316637599609:45787829:tags:_","1381316637599609:45787829:tags:!",1438264650252000,"t",1438264650],
我们认为“t”代表墓碑。 This blog post 详细介绍了这种墓碑的另一个例子。
【讨论】: