你需要知道的MySQL开源存储引擎TokuDB
在四月份的Percona Live MySQL会议上, TokuDB庆祝自己成为开源存储引擎整一周年。我现在仍能记得一年前它刚创建时的官方声明与对它的期望。当时的情况非常有意思,因为它拥有帮助MySQL管理大数据的潜力,而这是InnoDB无法做到的。TokuDB还有一些有意思的特性,比如”热模式转换(hot schema changes)”,可以使我们昂贵的闪存能够持续更长时间。
尽管在过去这一年里,我一直在关注TokuDB的发展,但我一直认为我不会去尝试使用它。直到最近,Percona Server发布了支持TokuDB插件的beta版本,我才觉得值得一试。
如果你还没有尝试过TokuDB,现在就是一个机会。首先我将介绍TokuDB是如何与MySQL协同工作的。
大家都知道,MySQL的核心在于存储引擎。InnoDB已经完全改变了MySQL,不仅让MySQL支持事务处理,并让整个系统变得更加成熟和稳定。即使是那些并不是事务特性的应用使用InnoDB也自得其乐。但是你是否记得不久之前InnoDB也是第三方专有插件呢?首先你需要将它与MySQL进行编译。然后将能够很容易的将该插件安装或者下载到已存在的服务器中。但是当InnoDB开源之后,一切就变得繁荣昌盛起来:人们越来越能接受它,而且慢慢地,它走上了正轨,得到了人们的推广。任何一个人都能阅读、修复、扩展它的编码,很多公司提交自己的修改融入其中,让InnoDB变得更好,直到它成为MySQL的首屈一指的存储引擎。
平衡大数据与存储成本
目前来看,与类似的MyISAM表相比,数据存(即使是压缩存储)到一个InnoDB表中需要的磁盘空间的确要更大,但是没有人会认为在一项新技术发展过程中不会出现缺点和不足。同时,磁盘的存储能力也在增强,这也有助于平衡每字节的价格,而且也能补偿InnoDB的空间需求。
但是磁盘容量的增加也对“什么值得存储”的界限进行了扩展。曾经的GB级磁盘既是近乎无限的存储空间,到如今已经成为有限,而TB级的磁盘成为了标配和基本需求。同时,尽管有大量有意思的东西可以浏览和探索,人们的注意力开始涣散,之前能够牢牢抓住现在却常常难以吸引眼球。如今,如果一个网站需要数秒才能进入,那么有些人就可能会失去兴趣。
SSD磁盘开始进行挽救这种情况,只需普通机械磁盘耗时的一小部分便能访问到数据。然而SSD在容量的扩展性却不太好:每字节成本的增加是跟与数据获取速度成比例的,而且SSD的寿命(或称持久性)不是很好,这是一笔昂贵的支出。需要明智地使用SSD。
基于这个原因,现在人们逐渐开始采用混合使用的方式,用快速、昂贵的SSD磁盘存储“热”的数据,将更慢一些、便宜一些的机械磁盘存储其他所有的数据。当然,这只是一种短期内可使用的方案,因为这难以维护,并要求大量专业人才去决定每一种磁盘存储哪种数据。长期来看作为一种较为便宜的存储,可以预测基于SSD的方案将发展的更好。但是,在此之前,还是很有必要在大数据与硬件投资之间做出权衡,做合乎两方的选择。
TokuDB的前提
解决这个问题还有一个办法,就是转变逻辑。如果能够在同样大小的磁盘容量中储存更多数据,而且能够存储、读取的更快,那么我们就可能得到更好的结果(从性能方面来讲)并获得存储投资带来的更好回报。这就是在TokuDB存储引擎发展过程中,Tokutek要达到的目标。它架构的核心基于一个不同的、现代的检索方法,名为分形树索引(FTI,Fractal Tree Indexes)。我所说的“不同”在于,大部分流行的存储引擎,比如MyISAM 、 InnoDB,都是基于B树索引。在过去至少30年内,该索引都保持着,作为某种无法挑战的标准。我所说的“现代”,是因为FTI的设计考虑到了写-密集型操作(这种操作在现在的数据系统中出现的越来越频繁)以及最新存储设备易损耗的特性。
两种数据结构都是基于树的,类似地在叶节点中存数数据,并且利用索引Key值加速排序。但是它们通过树来管理与存储数据的方法是不同的。TokuDB以及它的分形树索引与基于B树的InnoDB相比,使用的块大小更大(更大的叶子节点),进而数据能够得到更好的压缩(使用更小磁盘空间的关键技术),也提高了范围查询的性能。同样重要的是,TokuDB称能够通过一个消息传递系统与“优化的”缓存机制来更好的利用I/O。
尽管在基于传统B树的系统中,对表的一个改变会触发索引的相应更新,TokuDB最初会将每一个改变都当做一条消息。有意思的是,在消息到达相应的叶子节点并作出修改之前,它所带来的改变就已经存在于数据库中了。于是,数据库的内容则是叶子节点中存储的数据加上消息循环中的数据。这使存储引擎更加敏捷,举例来说,这会在热模式转换(Hot Schema Changes)中发挥重要的作用。
对于优化的I/O缓存系统的读操作,与更大的叶子节点的使用有关。或者如果你愿意的话,也有另外的方法:更有效的方法来使用缓存,使得更大的叶子节点的使用成为可能。这里提到的有效主要指的是带宽使用程度。需谨记,从消耗的时间来看,对磁盘的I/O远大于对内存的I/O;这就是使用缓存的原因——更频繁的将数据储存于缓冲中(低消耗),就可以减少将缓存“刷到”磁盘的频率(高消耗)。刷到磁盘的缓冲区越满,可以达到的带宽利用率越高。TokuDB试图最大限度的利用缓存,即“对单个I/O进行成千上万次操作”。B树的问题是因为设计的原因,它很难实现一个有效的缓存系统,而人们经常习惯将不太满的缓存刷到磁盘。因此,对于B树来说,更好的方法是在B树中维持小一些的叶子节点,这样产生的副作用是使压缩变差。Tokutek的工程负责人Tim Callaghan 11月份时在Percona Live London解释了对比的各种不同,比我解释的要好得多,
优化使用I/O,使得写操作密集型应用受益良多。目前在我们的Percona Cloud Tools (PCT)中使用TokuDB,用来存储和分析来自MySQL服务器的查询日志。选择TokuDB作为PCT存储设备的另一个好处是压缩性能更好,如果没有这个的话,在PCT服务beta阶段,我们会在支持的用户数上受到很多限制。压缩的影响究竟有多大?就像MySQL中的其他事情一样,这取决于你的模式。据Shlomi Noach报导,他能够把未压缩的InnoDB引擎的4TB数据(或者是使用KEY_BLOCK_SIZE=8压缩的InnoDB引擎的2TB数据)压缩到200GB。这样能够给大家一个感性的认识。
压缩本身就是TokuDB一个很吸引人的特性,但是对于存储空间的大小不是问题的应用场景,这个存储引擎也做的不错。对于写(INSERT)性能而并非网络是性能瓶颈的场景来说,对I/O的优化能够延迟副本操作。如果你需要对一个大表添加一列或者添加第二索引,“热模式转换”功能将助力不少。对于闪存磁盘的持久性也有不少重要影响。Mark Callaghan对于之前的文章做过以下评论:“与InnoDB相比,全磁盘服务器使用TokuDB支持更大的负载压力,全闪存的服务器使用TokuDB是通用的——2倍以上的压缩率(与InnoDB的压缩相比)以及批量的写操作(更多是顺序写)意味着你你可以买更少的闪存、这些闪存可以用更久、买更为廉价的缓存也能够用”。另外,不要忘了TokuDB中让Vadim最赏心悦目的一个特性:支持使用SHOW PROCESSLIST跟踪查询的实时进展。
展望
Tokutek擅长打破传统,并从其他角度出发找到了TokuDB发展中的问题。它受益于MySQL的开放性,使用它的引擎API实现了一个完全不同的方案,该方案脱胎于对现实的深思熟虑——更快的多核CPU、现代却又“脆弱”的存储设备以及对“大数据”的渴望。当然,它也受益于对基于B树的存储引擎的观察,该引擎在过去数十年内处理了不断进化的数据,伴随着新方法和新算法到来,一直让事情变得更加简单。与InnoDB相比,TokuDB更容易进行调优:我统计过共有40个“tokudb_”变量,而“innodb_”有超过100个。但是这还需要时间的考验。尽管我们并不是在讨论一个崭新的引擎(Vadim在5年前就记录过他对该引擎的使用经历),但该引擎最近变成了开源的、公共的,并处于初始阶段。尽管在稳步发展,我们也还是能看到很多未解决的bug。
令人担忧的是目前并没有支持TokuDB的开源热备份软件。尽管有一个“可插拔备份工具标准”在GitHub上提供有HotBackup的API,而目前唯一一个可能存在的热备份方案存在于TokuDB的企业版本中。TokuDB的设计并不适用于“拷贝数据库文件、然后在把存有数据库变化的日志应用到文件上”这样的备份方案,而这正是MySQL Enterprise Backup及Xtrabackup的工作方式,所以现在仍然没有希望,简单扩展一个已存在的开源软件来就可以支持TokuDB,如Percona XtraBackup 之类的软件。
我们将充满希望的看到一个新的开源备份软件到来,它将在不久的未来使用对外的API来实现,但是现在看来多数软件还是基于快照的工具,停留在文件系统水平,如mylvmbackup和 xfs_freeze,它们可以暂时作为未来新方法的替代方案。