【问题标题】:Cassandra SSTables and CompactionCassandra SSTables 和压缩
【发布时间】:2012-02-13 15:06:46
【问题描述】:

所以我正在研究 Cassandra 并试图了解架构,我正在阅读 wiki 中的以下页面: http://wiki.apache.org/cassandra/MemtableSSTable

所以,按照这里的工作流程,你发送一个更新你的表的请求,这个请求被写入一个 CommitLog,然后写入一个称为 Memtable 的内存表(可以从 Commitlog 重建,以防系统失败)。一旦 Memtable 达到一定大小,它会将整个 Memtable 刷新到磁盘上的 SSTable 中,该 SSTable 不能再被修改,只能在压缩期间合并。当您达到可配置数量的 SSTable 时,您会进行压缩,这基本上会合并结果以释放磁盘空间并创建一个新的和改进的最新 SSTable。如果我在这里理解任何错误,请纠正我。

现在我有几个关于压缩的问题。首先,这个手术有多贵?如果我在磁盘上有两个 SSTable 时要求进行压缩,这是否会令人望而却步,或者等到半夜使用量下降时我会得到更好的服务吗? 如果我有多个(但很小)SSTables 与有几个但非常大的 SSTables 相比,压缩会更好吗?有很多未压缩的 SSTable 会影响读取性能吗?并发如何处理这个问题:如果我从这些 SSTable 中读取数据,那么有人会执行插入操作,将新的 Memtable 刷新到磁盘,进而导致压缩?

您能提供的任何有关这方面的信息和经验都会很棒!

【问题讨论】:

    标签: nosql cassandra


    【解决方案1】:

    尝试回答每个问题:

    首先,这项手术有多贵?

    压缩必须复制它正在压缩的 SSTables 中的所有内容(减去来自墓碑或覆盖的任何湮灭)。然而,这比最初看起来要便宜,因为压缩使用纯顺序 IO,这在旋转磁盘上既好又快。

    如果我在磁盘上有两个 SSTable 时要求进行压缩,这是否会令人望而却步,或者我最好等到半夜使用量下降时再提供服务?

    这意味着您的写入成本会大大增加;想象每次写入都会导致一个新的 SSTable;因此,每次写入都必须压缩之前的所有写入。写 N 个项目的成本是 N^2。

    一个更好的想法是采用类似于 Acunu 的双倍数组使用的压缩策略:将每个 SSTable(又名数组)存储在一个“级别”中,并在一个级别中有两个数组时压缩它们,将输出数组提升到下一级。可以证明这可以摊销到每次写入的 O((log N) / B) 顺序 IO,同时将数组的数量限制为 O(log N)。

    这个方案在Cassandra 的(开源)存储引擎Cassandra 中实现。有关详细信息,请参阅此处:

    注意我为 Acunu 工作

    如果我有多个(但很小)SSTable 与有几个但非常大的 SSTable 相比,压缩会更好吗?

    使用较小的 SSTable 进行压缩将花费更少的时间,但您将不得不做更多的事情。它的马换课程,真的。但是,SSTable 计数和大小确实会影响读取性能(请参阅下一个问题)

    拥有大量未压缩的 SSTable 会影响读取性能吗?

    对于点读,不是很多:Cassandra(和 Castle)有布隆过滤器,以避免在知道密钥不存在时查看 SSTable,并且可以在找到正确的值时提前终止(通过使用时间戳关于值和 SSTables)。

    但是,对于 get_slice 查询,您不能提前终止,因此您必须访问每一个可能在您的行中包含值的 SSTable - 因此,如果您有很多,您的 get_slices 会更慢。

    get_range_slices 的情况更糟,不能使用布隆过滤器,每次调用都必须访问每个 SSTable。这些调用的性能将与您拥有的 SSTable 数量成反比。

    更重要的是,对于数千个 SSTable,布隆过滤器误报率 (~1%) 将开始受到影响,因为每次查找您都必须查看 10 个不包含该值的 SSTable!

    并发如何处理这个问题:如果我从这些 SSTables 中读取数据,然后有人执行插入操作,将新的 Memtable 刷新到磁盘,进而导致压缩?

    在 Cassandra 中,一旦内存中不再有对 SSTable 的引用(由垃圾收集器决定),就会从磁盘中删除 SSTable。所以读取不用担心,旧的 SSTables 会被懒惰地清理掉。

    谢谢

    汤姆

    【讨论】:

    • 谢谢!只是几个澄清的问题:当你说“想象每次写入都会创建一个新的 SSTable”时,你的意思是假设你有一个非常大的写入,对吗?其次,你能解释一下为什么读取不需要担心 SSTables 消失吗?我的意思是,如果我必须阅读 N SSTables,我已经阅读了一半,然后在我完成之前进行压缩删除其余部分,这不是问题吗?
    • > 当你说“想象每次写入都会创建一个新的 SSTable”时,你的意思是假设你有一个非常大的写入,对吗?我这样做只是为了简化数学。实际上,您将有一批 (B) 写入创建一个新的 SSTable,但我认为对于 N 次写入,这只是 O(N^2 / B),对于每次写入,结果为 O(N/B)(即与 O((log N) / B) 相比,确实很大
    • > 其次,你能解释一下为什么读取不需要担心 SSTables 消失吗?在 Castle 中,我们引用了每个 SSTable 的计数;在读取操作开始时,我们增加每个 SSTable 的引用计数,以阻止它们消失。当引用计数变为零时(作为合并的结果或读取完成时),该表实际上被删除。我们还有一些技巧可以加快速度。我假设 Cassandra 做了类似的事情,但是使用了垃圾收集器。
    • acunu.com 不适合我,isitdownorjust.me/acunu-com 同意
    【解决方案2】:

    我在这里写过 Cassandra 1.0 支持的不同压缩策略:http://www.datastax.com/dev/blog/leveled-compaction-in-apache-cassandra

    tldr:分级压缩在压缩方面更具侵略性,因此建议用于具有大量读取的工作负载。

    【讨论】:

      猜你喜欢
      • 2015-04-10
      • 1970-01-01
      • 2014-10-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-10
      • 2012-08-04
      • 1970-01-01
      • 2019-02-12
      相关资源
      最近更新 更多