Cassandra SSTables和压实

时间:2012-01-18 21:43:07

标签: nosql cassandra

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

因此,要按照此处的工作流程,发送更新表的请求,将此请求写入CommitLog,然后写入名为Memtable的内存表(如果系统情况下可以从Commitlog重建)失败)。一旦Memtable达到一定的大小,它就会将整个Memtable刷新到光盘上的SSTable,它不能再被修改,只能在压缩过程中合并。当您达到可配置数量的SSTable时,您会进行压缩,这基本上会合并结果,释放磁盘空间并创建一个新的和改进的最新SSTable。如果我在这里弄错了,请纠正我。

现在我有一些关于压实的问题。首先,这项操作有多贵?如果我在光盘上有两个SSTables时要求压缩,这是否会令人望而却步,或者我会更好地服务,直到半夜使用率下降? 如果我有多个(但很小的)SSTables与一些但是非常大的SSTables,压缩会更好吗?是否有很多非压缩的SSTable会影响读取性能?并发如何与此协同工作:如果我从这些SSTable中读取,那么有人会执行一个插入操作,将新的Memtable刷新到磁盘,从而导致压缩?

您可以提供的关于此的任何信息和经验都会很棒!

2 个答案:

答案 0 :(得分:13)

尝试回答每个问题:

  

首先,这项操作有多贵?

压缩必须复制它正在压缩的SSTable中的所有内容(减去来自逻辑删除或覆盖的任何湮灭)。然而,这比起初看起来要便宜,因为压缩使用纯粹的顺序IO,这在旋转磁盘上很好而且快速。

  

如果我在光盘上有两个SSTables时要求压缩,这是否会令人望而却步,或者我会更好地等到半夜使用率下降?

这意味着您的写入会变得更加昂贵;想象每次写入都会导致新的SSTable;因此,每次写入都必须压缩所有写入之前的写入。写N项的费用为N ^ 2.

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

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

NB我为Acunu工作

  

如果我有多个(但很小的)SSTables而且有一些但是非常大的SSTables,压缩会更好吗?

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

  

有很多非压缩的SSTable会影响读取性能吗?

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

但是,使用get_slice查询时,您无法提前终止,因此您必须访问可能包含行中值的每个SSTable - 因此,如果您有很多,则get_slices将会更慢。

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

更重要的是,有数千个SSTables,布隆过滤器误报率(~1%)将开始受到伤害,因为每次查找都需要查看10个不包含该值的SSTable! / p>

  

并发如何与此协同工作:如果我从这些SSTable中读取,那么有人会执行一个插入操作,将新的Memtable刷新到磁盘上,从而导致压缩?

在Cassandra中,一旦在内存中没有对它的引用(由垃圾收集器决定),SSTable就会被删除。所以读取不需要担心,旧的SSTables会被懒散地清除。

由于

汤姆

答案 1 :(得分:3)

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

tldr:水平压缩对压缩更具侵略性,因此建议用于具有大量读取的工作负载。