第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云中是受限的,在某些场景下尤其明显。总的来说,这些基础资源并没有商业硬件那样的性能。下一节我们会讨论这些确切的结论。
图11-1:一个只有一台服务器的系统
图11-2:一个线性扩展的系统能由两台服务器获得两倍容量
图11-3:一个非线性扩展的系统
图11-4:线性扩展、AmdahI扩展以及USL扩展定律