前言
Cassandra是基于LSM架构的分布式数据库。LSM中有一个很重要的过程,就是压缩(Compaction)。默认的压缩策略是SizeTieredCompactionStrategy,今天主要说一下另一种压缩策略LeveledCompactionStrategy。
LeveledCompactionStrategy
LeveledCompactionStrategy被用在读密集的场景,读操作的延迟相对容易估算(最坏情况可控),缺点是会有更多的磁盘IO消耗。
SSTable合并过程
这个压缩算法主要是将数据分级(L0,L1,L2……)。最开始数据在内存(memtable)里,然后被flush到磁盘上,也就是到了L0这级。L0的sstable会和L1的合并成更大的sstable。
大于等于L1的层级,sstable大小会被控制在sstable_size_in_mb(160MB)
。每个层级之间数据量是10倍的关系,即L2的数据量是L1的10倍。我们假设L1可以容纳10*160MB
,那么L2可以容纳100*160MB
。如果在L1做压缩,结果大于10哥文件,则会被合并到L2。如此反复,多出来的文件会跟下一层级中有重叠的文件合并。
非常多次写入后
性能分析
经过上面这个合并流程,LCS 会保证每个层级内的每个文件数据不重叠(除了L0),这也就是它高效原因所在。你所要读的数据大概率会只在某个层级中,而层级内文件数据不重复,所以你大概率只需要读一个文件即可。这个概率是多少呢,大约是90%。这个是怎么算的呢?因为每一层是前一层的10倍,所以最后一层容纳了大部分数据。比如:L1=10,L2=100,L3=1000,L3占比90.09%。同理,可以推出无用数据(删除或被覆盖的),最多占比10%左右(假设L1和L2全是无用数据)。
如果是更新删除比较高频的场景,那么读最坏情况,可能需要访问每个层级,每个层级读一个文件(L0除外),所以说最坏情况可控。如果L0中的文件出现积压,是有可能出现更坏的情况都,需要再访问L0中大部分文件。
更多细节可以参考:https://cassandra.apache.org/doc/latest/cassandra/operating/compaction/lcs.html