香港中文大学helen HashKV: Enabling Efficient Updates in KV Storage via Hashing
针对问题:kv分离设计中,valuelog的gc的效率低下,尤其在update intensive负载中。
第一:环形日志维持严格GC顺序,总是在最近的kv对插入的位置开始进行GC。会造成不必要的数据移动。
第二:gc需要查询LSM来检查kv的有效性,而这个查询有着很高的延迟。
hashkv的解决方法:
1.对value storage进行基于hash的数据分组设计。将value storage分成固定大小的分组,每个新插入的kv对根据hash值选择group进行append。
并在此基础上,提出了三点扩展:
动态的保留空间分配:如果原始的hash分组满了,动态的分配保留空间给额外的write
热点感知:分离hot和cold的键值对来提高gc效率。
选择性的kv分离:!!!!小size的kv对完全保留在LSMtree来简化查询。
实验,对leveldb,rocksdb,kvseperation进行了对比,在load和update两种数据scheme下,wisckeydb在update表现的很差。
SSD分组,hot kv对会进行更多gc,相应他们在lsmtree也在更上层,查询更少。
hashkv设计:
1.基于哈希的数据分区:分区隔离,使得一个key的所有update都在一个分区里。确定性分区,一个value应该被存储的分区由hash决定。
2.动态保留空间的分配,每个分区大小固定,有些分区可能增长的超出了这个限制,这时就分配保留空间给他。
3.热点感知:很多时候,热点数据和冷数据被分配到一个分区,那么对这样分区的垃圾回收会导致冷数据被反复重写。hashkv通过标签技术将冷热数据分开。
4.选择性的kv分离:比较小的value就不适用kv分离的机制。
gc策略:
选择那个segmentgroup进行gc?
目前是贪婪算法,最多写操作的一个group
怎么尽快判断一个kv对是否valid?
将key,meta和value一起存在valuelog中,这样就不用去LSMtree里去找,直接通过scan valuelog的对应group就能知道。与group end离得最近的一个版本的kv对必然是最新的。
热点感知:
标签技术,对seggroup中每个kv pair进行hot、cold分类
当前方法:上次插入之后至少update过一次的叫做热数据,热数据还存在seggroup,但冷数据就只将meta放在group里,而将kv放在另外的存储空间,并用tag标示,等以后被更新过,在更新为热数据。而对于colddata的vlog的垃圾回收,就执行wisckeydb的vlog gc方法。
选择性的键值分离:
我当初的想法和他一致
范围查询:
使用LSMtree的关键因素,键值在sstable中都是有序排列的。类似wisckeydb,通过preread策略,减少范围查询的延迟,将值预取到pagecache中。
崩溃一致性:
元数据日志,flush写缓存,gc
元数据日志是用来记录每一次flush操作的。