【问题标题】:Cassandra eats up all the disk spaceCassandra 占用了所有磁盘空间
【发布时间】:2015-03-24 16:28:26
【问题描述】:

我有一个单节点 cassandra 集群,我使用当前分钟作为分区键并插入 TTL 为 12 小时的行。

我看到一些我无法解释的问题

  1. /var/lib/cassandra/data/<key_space>/<table_name> 包含多个文件,其中很多文件都非常旧(超过 12 小时,大约 2 天)
  2. 当我尝试在 cqlsh 中执行查询时,我收到很多日志,这些日志似乎表明我的表包含很多墓碑

日志:

WARN  [SharedPool-Worker-2] 2015-01-26 10:51:39,376 SliceQueryFilter.java:236 - Read 0 live and 1571042 tombstoned cells in <table_name>_name (see tombstone_warn_threshold). 100 columns was requested, slices=[-], delInfo={deletedAt=-9223372036854775808, localDeletion=2147483647}
WARN  [SharedPool-Worker-2] 2015-01-26 10:51:40,472 SliceQueryFilter.java:236 - Read 0 live and 1557919 tombstoned cells in <table_name> (see tombstone_warn_threshold). 100 columns was requested, slices=[-], delInfo={deletedAt=-9223372036854775808, localDeletion=2147483647}
WARN  [SharedPool-Worker-2] 2015-01-26 10:51:41,630 SliceQueryFilter.java:236 - Read 0 live and 1589764 tombstoned cells in <table_name> (see tombstone_warn_threshold). 100 columns was requested, slices=[-], delInfo={deletedAt=-9223372036854775808, localDeletion=2147483647}
WARN  [SharedPool-Worker-2] 2015-01-26 10:51:42,877 SliceQueryFilter.java:236 - Read 0 live and 1582163 tombstoned cells in <table_name> (see tombstone_warn_threshold). 100 columns was requested, slices=[-], delInfo={deletedAt=-9223372036854775808, localDeletion=2147483647}
WARN  [SharedPool-Worker-2] 2015-01-26 10:51:44,081 SliceQueryFilter.java:236 - Read 0 live and 1550989 tombstoned cells in <table_name> (see tombstone_warn_threshold). 100 columns was requested, slices=[-], delInfo={deletedAt=-9223372036854775808, localDeletion=2147483647}
WARN  [SharedPool-Worker-2] 2015-01-26 10:51:44,869 SliceQueryFilter.java:236 - Read 0 live and 1566246 tombstoned cells in <table_name> (see tombstone_warn_threshold). 100 columns was requested, slices=[-], delInfo={deletedAt=-9223372036854775808, localDeletion=2147483647}
WARN  [SharedPool-Worker-2] 2015-01-26 10:51:45,582 SliceQueryFilter.java:236 - Read 0 live and 1577906 tombstoned cells in <table_name> (see tombstone_warn_threshold). 100 columns was requested, slices=[-], delInfo={deletedAt=-9223372036854775808, localDeletion=2147483647}
WARN  [SharedPool-Worker-2] 2015-01-26 10:51:46,443 SliceQueryFilter.java:236 - Read 0 live and 1571493 tombstoned cells in <table_name> (see tombstone_warn_threshold). 100 columns was requested, slices=[-], delInfo={deletedAt=-9223372036854775808, localDeletion=2147483647}
WARN  [SharedPool-Worker-2] 2015-01-26 10:51:47,701 SliceQueryFilter.java:236 - Read 0 live and 1559448 tombstoned cells in <table_name> (see tombstone_warn_threshold). 100 columns was requested, slices=[-], delInfo={deletedAt=-9223372036854775808, localDeletion=2147483647}
WARN  [SharedPool-Worker-2] 2015-01-26 10:51:49,255 SliceQueryFilter.java:236 - Read 0 live and 1574936 tombstoned cells in <table_name> (see tombstone_warn_threshold). 100 columns was requested, slices=[-], delInfo={deletedAt=-9223372036854775808, localDeletion=2147483647}

我尝试了多种压缩策略,多线程压缩,我尝试使用 nodetool 手动运行压缩,也尝试使用 jmx 强制垃圾回收。

我的一个猜测是压缩不会删除墓碑文件

任何如何避免磁盘空间变得太大的想法,我最担心的是空间不足,我宁愿存储更少(通过使 ttl 更小但目前没有帮助)

【问题讨论】:

    标签: cassandra cassandra-2.0


    【解决方案1】:

    Tombstone 将使用默认配置保留 10 天。这样做的原因是为了确保离线节点在再次加入集群时能够赶上删除。您可以通过设置gc_grace_seconds 设置来配置此值。

    【讨论】:

    • 斯特凡谢谢!但是我已经试过了,目前 gc_grace_seconds 是 0。抱歉我忘了说
    • 您确定正确指定了 TTL 值(使用秒,而不是毫秒)?
    • 是的,我什至看到行被删除了,我确实看到很多墓碑,看起来所有文件都是墓碑
    • 如果你在压缩后看到墓碑,那么 gc grace 不是 0。
    【解决方案2】:

    当您说您使用分钟作为分区键时,我假设您使用时间戳作为每个分区中的集群列,以及执行插入时 12 小时的 TTL。这将在每个分区中建立墓碑,因为您永远不会删除整行(即一整分钟的分区)。

    假设你的keyspace叫做k1,你的table叫做t2,那么你可以运行:

    nodetool flush k1 t2
    nodetool compact k1 t2
    sstable2json /var/lib/cassandra/data/k1/t2/k1-t2-jb-<last version>-Data.db
    

    然后你会看到所有像这样的墓碑(标有“d”表示已删除):

    {"key": "00000003","columns": [["4:","54c7b514",1422374164512000,"d"], ["5:","54c7b518",1422374168501000,"d"], ["6:","54c7b51b",1422374171987000,"d"]]}
    

    现在,如果您删除该行(即从 k1.t2 中删除 key=3;),然后再次执行刷新、压缩和 sstable2json,您会看到它变为:

    {"key": "00000003","metadata": {"deletionInfo": {"markedForDeleteAt":1422374340312000,"localDeletionTime":1422374340}},"columns": []}
    

    所以你看到所有的墓碑都消失了,Cassandra 只需要记住整行是在某个时间被删除的,而不是在某个时间被删除的一点点。

    摆脱墓碑的另一种方法是截断整个表。当您这样做时,Cassandra 只需要记住整个表在某个时间被截断,因此不再需要保留该时间之前的墓碑(因为墓碑用于告诉其他节点某些数据已被删除,如果你可以说整个桌子在时间 x 被清空了,那么之前的细节就不再重要了)。

    那么你怎么能在你问的情况下应用这个。好吧,您可以使用小时和分钟作为分区键,然后每小时运行一次 cron 作业以删除 13 小时前的所有行。然后在下一次压缩时,该分区的所有墓碑都将被删除。

    或者每小时保留一个单独的表,然后使用 cron 作业从每小时 13 小时前截断该表。

    另一个有时有用的策略是“重用”集群键。例如,如果您每秒插入一次数据,而不是将高分辨率时间戳作为集群键,您可以使用时间模 60 秒作为集群键,并将更唯一的时间戳保留为数据字段。因此,在每一分钟的分区内,您会将昨天的墓碑(或过时的信息)更改回今天的活动行,这样您就不会在很多天内积累墓碑。

    希望这能给你一些尝试的想法。通常,当您遇到墓碑问题时,这表明您需要重新考虑一下您的架构。

    【讨论】:

      【解决方案3】:

      我有一个类似的问题,只是在我的情况下,只有一个表拒绝收缩(旧文件没有被删除,它们的存储空间不断增长)。我使用了nodetool compactionstats,看到有很多待处理的压缩任务。 另一个有趣的事情是我在 nodetool compactionstats 中看到总是显示有问题的表的压缩类型 Compaction 的压缩,而不是 Tombstone Compaction 类型的压缩,这与表现的表相反好的。 会不会是问题?

      【讨论】:

        猜你喜欢
        • 2013-11-02
        • 2015-10-28
        • 1970-01-01
        • 2011-04-30
        • 1970-01-01
        • 2016-05-10
        • 2023-01-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多