【问题标题】:What types of tombstones does Cassandra support?Cassandra 支持哪些类型的墓碑?
【发布时间】:2015-03-02 19:15:27
【问题描述】:

Cassandra(第 2 版)支持哪些类型的墓碑?根据this它支持的文章(以CQL术语):

  • 一行的特定列。
  • 静态列。
  • 分区键的所有行。

我是否遗漏了其他类型的墓碑?删除特定(CQL)行?是否有任何特殊的墓碑来支持删除集群键或类似的范围?在规划模式以避免过多的墓碑时,了解此信息很有用。

【问题讨论】:

    标签: cassandra cassandra-2.0 tombstone


    【解决方案1】:

    墓碑是放置在指示删除的行中的标记。它们可以存在于不同的位置、列或列的范围内,或者整行。下面的例子展示了普通类型的墓碑(范围类型这里不涉及)。

    在规划架构时,您根据正在执行的查询类型对表进行建模,而不是使用一张表,您可能会发现数据在许多表中重复。这些表经过优化以服务传入的读取和写入。下面的链接应该为您提供有关使用 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 - 删除的值范围(范围墓碑)

    【讨论】:

    • 这很好地解释了墓碑“在引擎盖下”的外观。做得很好!
    • 有趣。为了清楚起见,您介意发布表架构吗?
    • 另外,在您第一次删除(和刷新)之后,我不应该期望在生成的墓碑中看到​​对“1”和/或“11”的引用吗?我很困惑。
    • 您好,很抱歉给您带来了困惑,请接受我的歉意。这些行仅在 gc_grace_seconds 过期后才真正消失。我现在已经编辑了我的帖子,应该更清楚,如果您仍然不清楚,请告诉我。谢谢!
    【解决方案2】:

    除了@markc 的答案之外,还有一个列范围墓碑,每当您使用集合时都会显示。我们有一个名为“tags”的set<text> 列,每当我们插入一行时,我们都会得到其中的一个(即使我们只是将它设置为 null,就像在本例中一样):

    ["1381316637599609:45787829:tags:_","1381316637599609:45787829:tags:!",1438264650252000,"t",1438264650],
    

    我们认为“t”代表墓碑。 This blog post 详细介绍了这种墓碑的另一个例子。

    【讨论】:

    猜你喜欢
    • 2023-03-08
    • 2019-07-09
    • 2017-08-22
    • 2018-11-20
    • 2017-02-09
    • 2015-06-14
    • 2017-02-09
    • 2017-10-03
    • 2014-09-09
    相关资源
    最近更新 更多