Page 235 - 《软件学报》2021年第10期
P. 235
朱阅岸 等:构建新型高性能与高可用的键值数据库系统 3207
队列:与 VoltDB [20,21] 类似,系统采用 single-thread-per-partition 的执行模型消除写写冲突并发控制开销.
当写请求到达时,它首先被放入分片对应的队列中等待调度;
索引:数据以顺序 I/O 的方式写入磁盘.我们利用 ART 树索引日志,能够以最多一次 I/O 的代价检索(点
查询)请求的数据.ART 树是一个高效的内存索引,并且利用可变节点大小节省内存空间使用.最重要的
是:如文献[22]所证明的,ART 树的性能大幅度优于典型的读优化的索引,例如高速缓存优化的 CSB+
tree [23] ;并且,ART 树支持更新操作.ART 树的一个不足之处是,对范围扫描支持不够友好.优化 ART 树
的范围扫描特性,是我们未来工作的一部分;
存储:系统分为计算引擎与存储引擎,通过这种划分,我们可以单独优化不同的模块.类似于 Aurora,
LogStore 只写日志到存储节点.这种设计有利于节省磁盘/网络带宽;而且我们还可以在这种架构上进
行许多优化,例如:存储引擎可以将合并操作委托给不同的机器,计算引擎可以用较小的代价对索引、
缓冲区进行单独的优化.
2.1 执行模型
多线程执行以及对同步进行精细的设计,一直被开发人员认为是高性能系统设计的不二法则.传统的
DBMS 将这个准则利用到极致.在这个设计理念的背后,底层的硬件设施起着决定性的作用.在 RDBMS 出现时
期,计算机的内存与外设的访问速度差距达到 6 个数量级左右,而且内存的容量以 KB 来衡量.存储系统的性能
瓶颈集中在 I/O 上.因此,高性能系统的一个要求是运行尽可能多的任务,期望多线程的复用可以隐藏 I/O 的延
迟.存储系统的永恒主题是设计高效的缓冲区管理器、细粒度的锁机制以及高性能的闩锁和日志子系统.但是,
现在的情况已经发生了巨大的变化.服务器通常配备数 GB 大小的内存以及多个处理核心的 CPU.很多工作负
载,特别是 OLTP,都可以常驻内存.对于这类工作负载,尤其是 KV 操作,通常是搜索以及更新若干记录.这些操作
本身并不耗时,但是日志模块、缓冲区、闩锁等占用了线程大部分执行时间.正如 Harizopoulos 等人 [24] 所验证
的:在典型的 OLTP 工作负载中,线程花费在实际有效的工作时间只占执行总时间的 12%,其余时间都耗费在加
锁、缓冲区管理等上面.基于这一个研究结论,LogStore 转而使用 single-thread-per-partition 的执行模型结合多
版本并发控制,消除线程同步开销、读写冲突以及写写冲突.同时将线程绑定到特定的分片,以减少上下文切换
开销.当读写请求到来时,该写请求被放入相应的分片的请求队列等待调度.任务执行期间以独占的方式执行,
不能被抢占.
2.2 索 引
在 LogStore 中,日志文件被划分成两部分:一部分是有序的、不活跃段;另一部是无序的、活跃段.系统将日
志记录顺序写入活跃文件段.无序的子文件会被定期合并到有序的、不活跃段以清除无效数据,同时为范围查
询提供便利.ART 树索引建立在日志文件之上,以快速响应查询请求,如图 2 所示.
K1 K2 K3 Ki Kj Ku Kz ......
V1 V2 V3 V1 V1 V2 ......
Log record
...... ......
有序、不活跃日志段 无序、活跃日志段
Fig.2 Index on log file
图 2 日志文件索引