偶然看到一篇文章,WiscKey: Separating Keys from Values in SSD-conscious Storage。这篇文章的思路并不复杂,不过我觉得其对LSM类系统的设计有很好的启发。
LSM,即Log structure tree[1],我是在Google的BigTable[2]文章里面了解到的,其考虑到互联网数据写入规模大,而且写入频率远远高于读取频率,因此采用LSM以牺牲读性能换取写性能。LSM基本原理描述见图1(来自[3]),对于写请求,写完日志之后,数据直接放内存,返回client请求成功。当内存满之后,内存数据写入到磁盘。可以看到整个过程基本都是顺序写,机械磁盘的顺序读写性能是随机读写性能的100X倍以上,所以这个结构非常适合机械硬盘。同时这个描述比牺牲读优化写要接近本质多了^_^。想想BigTable发表于2006年,那时候SSD还远未流行,从侧面也说明了这一点。
图1:LSM基本原理描述(左)
但是现在硬件在飞速发展,SSD的随机读(延时和并发)能力比HDD有了100X+的提升,SSD厌恶写(SSD覆盖写放大严重、延时高且影响其使用寿命),这些跟HDD截然不同的特点启发了作者思考是不是LSM也需要做一些改进呢?YES。作者的改进非常直白,跟LSM上面的写入架构直接相关。从上面的架构看,LSM写入过程是很爽,但是读的时候就不爽了,需要从C0…Ck里面读数据并merge后返回给用户。比如我们有一个key,要找到其value,那么需要如下步骤:
读C0,如果没发现,读C1
读C1,如果没发现,读C2
读C2,如果没发现,读C3
…
可以看到,这个读全是随机IO,相当的低效,怎么办呢?LSM提出的思路是启动一个背景线程,将C1…Ck合并成一个文件,比如Cx,那么要读key,就只要读C0、Cx就行了,极大的减少了随机IO的次数。这个背景操作一般称为compaction。问题是compaction定期的读、合并、写要占用额外的IO和CPU,有时候反而影响了在线读写的性能。在机械硬盘时代,只能做一些算法调整,比如更智能的检测啊,提前设定规则啊之类的,基本没有什么大突破。到了SSD时代,因为读的性能很高了,而且还会越来越高,所以就有了更多的可能。Wisk提出的思路简单易懂,就是将key和value分开存放,降低每次compaction遍历的数据量。
从上面可以看到如下几点:
Wisk思考的依据:SSD跟HDD不同,读更快(HDD 7-10ms,SSD 30-100us,NVDIMM更快,据说理论上做到3us),随机读跟顺序读性能类似,厌恶写
Wisk解决问题的思路:key、value分开存储,让compaction只处理key,降低compaction过程中处理的数据量,在value比较大(大于1K)的场景下,这能节省非常多的IO带宽,也能节省CPU
思路是美好的,会面临哪些问题呢?首当其冲的就是因为KEY/VALUE分离,所以读VALUE会面临至少两次IO的问题(不考虑各种索引),这个正好对应上面SSD随机读性能极好的特点,所以不是大问题。然后就是空间回收问题,这个本质问题还是上面第一个问题,因为回收就得知道这个key是否还有效,而这个需要查询才知道,是一个读的问题。第三个问题就是一致性的问题,KEY/VALUE分离之后就面临两次写入,需要保证一致性。实际上这个问题挺简单的,只要以key为准就可以了。
所以上面的几个问题总结下来,核心问题就是如何充分利用SSD的读能力,解决各种操作对高速读的需求。作者说了,要充分利用SSD的并发能力,搞一个线程池,并发的读SSD,这个思路很自然,论文评估证实在大部分场景下(value大于1K)也确实有效。
而且,文中还提到了,可以定期对value做compaction,这样,会进一步提高读能力,本质上是将key和value的compaction分开来做,这样就能更充分的利用各自的特性,以更少的资源来完成目的。这个思路放在哪都是对的,将步骤拆的更细,然后再看看是否可以分别优化。CPU流水线、网卡收发包都有类似思路。
文中提到的几个量化数字还是比较有意思的,
以写入磁盘的数据除以用户写入的数据计算放大系数,则LevelDB的写入放大高达数十倍,而读放大高达数百倍(索引和数据)。但是对HDD这是可以接受的,因为HDD的随机读写延时是顺序读写延时的数千倍,只要放大低于这个值,就是有效的。Wisk的方法可以将放大降低到4甚至1(value大小不同)
作者还分析了不同value大小场景下LevelDB的各个组件的延时,见图2,这个分析对很多类似系统有指导意义
作者提到在某些场景下,因为竞争磁盘读写,compaction对online操作流量影响高达35%
图2:LevelDB不同value大小各部分延时
[1]. Log-structured merge-tree
[2]. http://research.google.com/archive/bigtable-osdi06.pdf
[3]. https://www.usenix.org/system/files/conference/fast16/fast16-papers-lu.pdf