(一)数据存储方式的差异
从磁盘数据库转变到内存数据库,首先需要考虑的是如何改变数据的存储方式。对于磁盘数据库,需要考虑如何使数据的存储能尽量少地占用磁盘空间。需要读写的数据量越小,能获得更高的磁盘I/O效率。对于内存数据库,毕竟相对于磁盘来说内存的价格还是比较昂贵的,所以存储数据的大小就显得越发重要了。在磁盘数据库系统中,区分出经常被访问的数据对象,将这些对象存放在同一个磁盘分区内,可以提高磁盘I/O的效率。磁盘的机械物理特性,适合于读取顺序存储的数据而对于随机位置数据的读写,需要经过耗时的磁盘寻道等I/O时间的等待,磁盘I/O效率就要差很多。在内存数据库中,对于时间的影响就不是那么严重了。相比磁盘,内存更加适用于对数据的随机访问。内存的访问速度很快,是磁盘访问速度的数十倍。因此,在内存数据库系统中,系统的主要性能瓶颈转移到数据访问延迟和数据管理算法的处理器消耗上。不少的内存数据库系统都致力于减少在访问数据时所耗费的处理器时间(包括处理器空等时间和处理器运算时间),甚至在某些情况下,采取用空间换时间的策略,来提升系统的效率。不同的内存数据库,有不同的数据存储方案。在传统的内存数据库系统中,内存的数据存储模式设计显得更加自由,大量使用指针来引导对数据的访问。同时也给应用程序更大的灵活性,可以直接通过指针来访问内存数据库中的数据。在内存中通过使用直接指向数据地址的指针,看起来解决了内存数据库中的记录数据访问上的瓶颈。但是,这也会带来一些问题。在当今的计算机硬件的架构中,内存的访问速度始终满足不了处理器对数据访问速度的要求,处理器和内存之间的缓存(Cache)变得更加重要。对内存的随机访问,不能很好地配合缓存的硬件设计。虽然内存不像硬盘具有磁头的寻道和定位等机械因素的牵制,但是随机访问内存中的数据,会把多个不同的内存块重复的装入内存和处理器之间的多级缓存中。因此在内存数据库系统的数据存储方式设计上,不仅要考虑到内存访问数据的方式,也要考虑到缓存对内存访问的性能影响。
(二)数据访问方式的差异
如今,随着对处理器缓存作用的认识的逐渐加深,内存数据库的数据访问技术的热点研究方向是在访问的过程中如何利用好处理器缓存,使得性能得到最大优化。人们重新研究过在内存数据库系统中曾普遍使用的索引,例如T树,发现其对缓存的利用率很差,反而制约了其性能潜力的发掘。因此人们相继研制出对缓存敏感的索引,例如CSS树,CSB+树等。同时多种针对缓存效率的索引优化方法也被使用。
在内存数据库系统中的查询处理也与磁盘数据库有所差异。在磁盘数据库系统上,查询处理的时间消耗,以磁盘I/O的操作时间为主,而在内存数据库上,因为没有磁盘I/O的操作,因此处理器的计算时间和缓存的利用成为最主要的开销。在内存数据库上,有不少特殊的查询处理方法,例如将表里面的外键值用指向外键值的指针来替换。外键的值相同就使用相同的指针。这样在join做操作的时候,可以直接比较外键指针,而不是比较外键的值,显然这种方法是比较高效的,特别是外键的值是字符串类型的时候。同样的道理,在物化的中间结果上也只需要保存指向实际值的指针,而不必将实际数据拷贝到中间结果表(intermediate table)上。在内存数据库中,join的方法可以不使用归并排序(sort-merge)的方式,因为归并排序会带来处理的负担并且排序的中间结果也会占用空间。虽然过去有过实验数据证明基于T树的归并join通常比归并排序join在性能上更好,但是最近的研究结果又表明,如果排序的方法能够对缓存做优化,归并排序join在内存数据库上还是有重要位置的。
(三)事务处理方式的差异
在事务处理时,由于内存的访问速度比磁盘快,因此,在内存数据库中事务的执行速度通常也较快。在采用基于锁的并发控制系统中,这意味着锁的时间不会保持太长,由此在做并发控制时不必像磁盘数据库那样时刻注意对锁的控制和操作。因此,在内存数据库中,对锁的管理又有些与磁盘数据库不同的设计思路。比如说,通常系统会通过选择小的加锁粒度来减少对锁的竞争。但是在内存数据库系统中,数据已经常驻在内存中,并且对该数据上的锁持有时间又很短,那么使用低粒度锁的优点不是那么明显了。使用大粒度的锁例如表级锁,不仅能简化锁管理,也有一些性能上的优势。在内存数据库中,对整个数据库加锁并不是一件不可想象的事情。
对数据库加锁使得所有的事务都将串行化执行。串行化执行也有不少的好处:首先,可以消除许多并发控制上的开销,例如加锁和放锁,对死锁的检测和处理等;再次,由于事务的串行化执行,使得在执行单个事务的过程中,处理器的缓存上下文无需被切换,可以在事务指令和事务所访问数据的连续性基础上,更好地利用处理器的指令缓存和数据缓存。因为在并发条件下,当一个事务在等待锁的时候,需要调度激活另外一个符合执行条件的事务开始执行。原先在处理器缓存中的事务指令和数据都将作废,需要重新切换加载新的指令和数据,这将耗费不少的处理器时间。但是,串行化执行在有长事务出现的情况下,就不太实际了。可以考虑使用某种策略,使得短事务能够和长事务并发执行。在锁的实现过程中,内存数据库可以在被加锁的数据对象上使用新的技术。在内存数据库中,存储在磁盘上的数据对象本身并不带有任何的锁信息。而在磁盘数据库中,数据对象存储在内存中,我们可以用非常方便而又简单的方法使得数据对象本身也附带一些锁信息,来标示自身的加锁状态。例如,事务在访问数据对象时,不必通过全局的加锁Hash表来判断当前数据对象的加锁状态,而是直接在访问数据对象时,读取对象自身的加锁状态信息。如果对象还没有被加锁,则事务可以对数据对象进行相应的操作。
(四)内存数据库常用技术
内存数据库的技术包括了内存数据库的恢复处理技术(Recovery)、并发控制技术(Concurrency Control)、存储与数据组织技术(Storage and Date Organization)、事务提交处理技术(Transaction Processing)、数据迁移技术(Data Migration)、数据访问技术(Data Access)、查询处理和查询优化技术(Query Processing and Query Optimization)、负载均衡(Load Balancing)技术等各个方面。其中由于应用程序直接访问数据,数据库更易受到应用软件错误和系统崩溃等故障带来的伤害。内存数据库的恢复较之传统磁盘数据库要复杂得多,也更为关键,恢复部件一定要被恰当地设计、实现和维护。内存数据库恢复系统的设计方法,由于应用领域和设计思路的不同而千差万别,但它们追求的目标是相同的,都是保持数据库的一致性,使数据库能从故障中快速恢复,且恢复时占用尽量少的时空开销。由于内存数据库主要基于内存,内存又具有易失性,存储在内存中的数据出现故障时,很容易导致数据的丢失,为了防止数据不丢失,就必须在磁盘或者其它非易失性存储器中保存它的备份。而数据库的备份、日志存储及异常情况下的系统恢复需要执行大量费时的磁盘I/O 操作,这必将成为系统的瓶颈,影响系统正常的事务处理能力,所以,在系统出现故障时,快速、有效地确保数据恢复到一致性状态就显得特别重要。
日志、检测点和重装技术是内存数据库故障恢复技术的三大要素。这些技术主要包括恢复处理器(Recovery Processor)、NVRAM、热备份技术、影子内存、影子页面、预提交、成组提交、模糊检查点、非模糊检查点、日志驱动检查点、部分重载和完全重载等。其中,恢复处理器、NVRAM、热备份技术在速度和稳定性能上都相当不错,不足之处在于都需要额外硬件支持。恢复处理器技术就是增加一个CPU,用它专门处理日志、检查点进程以及系统崩溃后的恢复进程;NVRAM是一种非易失性内存,具有内存的存储速度,而且掉电时内存中的数据不丢失,日志等信息刷到NVRAM的速度比刷到磁盘上快很多,事务日志刷到NVRAM就完成提交,具有较快的时间响应性;热备份技术是用另一台远程机器作为映像,维持一个数据库热备,当数据库主服务器崩溃时,这个备份数据库随时能切换成数据库主服务器,确保服务器正常提供服务。在检查点方面,有非模糊检查点、模糊检查点、日志驱动检查点三类。模糊检查点进程不加任何锁,而且不阻塞事务的正常执行,不足之处在于模糊检查点更新的数据库映像无法保证事务一致性;非模糊检查点需要对被检查的数据项加锁,特别是在大容量内存环境下,检查点操作需要将整个数据库的脏页拷贝到磁盘,过程中产生很多磁盘I/O操作,导致检查时间消耗比较长,无法支持对事务响应时间要求比较高的应用,但是它们备份出来的数据库由于满足事务一致性,其恢复算法相对简单。而日志驱动检查点在检查的时候,使日志作用于磁盘备份,速度很慢,一般用于远程备份。重载就是利用数据库的外存版本和日志文件恢复内存数据库的过程,它有两种类型:部分重载和完全重载。它的方法有:顺序重载、带优先级的顺序重载和基于优先级的带存取频率的重载。
(五)展望
内存数据库是一个与传统数据库有着显著差异的新兴方向,应用进展值得关注。当然,最近几年,一些厂商陆续推出全闪存服务器和适应闪存架构的数据库。闪存作为机械硬盘和内存之间的一种存储形态,也展现出了比较大的发展潜力。内存数据库和闪存数据库未来发展孰优孰劣,还需要经过大量实践的检验。
*本文在撰写过程中,得到贵州大学李晖教授的指导。
*
参考文献:
- 王晨,内存数据库若干关键技术研究。
- 袁培森,内存数据库的设计与实现。
- 宋毅,缓存敏感T树的设计与实现。
- 史习一,在数据清洗过程中基于MMDB的数据匹配技术。
- 靳若冰,基于商业数据库的实时数据库开发研究。
- 石英伟,分布式实时内存数据库关键技术研究与实现。
- 梁智兴,内存数据库恢复技术研究。
- 张效尉,王大羽,内存数据库故障恢复策略研究。