存储 频道

详解新硬件环境下日志模块的设计与演进

  【IT168 技术】本文根据朱阅岸老师于第九届中国数据库技术大会(DTCC 2018)的现场演讲《新硬件环境下日志模块的设计与演进》内容整理而成。

  讲师介绍:

新硬件环境下日志模块的设计与演进详解

  朱阅岸,中国人民大学博士,现供职于YY Research LAB。研究方向主要为数据库系统理论与实现、新硬件平台下的数据库系统以及TP+AP型混合系统。

  分享提纲:

  1、现代处理器及新型存储的发展

  2、传统的数据库系统日志模块设计

  3、面向新型硬件的日志子系统设计

  4、总结

  演讲内容:

  大家好,我今天带来的主题是“新硬件环境下日志模块的设计与演进”。该topic对近些年来工业界与学术界在日志子系统的优化进行总结,尤其是新硬件环境下的工作。分享由四部分组成,首先介绍一下新硬件和信息存储的一些发展,题目中的新硬件主要是指现代处理器和新型存储这两种。我会简要回顾一下数据库系统经典日志模块设计的原理和不足,然后是面向新硬件的一些日志子系统设计的方法,最后是总结。

  一、现代处理器及新型存储的发展

  我们首先简要回顾一下处理器的发展趋势。由于能耗与制造工艺的原因使得处理器制造商不再追求高频率,而是转向片上多处理器技术,也就是多核技术。现在服务器配备几十个CPU处理已经很常见了,一些厂商甚至推出了成百上千个处理核心的处理器,“众核”的概念开始流行起来。

  另一方面大家可能没有注意到,非易失性内存开始从实验室走向工业界,例如Intel傲腾,这类存储具有磁盘的持久存储特性与接近内存的访问速度,可以实现字节寻址,也就是使用CPU的load与store指令直接寻址。总体来说,它的主要特性是非易失、低延迟、高密度和读写不对称。可以看到,非易失性内存的存储容量比较大,可以达到内存的2到4倍左右,但是也有读写不对称的一些问题。

  目前实现非易失性内存的主流技术有四种:这里简要介绍一下非易失性内存的实现原理,可以分为四类。第一类是采用相变存储。相变存储器主要由相变材料、加热体、存取设备组成。通过加热体对相变材料进行加热材料会出现结晶与非结晶两种状态,呈现低电阻与高电阻,这对应与1和0;第二类是使用自旋磁力矩。自旋磁力矩的一个单元由固定层,自由层以及隔离层组成。对磁性材料施加电流会改变自由层的磁性方向从而使得存储单元具有低电阻与高电阻的二元状态;第三类是使用铁电材料:铁晶体管在电场的作用下会使得中心原子出现高极化电荷与低极化电荷。这种铁电材料的二元稳定状态使得它可以作为存储介质;最后是采用忆阻器技术。简单说,忆阻器是一种有记忆功能的非线性电阻。它可以记忆流经它的电荷数量,控制电流的变化可改变其阻值。如果把高阻值定义为“1”,低阻值定义为“0”,则这种电阻就可以实现存储数据的功能。非易失性内存是忆阻器的最简单应用。它的最大用途还是构造类大脑的硬件,为AI实现质的突破。

  我们来看一下非易失性内存、闪存以及内存之间的对比参数。由于PCM(Phase Change Memory)最具市场前景,我们将基于相变存储的非易失性内存与flash与DRAM进行比较。

新硬件环境下日志模块的设计与演进详解

  相比flash,PCM可以实现字节寻址,在读写速度上快2-3个数量级左右,同时读写寿命与能耗也有大幅改进。相比DRAM,PCM的读写延迟与带宽稍微逊色,但是在闲时能耗以及密度令人眼前一亮。在闲时能耗方面,PCM是DRAM的1/100。这主要是DRAM需要不断刷新电容来保持存储单元的内容,而PCM并不需要这样子的操作。能耗是数据中心最关心的一个问题,非易失性内存在大型数据中心的具有非常大的优势。

  回到软件设计,其实在我们的观念里在非易失性内存出现之前,内存与外设存在着巨大的性能差距。为了弥补这个差距,软件系统都会加上一层buffer,减少与外设打交道的频率。数据库系统有数据buffer和日志buffer,一般使用的steal与no force策略。也就是说,事务提交时刻无需刷脏页,直接将日志写出即可。这个模式是针对磁盘时代而设计的,在某些工作负载下,日志模块容易成为系统瓶颈。

  09年的时候,CMU的研究人员对几款流行的开源数据库系统进行了详尽的研究,验证了上述的观点,这几款开源的数据库系统都不能很好地利用底层硬件设施。随着并发线程的增加,上述系统性能都遭受了不同程度的下降。尤其是,事务真正花费在实际工作上的时间只占12%左右。缓冲区管理/锁管理器/日志模块耗费了大部分的事务执行用时。其主要原因是关系数据库系统的研发。时至今日,MYSQL的日志管理/锁管理以及Pg的缓冲区管理与日志管理都是一个大问题。他们的研究论文具有里程碑的意义,拉开了开源系统在多核处理器时代优化的序幕。

  总体来看,现在硬件发展就是CPU向多核、众核发展,非易失性内存开始从实验室走向工业界。非易失性内存的出现弥补了DRAM和持久性存储设备性能差距的鸿沟。有了非易失性内存以后,系统开发人员可以认为内存与外设之间的一个性能差距问题不复存在。在新硬件环境下,上层软件必须去适配底层硬件的发展,才能获得硬件上的红利。

  二、传统的数据库系统日志模块设计

  接下来我们简要回顾一下日志模块的设计和不足。其实现在来看,InnoDB的性能瓶颈目前主要集中在锁管理器与日志模块,PostgreSQL的性能瓶颈体现在缓冲区管理模块与日志模块。日志模块有一个通病,数据库通常采用集中的WAL方法实现,经常会引发热点问题。

新硬件环境下日志模块的设计与演进详解
WAL的集中式实现引发热点问题

  传统的日志提交主要有三个步骤,首先要获取写日志缓冲区上的排他锁,然后递增LSN, 代理线程将事务日志记录拷贝到日志缓冲区相应位置,最后释放缓冲区上的锁。当然在两三年前(至少开源数据库系统)数据库系统都是这么干的,现在大家都已经发现这个问题了。

  我们先看看MySQL 8.0版本之前,InnoDB是怎么提交日志的。当提交一个mini transaction时,需要将记录数据的更改日志提交到公共buffer中,并将对应的脏页加到flush list上。入口函数为mtr_t::commit,执行过程如下:

  1. mtr_t::Command::prepare_write 获取log_sys->mutex

  2. mtr_t::Command::finish_write 将日志从mtr中拷贝到公共log buffer。这里需要考虑block空间不足的情况(持有log_sys->mutex)

  3. 若本次事务产生脏页,申请flush list mutex随后释放log_sys->mutex。

  这三个步骤完全遵循上述的日志提交方法。

  PostgreSQL也有相同的问题,9.4版本之前日志提交的临界区设计的相当粗糙,事务执行的关键路径的代码长度大概有300行左右。

  基于这一点我们可以猜测很多数据库系统,特别是开源系统,在临界区上的设计上是比较随意的,面临一些扩展性的问题。从当前的研究实践看来,MySQL、PostgreSQL等性能瓶颈主要还是聚焦在日志模块。因此在当前硬件环境下,重构日志模块是具有很重要的意义的。

  三、面向新型硬件的日志子系统设计

  这部分我们来看一下面向新型硬件的日志子系统设计。主要分成三个部分,一部分是针对大并发场景优化日志子系统,通常做法是缩短临界区。第二种面向NVM优化日志子系统,但还是在现有的框架下去优化这个系统。第三部分是比较激进的,或许也是趋势,从头开始构建一个日志子系统,颠覆以前的认知。

  1、大并发场景优化之一:预留空间

  第一种优化方法叫做预留空间。下面是事务日志提交步骤:(1)事务只需在临界区内简单计算日志记录所占长度,然后即可释放锁。事务之间可以并行拷贝日志。(2)追踪日志记录填充情况。事务提交时刻需要确保之前的事务已经完成日志拷贝。

新硬件环境下日志模块的设计与演进详解

  针对多核处理器,大并发场景下的优化方法主要是缩短临界区。如图a所示,之前通常的做法是在临界区内拷贝日志。这将日志记录大小的引入事务执行的关键路径,其实只需要简单地预留空间以后即可释放锁。预留空间就是计算事务日志应该在缓冲区中的占据的位置。事务之间的日志拷贝可以同时进行,如图(b)所示。

  但是这个做法有个有个挑战,就是怎么样去追踪日志空洞,因为事务拷贝日志是并发执行的,有些事务执行的比较快,有些事务执行的比较慢。如果先执行的事务还没有拷贝完日志,而后来执行的事务却先于之前的事务完成日志拷贝,那么会导致在日志缓冲区上存在日志空洞,系统怎样去追踪空洞,这是一个很重要的研究课题。

新硬件环境下日志模块的设计与演进详解

  其中这一类做法(预留空间)的典型代表是ELEDA算法(ELEDA,Express Logging Ensuring Durable Atomicity),它把系统分成三类线程:工作线程、日志状态追踪线程以及日志刷盘线程。这样子分工主要是为了达到无锁化设计的目的(回想一下InnoDB的log_sys->mutex以及log_sys->write_mutex的作用)。工作线程在提交时刻利用原子操作申请LSN,预留空间,然后将日志记录拷贝到缓冲区。拷贝完成以后即可继续执行其它操作。如果是提交事务那么需要提供回调函数。追踪线程记录最大连续的日志缓冲区偏移SBL(Sequentially Buffered Log)。刷盘线程将小于等于SBL的日志写入持久存储,更新SDL(Storage Durable Log)为SBL。这时候就可以通知commit LSN小于SDL的事务提交成功。

新硬件环境下日志模块的设计与演进详解

  怎样维护这些信息还是很有挑战的,特别是追踪日志空洞。在ELEDA中,每个工作线程维护一个共享LSN链表如图所示,日志追踪线程根据这些链表建立最小堆,堆的顶部就是SBL。同时,工作线程在日志拷贝完成以后会在跳表(Hopping Index)相应的区间进行累加。当拷贝的字节数等于设定的区间值,那么表明该区间的日志已经全部拷贝完成,可以执行刷盘动作(这种方式对比利用最小堆推进SBL可以起到加速作用)。

新硬件环境下日志模块的设计与演进详解

  论文作者修改了MongoDB的存储引擎wiredTiger,在36核,488G内存上的服务器上测试。在YCSB的测试标准上,修改后的wiredTiger扩展性可以达到32核,对比没有修改的版本性能提升71X,可以充分利用底层硬件的处理能力。在TPCC的测试基准上,也有类似的表现。

  2、大并发场景优化之二:PostgreSQL的做法

  我们来看一下PostgreSQL的另一种做法。在9.4版本,PostgreSQL的开发者意识到了日志提交的问题,重构了日志提交算法。在之前的版本中,日志提交临界区代码段有300行左右,优化之后,该临界区代码段缩短为只有5行。PostgreSQL的设计者们利用8把锁追踪日志空洞,规定事务将日志写入共享日志缓冲区时刻需要申请这种类型的锁,在日志拷贝完成后即可将锁释放。事务提交时刻只需检查这8把锁的状态即可。

新硬件环境下日志模块的设计与演进详解

  这个设计有一个技巧性,就是需要优先考虑事务提交请求,也即对于锁的排队需要考虑优先级。通过类TPC-B测试显示,这个实现在大并发场景下性能能够提升30%以上。

  3、NVM上的日志管理器

新硬件环境下日志模块的设计与演进详解

  另外一个就是针对非易失性内存而设计的日志子系统。这种方法更为激进,大概的思路是现在不再是维护一个集中式日志管理器了,而是把负载分散到N个不同的日志管理器上,去提高写日志的并发性,但是还是要去解决日志空洞问题与确定日志回放顺序问题。在提交技术上,多数采用passive group commit技术。

新硬件环境下日志模块的设计与演进详解

  如上图,这个方法就是完全去掉了集中式的log buffer,每个事务自己维护一个私有的日志缓冲区,这样的话就把log buffer上的一些锁、临界区等资源竞争完全给去除掉了。系统可以选择在事务提交时刻将日志记录批量移动到非易失性内存或者在填充完日志记录以后马上移动到非易失性内存。这两种日志持久化策略分别对应:flush-on-commit以及flush-on-insert。在当前的CPU体系架构下,需要使用cflush以及mfence等指令将高速缓存的数据一并写入。Flush-on-commit可以将日志持久化的代价均摊。

新硬件环境下日志模块的设计与演进详解

  这是惠普实验室的研究人员针对非易失性内存而设计的日志管理器。如上图,Redo空间按照页面进行划分, undo空间按照事务进行划分;事务日志可以按照页面为划分并行写入,这对于以页面为单位进行重放日志的系统模型十分友好,加速系统恢复速度。在TPC-C测试基准下,性能提升1.2-1.6倍。

新硬件环境下日志模块的设计与演进详解

  最后介绍卡耐基梅隆的数据库研究小组提出的新理论实践,Write-Behind Logging(WBL)。目前几乎所有的数据库都是使用Write-Ahead Logging方法。这种方法带来的一大弊端是软件运行时开销以及系统恢复时间较长。WBL运行时只需追踪脏页,无需构造redo日志。事务提交时刻先写脏页,然后写日志。事务的日志协议不用再去构造After-image,直接就写上事务提交的时间区间(Cp,Cd)就行了。小于CP这个时间点的事务都已经提交了,而落在这个时间区间(Cp,Cd)里面的事务,就是还没有提交的,也即是活跃事务区间。在事务恢复的时候,系统知道这个时间区间的事务没有提交,对其它事务不可见,无需undo操作。系统也没有必要去进行Redo操作,因为提交数据都已经持久化。系统崩溃恢复时,需要一趟扫描日志,建立崩溃时候的时间区间(检点可以减少需要扫描的日志量)。从实验上看,WBL可以达到即时恢复的效果,同时性能提升约30%。

  最后一种做法是统一数据块与日志块,采用log is database的理念。数据块可以在多种状态下转换,减少系统IO,提升性能。由于时间关系不仔细展开,可以参考相应的参考文献。

  总的来说,我们传统的ARIES算法是面向磁盘而设计的,在大并发情况下日志模块容易成为系统瓶颈。因此可见软件的设计需要适配底层硬件的发展,才能更好地获取底层硬件的能力。目前优化集中式日志管理器主要有三种方式:一种是缩短临界区,另一种是并行化写日志操作,另外,就是针对新硬件场景开辟新的理论实践。

  四、总结

  综上,计算机硬件的发展为我们数据库理论的创新打开了新的一扇大门。以前我们认为数据库理论发展进入了封闭期,基本上没有什么可以突破的了,但是现在,特别是非易失性内存出来以后,还有AI的飞速发展(从某种意义上说,AI的飞速发展其实也是得益于新硬件),我们发现数据库系统理论又有了新的方向,新的进展,这对于我们数据库内核开发人员来说,是一个很激动人心的现象。

  在多核与内存计算时代下,系统设计人员应当将更多的精力放在系统扩展性以及数据访问的局部性上。而非易失性内存的出现使得系统设计人员可以将注意力完全地从I/O上移除,专注系统扩展性设计。

  引用狄更斯的名言,“这是最坏的时代,也是最好的时代” 。各种不同应用领域的出现,对数据库的要求更高了,同时机遇与挑战并存,这对我们而言也是最好的时代。

  关于DTCC

  第九届中国数据库大会以“数领先机?智赢未来”为主题,设定2大主会场及22个技术专场,邀请来自国内外互联网、金融、教育等行业百余位技术专家,共同探讨Oracle、MySQL、NoSQL、大数据、机器学习、区块链、数据可视化等领域的前瞻性热点话题与技术。

新硬件环境下日志模块的设计与演进详解

  (更多精彩报道,请戳:http://www.it168.com/redian/dtcc2018/

0
相关文章