第13章 云端的MySQL
许多人在云中使用MySQL,有时候规模还非常庞大,这并不奇怪。从我们的经验来看,大多数人使用的是Amazon Web Services平台(AWS):特别是Amazon的弹性计算云(Elastic Compute Cloud,EC2),弹性块存储(Elastic Block Store,EBS),以及更小众的关系数据库服务(Relational Database Service,RDS)。
为了便于讨论MySQL在云中的应用,可以将其粗略分为两类。
IaaS(基础设施即服务)
Iaas是用于托管自有的MySQL服务器的云端基础架构。可以在云端购买虚拟的服务器资源来安装运行MySQL实例。也可以根据需求随意配置MySQL和操作系统,但没有权限也无法看到处于底层的物理硬件设备。
DBaaS(数据库即服务)
MySQL本身作为由云端管理的资源。用户需要先收到MySQL服务器的访问许可(通常是一个连接串)才能访问。也可以配置一些MySQL选项,但没有权限去控制或查看底层的操作系统或虚拟服务器实例。例如 Amazon运行MySQL的RDS。其中一些服务器并非真的使用MySQL,但它们能兼容MySQL协议和查询语言。
我们讨论的重点主要集中在第一类:云托管平台,例如AWS、Rackspace Cloud以及Joyent(1)。有许多很好的资源介绍如何部署和管理MySQL及其运行所需要的资源,并且也有非常多的平台来完全满足这样的需求,所以我们不会展示代码样例或讨论具体的操作技术。因此,本章关注的重点是,在云端运行MySQL还是在传统服务器上部署MySQL,它们在最终经济上和性能特性上的关键区别是什么。我们假定你对云计算很熟悉。这里不是对云计算概念的简单介绍,我们的目的只是帮助那些还不熟悉在云端部署MySQL的用户在使用时避免一些可能遇到的陷阱。
一般来说,MySQL能够在云中很好地运行。在云中运行MySQL并不比在其他平台困难,但有一些非常重要的差别。你需要注意这些差别并据此设计应用和架构来获得好的效果。某些场景下在云端托管MySQL并不是非常适合,有时候则很适合,但大多数时候云仅仅是另外一个部署平台而已。
云是一个部署平台,而不是一种架构,理解这一点很重要。架构会受平台的影响,但平台和架构明显不同。如果你把架构和平台搞混了,就可能会做出不合适的选择而给以后带来麻烦。这也正是我们要花时间讨论云端的MySQL到底有什么不同的原因。
13.1 云的优点、缺点和相关误解 #
云计算有许多优点,但很少是为MySQL特别设计。有一些书籍已经介绍了相关的话题(2),这里我们不再赘述。不过我们会列出一些比较重要的条目供参考,因为接下来会讨论到云计算的缺点,我们不希望你认为我们是在过分苛求云计算。
- 云是一种将基础设施外包出去无须自己管理的方法。你不需要寻找供应商购买硬件,也不需要维护和供应商之间的关系,更无须替换失效的硬盘驱动器等。
- 云一般是按照即用即付的方式支付,可以把前期的大量资本支出转换为持续的运营成本。
- 随着供应商发布新的服务和成本降低,云提供的价值越来越大。你自己无须做任何事情(例如升级服务器),就可以从这些提升中获益;随着时间推移你会很容易地获得更多更好的选择并且费用更低。
- 云能够帮助你轻松地准备好服务器和其他资源,在用完后直接将其关闭,而无须关注怎么处理它们,或者怎么卖掉它们收回成本。
- 云代表了对基础设施的另一种思考方式——作为通过API来定义和控制的资源——支持更多的自动化操作。从“私有云”中也可以获得这些好处。
当然,不是所有跟云相关的东西都是好的。这里有一些缺点可能会构成挑战(在本章稍后部分我们会列出MySQL特有的缺点)。
- 资源是共享并且不可预测的,实际上你可以获得比你支付的更多的资源。这听起来很不错,但却导致容量规划很难做。如果你在不知情的情况下获得了比理应享受到的更多的计算资源,那么就存在这样的风险:别人也许会索要他们应得的资源,这会使你的应用性能退化到应有的水平。一般来说,很难确切地知道本来应该得到多少(资源),大多数云托管服务提供商不会对此给出确切的答案。
- 无法保证容量和可用性。你可能以为还可以获得新实例,但如果供应商已经超额销售了呢?这在有很多共享资源的情况下会发生,同样也会发生在云中。
- 虚拟的共享资源导致排查故障更加困难,特别是在无法访问底层物理硬件的情况下无法检查并弄清到底发生了什么。例如,我们曾经看到过一些系统的iostat显示的I/O很正常或者vmstat显示的CPU很正常,而当实际衡量完成一个任务需要的时间时,资源却被系统上的其他东西严重占用了。如果在云平台上出现了性能问题,尤其需要去仔细地分析检测。如果对此并不擅长,可能就无法确认到底是底层系统性能差,还是你做了什么事情导致应用出现不合理的资源需求。
总的来说,云平台上对性能、可用性和容量的透明性和控制力都有所下降。最后,还有一些对云的误解需要记住。
云天生具备更好的可扩展性
应用、云的架构,以及管理云服务的组织是不是都是可扩展的。云并不是天生可扩展的,云也仅仅是云而已,选择一个可扩展的平台并不能自动使应用变得可扩展。的确,如果云托管提供商没有超售,那么你可以根据需求来购买资源,但在需要时能够获得资源仅仅是扩展性的一个方面而已。
云可以自动改善甚至保证可用时间
一般来说,个别在云端托管的服务器比那些经过良好设计的专用基础设施更容易发生故障或运行中断。但是许多人并没有意识到这一点。例如,有人这样写道:“我们将基础设施升级到基于云构建的系统以保证100%的可用时间和可扩展性”。而就在这之前AWS遭受了两次大规模的运行中断故障,导致很大一部分用户受影响。好的架构能够用不可靠的组件设计出可靠的系统,但通常更可靠的基础设施可以获得更高的可用性。(当然不可能有100%的可用时间的系统。)
另一方面,购买云计算服务,实际上是购买一个由专家构建的平台。他们已经考虑了许多底层的东西,这意味着你可以更专注于上层工作。如果构建自己的平台而对其中的那些细枝末节并不精通,就可能犯一些初学者的错误,早晚会导致一些宕机时间。从这一点来说,云计算能够帮助改善可用时间。
云是唯一能提供[这里填入任意的优点]的东西
事实上,许多云的优点是继承自构建云平台所用到的技术,即使不使用云也可以获得(3)。例如,通过管理得当的虚拟化和容量规划,可以像任何一个云平台那样简单快速地启动(spin up)一台新的机器。完全没必要专门使用云来做到这一点。
云是一个“银弹”(silver bullet)
虽然大部分人会认为这很荒谬,但确实有人会这么认为。实际上完全没有这回事。
无可否认,云计算提供了独特的优点,随着时间的推移,关于云计算是什么,以及它们在什么情况下会有帮助,我们会获得更多的共识。但有一点非常肯定:它是全新的,我们现在所做的任何预测都未必经得起时间的考验。我们会在本书讨论相对安全的部分,而将剩下的部分留给读者讨论。
13.2 MySQL在云端的经济价值 #
在一些场景下云托管比传统的服务器部署方式更经济。以我们的经验来看,云托管比较适合尚处于初级阶段的企业,或者那些持续接触新概念并且本质上是以适用为主的企业,例如移动应用开发者或游戏开发者。这些技术的市场随着移动计算的扩张出现了爆炸式增长,并且仍然是快速发展的领域。在许多情况下,成功的因素并不为开发者所控制,例如口口相传的推荐或者恰逢重要国际事件的时机。
我们已经帮助很多公司在云中构建移动应用、社交网络以及游戏应用。其中一个他们大量使用的策略是尽可能又快又便宜地开发和发布应用。如果一个应用碰巧变得流行了,公司将投入资源扩大其规模;否则就会很快终结这些应用。一些公司构建并发布的应用的生命周期甚至只有几个星期,在这样的环境下,可以毫不犹豫地选择云托管。
如果是一个小规模的公司,可能无法提供足够的硬件来自建数据中心以满足一个非常流行的Facebook应用的发展曲线。我们也协助过一些大型的Facebook应用进行扩展,它们能够以今人惊讶的速度增长——有时甚至会快到让一个主机托管公司耗尽资源。更为严重的是,这些应用的增长是完全无法预测的;它们可能只有极少量的用户(也可能突然有了爆炸性的用户数量增长)。我们在数据中心和云中都遇到过这样的应用。如果是一个小公司,云可以帮你避免前期快速注入大量的资金来获得更快更大规模的风险。
云的另一种潜在的大用途是运行不是很重要的基础设施,例如集成环境、开发测试平台,以及评估环境。假设部署周期是两个星期。你会每天每个小时都测试部署一次,还是只在项目最后的冲刺时测试?许多用户只是偶尔需要筹划和部署测试环境。在这种场景下,云可以帮助节约不少钱。
以下是我们使用云的两种方式。第一个是作为我们对技术职员面试的一部分,我们会询问如何解决一些实际的问题。我们使用AMI(Amazon Machine Images)来模拟一些被“破坏”的机器,然后让求职者登录并在服务器上执行一系列任务。我们不必开放他们到内部网络的授权,这种方案显然要方便得多。另一个是作为新项目的工作平台和开发服务器。有一个这样的项目已经在一台云端开发服务器上运行了数个月,而花费不足一美元!这在我们自己的基础设施上是不可能做到的。单是发送一封邮件给系统管理员申请开发服务器的时间价值就不止一美元。
但是另一方面,云托管对于长期项目而言可能会更加昂贵。如果打算长远地使用云,就需要花时间来计算一下(它是否划算)。除了猜想未来的创新能给云计算和商用硬件带来什么,还需要做基准测试以及一个完整的总体持有成本(TCO)账单。为了理清事情的本质并考虑全面所有相关的细节,你需要把所有的事情最终归结为一个数字:每美元的业务交易数。事情变化得太快,所以我们将这个留给读者思考。
13.3 云中的MySQL的可扩展性和高可用性 #
正如我们之前提到的,MySQL并不会在云端自动变得更具扩展性。事实上,如果机器的性能较差,会导致过早使用横向扩展策略。况且云托管服务器相比专用的硬件可靠性和可预测性要更差些,所以想在云端获得高可用性需要更多的创新。
但是总的来说,在云端中扩展MySQL和在其他地方扩展没有太多的差别。最大的不同就是按需提供服务器的能力。但是也有某些限制会导致扩展和高可用实现起来有点麻烦,至少在有些云环境中是这样的。例如,在AWS云平台中,无法使用类似虚拟IP地址的功能来完成快速原子故障转移。像这种对资源的有限控制意味着你需要使用其他办法,例如代理。(ScaleBase也值得去看看。)
云另外一个迷惑人的地方是梦想中的自动扩展——就是根据需求的增加或减少来启动或关闭实例。尽管对于诸如Web服务器这样的无状态部分是可行的,但对于数据库服务器而言则很难做到,因为它是有状态的。对于一些特定的场景,例如以读为主的应用,可以通过增加备库的方式来获得有限的自动扩展(4),但这并不是一个通用的解决方案。实际上,虽然许多应用在Web层使用了自动扩展,但MySQL并不具备在一个无共享(Shared Nothing)集群中的对等角色服务器之间迁移的能力。你可以通过分片架构来自动重新分片并自动增长或收缩(5),但MySQL本身是无法自动扩展的。
事实上,因为数据库通常是一个应用系统中主要或唯一的有状态并且持久化的组件,所以把应用服务迁移到云端是很普遍的事情,因为除数据库之外的所有部分都可以从云中收益——Web服务器、工作队列服务器、缓存等——而MySQL只需要处理剩下的东西。毕竟,数据库并非世界的中心。如果应用系统其他部分获得的好处,超过了让MySQL运行得足够好而投入的额外开销和必需的工作量,那这不是一个是否会发生的问题,而是怎么发生的问题。要回答这个问题,最好先了解你在云中可能碰到的额外的挑战。这些通常围绕着数据库服务器的可用资源。
13.4 四种基础资源 #
MySQL需要四种基础资源来完成工作:CPU周期、内存、I/O,以及网络。这四种资源的特性和重要程度在不同的云平台上各不相同。可以通过了解它们的不同之处和对MySQL的影响,以决定是否选择在云中托管MySQL。
- CPU通常很少且慢。在写作本书时最大的标准EC2实例提供8个虚拟CPU核心。EC2提供的虚拟CPU比高端CPU的速度明显要慢很多(可以查看本章稍后的基准测试结果)。虽然可能略有不同,但很可能在大多数云托管平台中这都是一种普遍现象。EC2提供使用多个CPU资源的实例,但它们的最大可用内存却更低。在写作本书时商用服务器能提供几十个CPU核心——甚至更多,如果按硬件线程算的话。(6)
- 内存大小受限制。最大的EC2实例当前能提供68.4GB的内存。与此相比,商用服务器能提供512GB~1TB的内存。
- I/O的吞吐量、延迟以及一致性受到限制。在AWS云中有两个存储选项。
第一个选择是使用EBS卷,这有点类似云中的SAN。AWS的最佳实践是在用EBS组建的RAID10卷上建立服务器。但是EBS是一个共享资源,就像EC2服务器和EBS服务器之间的网络连接。延迟可能会很高并且不可预测,即使是在适量的吞吐量需求下也是如此。我们已经测得EBS设备的I/O延迟可以达到十几分之一秒。相比之下,直接插在本机的商用硬盘驱动器只需几个毫秒,而闪存设备比硬盘驱动器的速度又要高出几个数量级。但另一方面,EBS卷也有许多很好的特性,例如和其他AWS服务、快照等结合起来使用。
第二个选择是实例的本地存储。每个EC2服务器有一定数量的本地存储,实际安装在底层服务器上。它能够比EBS提供更多的一致性性能(7),但如果实例停止了就无法做到持久化。正是由于这样的特性导致其不适合大多数的数据库服务器场景。 - 尽管网络通常是一个变化多端的共享资源,但是性能通常比较好。虽然使用商用硬件可以获得更快更持续的网络性能,但CPU、RAM和I/O更容易成为主要的性能瓶颈,在AWS云中我们还没有遇到过网络性能问题。
正如你所看到的,四种基础资源中有三种在AWS云中是受限的,在某些场景下尤其明显。总的来说,这些基础资源并没有商业硬件那样的性能。下一节我们会讨论这些确切的结论。
13.5 MySQL在云主机上的性能 #
通常,由于较差的CPU、内存以及I/O性能,在类似AWS这样的云托管平台上MySQL所表现出来的性能并不如在其他地方好。这些情况在不同的云平台之间略有不同,但这依然是普遍的事实(8)。然而对于你的需求而言,云主机可能仍然是一个性能足够高的平台,在某些需求上云平台可能比另外的解决方案要好。
如果使用更糟糕的硬件来运行MySQL,无法让MySQL性能比托管在云平台上更高,这并不奇怪。真正让人感到困惑的是在相似规格的物理硬件条件下却无法获得同样的运行速度。例如,如果有一台服务器拥有8个CPU核心,16GB内存以及一个中等的RAID阵列,你可能认为能够获得和一个拥有8个EC2计算单元、15GB内存以及少量EBS卷的EC2实例相同的性能,但这是无法保证的。EC2实例的性能可能比你的物理硬件更加多变,特别是它不是一个超大实例时,可以推测它跟其他实例共享了同样的硬件资源。
稳定性确实非常重要。MySQL和InnoDB尤其不喜欢不稳定的性能——特别是不稳定的I/O性能。I/O操作会请求服务器内部的互斥锁,当持续时间太长时,就会显著地导致很多“阻塞”进程堆积起来,出现令人难以理解的长时间运行的查询语句,以及例如Threads_running或Threads_connected这样的状态变量产生毛刺。
实际应用中前后不一致或者无法预测的性能导致的结果就是排队变得越来越严重。排队是响应时间和到达间隔时间多变自然会导致的结果,并且有个完整的数学分支专门致力于排队的研究。所有的计算机都是队列系统的网络,当需要请求的资源(CPU、I/O,网络,等等)繁忙时,请求必须等待。当资源性能更加多变时,请求更容易堆叠,会出现更多的排队现象。因此,在大多数云计算平台上很难获得高并发或者稳定的低响应时间。我们有很多次在EC2平台上遭受到这个限制的经验。以我们的经验来看,即便在最大的实例上运行的MySQL,在典型的Web OLTP工作负载上,你能够期待的最高并发度也就是Threads_running值为8~12。根据经验,当超过这个值时,性能会越来越不可接受。
注意我们所说的“典型的Web OLTP工作负载”,并非所有的工作负载都以相同的方式反映云平台的限制。确实有一些工作负载在云中表现得很好,而有一些则受到严重影响,让我们看看到底有哪些。
- 正如我们刚讨论的,需要高并发的工作负载并不是非常适合云计算。对于那些要求非常快的响应时间的应用同样如此。原因可以归结于虚拟CPU的数目和速度方面的限制。每个MySQL查询运行在一个单独的CPU上,所以查询响应时间实际上是由CPU的原始速度决定的。如果期望得到更快的响应时间,就需要更快的CPU。为了支持更高的并发度,你需要更多的CPU。MySQL和InnoDB不会因为运行在大量CPU核心上而提供爆炸式的改进,但目前通常能在至少24个核心上获得比较好的横向扩展,这通常比在云中能够获得的核心数更多。
- 那些需要大量I/O的工作负载在云中并不总是表现很好。当I/O很慢并且不稳定时,工作会很快中断。但另一方面,如果你的工作负载不需要太多的I/O,不管是吞吐量(每秒的执行量)还是带宽(每秒字节数),MySQL就可以运行得很好。
之前的几点是根据云端的CPU和I/O资源的缺点得出的。那么关于这些你可以做点什么呢?对于CPU限制你做不了太多,不够就是不够。但是I/O则不同。I/O实际上是两种存储器的交换:非永久存储器(RAM)和持久化存储器(磁盘、EBS,或者其他你所拥有的)。因此MySQL的I/O需求会受系统内存大小的影响。当有足够的内存时,可以从缓存中读取数据,从而减少读和写操作的I/O。写入同样可以缓存在内存里,多个对相同内存比特位的写入可以合并成单个I/O操作。
内存的限制就出现了。当拥有足够的内存来存放工作数据集时(9),某些工作负载的I/O需求可以明显减少。更大的EC2实例也会提供更好的网络性能,更有利于EBS卷的I/O。但如果工作集太大,无法装入可用的最大实例,则I/O需求会逐渐上升,并开始阻塞甚至停止服务,正如我们之前讨论的那样。EC2中内存最大的实例能够很好地为许多工作负载提供足够的内存。但是你需要意识到,预热时间可能会很长;关于这一话题本节后面会有更多的讨论。
哪种类型的工作负载无法通过增加更多的内存来解决呢?除了缓存外,一些写入很大的工作负载需要的I/O比你能从多数云计算平台上获得的要多。例如,如果每秒执行事务数很多,那么每秒就需要执行更多的I/O操作以保证持久性。你只能从诸如EBS这样的系统中获得这么多的吞吐量。同样地,如果你正在将大量数据写入到数据库中,可能会超过可用的带宽。
你可能认为通过RAID来为EBS卷进行条带(striping)和镜像可以改善I/O性能。在某种程度上确实有帮助。问题是,当增加更多的EBS卷时,在我们需要某个EBS卷的任意时间点都增加了它性能变差的可能性,而根据InnoDB内部I/O工作的方式,最差的一环通常是整个系统的瓶颈。实际上,我们已经尝试过10和20个EBS卷的RAID 10集合, 20卷的RAID比10卷的遭遇了更多的停顿(stall)问题。当我们测量底层块设备的I/O性能时,很明显只有一或两个EBS卷表现得很慢,但是却已经影响了整个系统。
你也可以改变应用和服务器来减少I/O需求,考虑周到的逻辑和物理数据库设计(Schema和索引)对于减少I/O请求大有帮助,应用程序优化和查询优化也一样。这是减少I/O最有效的手段。例如插入量很大的工作负载,明智地使用分区,将I/O集中到索引能完全加载到内存中的单个分区上,就会有所帮助。你也可以通过设置innodb_flush_logs_at_trx_commit=2 和来降低持久性,或者将InnoDB事务日志和二进制日志从EBS卷中转移到一个本地驱动器上(尽管这有风险)。但是你从服务器上压榨一点额外的性能越困难,就越不可避免地要引入更大的复杂性(以及它们的成本)。
此外还可以升级MySQL服务器软件。新版本的MySQL和InnoDB(最新的使用InnoDB Plugin的MySQL 5.1,或者MySQL 5.5及更新的版本)能够提供更好的I/O性能以及更少的内部瓶颈,并且相比5.1及之前的版本遭受的停顿和堆积会少很多。Percona Server在某些工作负载下能够提供更多的好处。例如,Percona Server的快速预热缓冲池特性在服务器重启后能够帮助备用服务器快速运行起来,特别是I/O性能不是很好并且服务器依赖于内存时。这也是我们讨论能在云中获得好的性能的候选场景,这里服务器比备用硬件更容易发生故障。Percona Server能够将预热时间从几个小时甚至几天减少到几分钟。在写作本书时,类似的预热特性在MySQL 5.6的开发里程碑版本里已经可用了。
尽管最终一个增长的应用总会达到一个顶点,届时你不得不对数据库进行拆分以保证数据能够存放到云中。我们倾向于尽量不拆分,但如果你只有这么点马力,当达到某个点时,就不得不去其他地方(离开这个云),或者将其拆分为多份,使每份数据需要的资源不超过虚拟硬件能提供的。通常当工作集无法适应内存大小时就得要进行分片了,这意味着在最大的EC2实例上的工作集大小为50GB~60GB。与之相对,我们已经有很多在物理硬件上运行几个TB大小级别数据库的经验。在云中你需要更早进行分片。
13.5.1 在云端的MySQL基准测试 #
我们进行了一些基准测试以说明MySQL在AWS云环境中的性能。当需要大量I/O时要在云中获得始终稳定并且可重现的基准测试结果几乎是不可能的,所以我们选择一个内存中的工作负载,本质上可以衡量除了I/O外的所有因素。我们使用Percona Server 5.5.16,缓冲池为4GB,在一千万行数据上运行标准SysBench只读基准测试。这样就可以根据不同的实例大小进行比较。我们忽略了高频率CPU实例,因为它们实际上比m2.4xlarge 实例的CPU性能要差。我们还引用了一台Cisco服务器作为参考。Cisco机器性能非常高但有点老化了,使用的是两个2.93GHz的Xeon X5670 Nehalem CPU。每个CPU有6个核心,每个核心上有两个硬件线程,在操作系统来看总共有24个CPU。图13-1显示了测试的结果。
图13-1:使用SysBench对AWS云中的MySQL进行只读基准测试
根据工作负载和硬件来看,这样的结果并不奇怪。例如,最大的EC2实例最高有8个线程,因为它有8个CPU核心。(读/写工作负载会花费一些CPU之外的时间来做I/O,所以我们能获得超过8个线程的有效并发度)。图13-1可能会让你认为Cisco的优势就是CPU能力,这也是我们原本认为的。所以我们使用SysBench的质数基准测试来测试原始CPU性能。结果如图13-2所示。
图13-2:使用SysBench对AWS服务器进行CPU质数基准测试
Cisco服务器每个CPU的性能比EC2服务器要低,奇怪么?我们也感到非常奇怪。质数基准测试本质上是原始CPU指令,因此不应该有非常明显的虚拟化开销或者太多的内存交换。对于这样的结果我们的解释是这样的:Cisco服务器的CPU已经使用了很多年了,并且比EC2服务器的要慢。但是对于一些更加复杂的任务,例如运行数据库服务器, EC2服务器会受到虚拟化开销的影响。区分慢CPU、慢内存访问以及虚拟化开销并不总是很容易,但在这个实例中这种区别看起来很明显。
13.6 MySQL数据库即服务(DBaaS) #
在云端服务器上安装MySQL并不是在云中使用MySQL的唯一方法。已经有越来越多的公司开始将数据库本身作为云资源,称之为数据库即服务(DBaaS,有时候也叫DaaS),这意味着你可以在一个地方使用云中的数据库,而在另外的地方运行真正的服务。虽然我们在本章花很多时间解释了IaaS,但IaaS市场正在快速商品化,我们期望未来重点会转到DBaaS。在写作本书时已经有以下几个DBaaS服务提供商。
13.6.1 Amazon RDS #
我们发现在Amazon的关系数据库(RDS)上进行的开发比其他任何一个DBaaS提供商都要多很多。Amazon RDS不仅仅是一个兼容MySQL的服务;它事实上就是MySQL,所以能够完全兼容你所拥有的MySQL 服务器(10)并能作为替代品提供服务。我们不是很确定,但如大多数人一样,我们相信RDS是托管在使用EBS卷的EC2机器上——Amazon并没有公布底层的技术,但当你足够了解RDS时,这看起来很明显就是MySQL、EC2以及EBS。
系统管理职责完全由Amazon来承担。你没有访问EC2机器的权限;只有登入MySQL的访问凭证。你可以创建数据库、插入数据等。你并没有被控制住,如果有需要,可以将数据导出来转移到其他地方,也可以创建卷快照并挂载到其他机器上。
为了防止你检查或干涉Amazon对服务器或主机实例的管理,RDS做了一些限制。例如一些权限限制。你不能利用SELECT INTO OUTFILE、FILE()、LOAD DATA INFILE或其他方法来通过MySQL访问服务器的文件系统。你不能做任何和复制相关的事情,也不能为自己赋予更高的权限。Amazon通过诸如在系统表上设置触发器等方法来进行阻止。并且作为服务条款的一部分,你要同意不会试图绕过这些限制。
安装的MySQL版本做了轻微的修改以阻止用户干涉服务器,其他部分看起来和原版MySQL一样。我们对RDS、EBS和EC2做了基准测试,并没有从该平台上发现超出我们预期的变化。也就是说,看起来Amazon并没有对服务器做任何性能增强。
RDS可以提供一些比较吸引人的好处,这取决于你的具体情况。
- 你可以将系统管理甚至许多数据库管理的工作留给Amazon。例如,他们会为你进行复制并保证你不会把事情搞砸。
- RDS相比其他选择而言可能更便宜,这取决于你的成本结构和人力资源。
- RDS中的限制也许是件好事:Amazon拿走了那把子弹上膛的枪,防止你用它自残。
但是,它也有一些潜在的缺点。
- 由于无法控制服务器,也就无法弄清操作系统中到底发生了什么。例如,你无法衡量I/O响应时间和CPU利用率。Amazon通过另一个服务CloudWatch提供了这一功能。它给出了足够的指标用于排查许多性能问题,但有时候你需要原始数据以知道到底发生了什么。(也无法使用类似FILE()这样的函数来访问 /proc/diskstats。)
- 无法获得完整的慢查询日志文件。你可以指定MySQL将慢查询记录到一个CSV日志表中,但这并不是很好。它会消耗很多服务器资源,并且不会给出精确的查询响应时间。这使得很难去分析和排除SQL故障。
- 如果你希望得到最新最好的,或者一些性能上的增强,例如那些你可以从Percona Server上获得的提升,那就不走运了,RDS并不提供这些。
- 你必须依赖Amazon的支持团队来解决一些问题,而这些问题可能本来是你自己可以解决的。例如,假设查询挂起了,或者服务器由于数据损坏崩溃了。你既可以等待Amazon来解决,也可以自己解决。如果是后者你就需要把数据转移到别的地方。你无法通过访问实例本身来解决。如果想这么做,你不得不额外花一些时间并支付额外的资源。这不只是理论上的推测;我们已经接到过许多技术支持请求,这些请求通常需要系统权限以进行故障排查,因此对于RDS用户而言是无法真正解决的。
正如我们所说,在性能方面,RDS跟一个大型大内存的使用EBS存储和原始MySQL的EC2实例相似。如果直接使用EC2和EBS并安装一个高性能版本的MySQL(例如Percona Server),你可以从AWS云中压榨出一点更高的性能,但这不会是一个数量级上的区别。考虑到这一点,有理由根据你的商业需求而非性能需求来决定是否使用RDS。如果确实非常要求高性能,那你根本就不应该使用AWS云。
13.6.2 其他DBaaS解决方案 #
Amazon RDS并不是MySQL用户唯一可选的DBaaS解决方案。还有诸如 FathomDB ( http://fathomdb.com)以及Xeround( http://xeround.com)等服务。但我们并没有足够的第一手经验来介绍它们,因为我们还没有在这些服务上做任何的生产部署。从关于FathomDB的一些有限的公开信息来看,它和Amazon RDS有点类似,虽然它也和AWS云一样可以在Rackspace云上获得。在写作本书时它还处于内部测试阶段。
Xeround 则有很大的不同之处:它是一个分布式服务器集群,前端是一个包含特定存储引擎的MySQL。它似乎和原始版本MySQL有少量的不兼容或不同之处。但它只是最近才发布正式GA版本(GA,generally available),所以现在下定论为时尚早。存储引擎似乎是用于和后台集群系统通信,这看起来有点和NDB CLuster类似。它增加了自动重分布功能,可以在工作负载增加或减少时自动地增加和去除节点(动态扩展)。
还有许多其他的DBaaS服务,新的服务也在不断地推出。我们这里所写的任何内容都可能在你阅读时已经过时了,所以我们将其留给你自己来研究。
13.7 总结 #
在云端使用MySQL至少有两种主流的方法:在云服务器上安装MySQL,或者使用DBaaS服务。MySQL能够在云主机上运行得很好,但云环境中的限制常常会导致更早需要进行数据拆分。并且尽管云服务器看起来和你的物理硬件很相似,但可能性能和服务质量要更低。
有时候似乎有人会说“云就是答案,有什么问题吗?”这是一个极端,但那些认为云是一个银弹的狂热信众,也有类似的问题。数据库所需要的四种基础资源中的三种(CPU、内存和磁盘)在云中明显更差并且/或者效率更低,会直接影响到MySQL的性能。
但是对于很多工作负载而言,MySQL能够在云中运行得很好。通常来说,如果能将工作集加载到内存中,并且产生的写入负载不超过云能支撑的I/O量,那么就可以获得很好的效果。通过严谨的设计和架构,选择正确的MySQL版本并做合适的配置,可以使你的数据库工作负载和容量能适应云的长处。但是MySQL并不是天生的云数据库;也就是说,它无法完全使用云计算理论上能提供的优点,例如自动扩展。但是一些可替代的技术(例如Xeround)正在尝试解决这些缺点。
我们已经讨论了很多跟云相关的缺点,这也许会给你一个我们反对云计算的印象。并非如此。这只是因为我们只集中在MySQL上,而不是讨论云计算所有的优点,这可能跟你从其他地方阅读到的非常不一样。我们在试着指出在云端运行MySQL有哪些不同,以及哪些是你需要知道的。
我们看到在云中最大的成功是由于商业原因做出的决策。即使长期来看每个商业交易的开销在云中会更高,但其他方面的因素,诸如增加了弹性、减少了前期成本、减少了推向市场的时间,以及降低了风险,这可能更重要。并且你的应用中其他和MySQL无关的部分所获得的好处要远远大于(在云端)使用MySQL带来的弊端。
————————————————————
(1) OK,我们承认。Amazon网络服务是一个云。本章主要讨论AWS。
(2) 参阅 George Reese所写的Cloud Application Architectures(O’Reilly)。
(3) 我们不是说这会更加容易或便宜,我们只是说云并不是能获得这些好处的唯一途径。
(4) Scalr ( http://scalr.net)是一个流行的开源服务,用于在云中进行MySQL复制自动扩展。
(5) 计算机科学家喜欢将之称为“重大挑战”(non-trivial challenge)。
(6) 在CPU、RAM以及I/O上,商用硬件能够提供超过MySQL可以有效利用的硬件能力,所以将云与云之外可获得的最强硬件相比较并不是完全公平的。
(7) 直到写入的时候本地存储才会被分配给实例,导致每个写入的块发生“第一次写处罚”(first-write penalty)。避免这个问题的办法是使用dd去写满设备。
(8) 如果你相信 http://www.xkcd.com/908/,那么显然所有的云都有同样的缺点,我们刚刚已经提过。
(9) 参阅第9章关于工作集的定义及其如何影响I/O需求的讨论。
(10) 除非你使用别的存储引擎或者其他一些非标准的MySQL修改版本。