层次压实策略如何确保90%的读取来自一个SSTable?

13
我正在尝试理解Cassandra中的平衡压实策略(Leveled Compaction Strategy),它保证90%的读取将从单个sstable中满足。
根据DataStax文档:
新的sstables被添加到第一级别L0,并立即与L1中的sstables进行压实。当L1填满时,额外的sstables将被提升到L2。在L1生成的后续sstables将与它们重叠的L2中的sstables一起压实。
1个回答

28

LeveledCompactionStrategy(LCS)在Cassandra中实现了LevelDB的内部机制。您可以在LevelDBimplementation doc中检查确切的实现细节。

为了给您一个简单的解释,请考虑以下几点:

  1. 当达到固定(相对较小)的大小限制时,将创建每个SSTable。默认情况下,L0会获得5MB的文件,每个后续级别的大小是前一个级别的10倍。(在L1中,您将有50MB的数据,在L2中为500MB,等等)。
  2. SSTable是使用保证不重叠创建的
  3. 当级别填满时,将触发压实,并将来自级别-L的稳定版本提升到级别-L + 1。因此,在L1中,您将在大约10个文件中获得50MB的数据,在L2中为大约100个文件的500MB等等。

加粗的是相关细节,可以解释90%的读取来自同一文件(SSTable)。让我们一起算一下,一切都会变得更清晰。

假设您在L0中拥有键A、B、C、D和E,并且每个键占用1MB的数据。

接下来我们插入键F。因为级别0已满,压实将在级别1中创建一个文件,其中包含[A、B、C、D、E],而F将留在级别0。

这就是L1中约83%的数据在1个文件中的原因。

接下来我们插入G、H、I、J和K。所以L0再次填满,L1获得一个新的sstable,其中包含[I、G、H、I、J]。

到目前为止,我们有K在L0中,[A、B、C、D、E]和[F、G、H、I、J]在L1中

这就是L1中约90%的数据的原因。

如果我们继续插入键,我们将获得大约相同的行为,因此您会从大约相同的文件/ SSTable中获取90%的读取。

更深入和详细的信息(包括更新和墓碑文件的处理)可以在我提到的链接中找到。 (这些关于压实选举的大小是LevelDB默认值,而不是C*s):

当级别L的大小超过其限制时,我们会在后台线程中对其进行压实(compaction)。该压实操作会选择来自级别L的一个文件和下一级别L+1中所有重叠的文件。请注意,如果级别L文件仅部分与级别L+1文件重叠,则将使用级别L+1中的整个文件作为压实输入,并在压实后将其丢弃。附注:由于级别0是特殊的(其中的文件可能互相重叠),因此我们会特别处理从级别0到级别1的压实操作:如果某些级别0文件重叠,则级别0压实操作可能会选择多个级别0文件。

压实操作合并所选择文件的内容,以生成级别L+1的文件序列。在当前输出文件达到目标文件大小(2MB)后,我们将切换到生成新的级别L+1文件。当当前输出文件的键范围增长到足以覆盖超过十个级别L+2文件时,我们还会切换到新的输出文件。这条规则确保级别L+1文件的后续压实操作不会从级别L+2中提取过多数据。


我已经编辑了我的问题。你能否解释一下? - Chaity
谢谢您的详细解释。有一个问题,如果另一行的重复输入例如:键A、C、G的输入呢?还有一件事,可能有个错别字。它应该是[F、G、H、I、J]而不是[I、G、H、I、J],对吗? - Chaity
@LuísCorreia 在第二层意图中重复两次的 I 是有意为之吗? - Tamil
据我所知,一旦SSTable在L0中创建,如果可能的话,Cassandra将尝试将其压缩到L1。它不必等待L0中有5个SSTable。这只涉及到L1及以上。 - Milan
@LuísCorreia 如果将L1与L0进行比较,L1拥有90%的数据,但如果将L2与L0进行比较,则不是这样。这意味着在最坏的情况下,Cassandra几乎会读取两个级别吗? - deFreitas
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接