应用层优化
缓存
作为基础组件的缓存
缓存有可能成为基础设施的重要组成部分。也很容易陷入一个陷阱,认为缓存虽然很好用,但并不是重要到非有不可得东西。你也许会辩驳,如果缓存服务器宕机或者缓存被清空,请求也可以直接落在数据库上,系统依然可以正常运行。如果是刚刚将缓存加入应用系统,这也许是对的,但缓存的加入可以使得在应用压力显著增长时不需要对系统的某些部分同比增加资源投入——通常是数据部分。因此,系统可能慢慢地变得对缓存非常依赖,却没有被发觉。
例如,如果高速缓存命中率是90%,当由于某种原因失去缓存,数据库上的负载将增加到原来的10倍。这很可能导致压力超过数据库服务器的性能极限。为了避免像这样的意外,应该设计一些高可用性缓存(包括数据和服务)的解决方案,或者至少是评估好禁用缓存或丢失缓存时的性能影响。比如说可以设计应用在遇到这样的情况时能够进行降级处理。
使用HandlerSocket和memcached
相对于数据存储在MySQL中而缓存在MySQL外部的缓存方案,另外有一种替代方法是为MySQL创建一个更快的访问路径,直接绕过使用缓存。对于小儿简单的查询语句,很大一部分开销来自解析SQL,检查权限,生成执行计划,等等。如果这种开销可以避免,MySQL在处理简单查询时将非常快。目前有两个解决方案可以用所谓的NoSQL方式访问MySQL。第一种时一个后台进程插件,成为HandlerSocket,由DeNA开发,这是日本最大的社交网站。HandlerSocket允许通过一个简单的协议访问InnoDB Handler对象。实际上,也就是绕过了上层的服务器层,通过网络直接连接到了InnoDB引擎层。有报告称HandlerSocket每秒可以执行超过750 000条查询。Percona Server分支中自带了HandlerSocket插件引擎层。第二个方案时通过memcached协议访问InnoDB。MySQL5.6的实验室版本有一个插件提供了这个接口。两种方法都有一些限制——特别是memcached的方法,这种方法对很多访问数据的方法都不支持。为什么会希望采用SQL以外的办法访问数据呢?除了速度之外,最大的可能是简单。这样做最大的好处是可以摆脱缓存,以及所有的失效逻辑,还有为它们服务的额外的基础设施
拓展MySQL
如果MySQL不能做你需要的事,一种可能是拓展其功能。在这里不会展示如何去做到这一点,但会提供一些可能的方向。如果你对进一步探索有兴趣,那么有很多很好的在线资源。当我们说"MySQL不能做你需要的事",我们指的是两件事情:MySQL根本做不到这一点或者MySQL可以做到,但是只能通过缓慢或笨拙的方法,总之做得不够好。无论哪个都是需要对MySQL拓展的原因。好消息事,MySQL已经越来越模块化和通用。存储引擎是拓展MySQL的一个很好的方式。Brian Aker已经写了一个存储引擎的框架,还有一系列介绍有关如何开始编写自己的存储引擎的文章。这是目前几个主要的第三方存储引擎的基础。许多公司都编写了它们自己的内部存储引擎。例如,一些社交网站公司使用了特殊的为社交图形操作设计的存储引擎,我们还知道有个公司定制了一个用于模糊搜索的引擎。写一个简单的自定义存储引擎并不难。还可以使用存储引擎作为另一个软件的接口。Sphinx引擎就是一个很好的例子,该引擎是Spinx全文检索软件的接口
MySQL的替代品
MySQL并不是适合每一个场景的解决方案。有些工作通常在MySQL以外来做会更好,即使MySQL理论上也可以做到。最明显的一个例子是在传统的文件系统中存储文件,而不是在表中。图像文件是静丹案例:虽然可以把它们放到一个BLOB列,但这通常不是个好办法(使用MySQL的复制来快速分布镜像到其他机器更有优势,我们知道一些程序使用这种技术)。一般的做法是,在文件系统中存储图片或其他大型二进制文件,而在MySQL中只存储文件名;然后应用程序在MySQL之外存取文件。对于Web应用程序,可以把文件名放在元素的src属性中,这样就可以实现对文件的存取。
全文检索是另一个最好放在MySQL之外处理额例子——MySQL在全文搜索方面明显不如Lucene和Sphinx。 NDB API也可能对某些任务有用。例如,尽管MySQL的NDB集群存储引擎(目前还)不适合存储一个高性能Web应用程序的全部数据,但用NDB API直接存储网站会话数据或用户注册信息还是可能的。在如下网站可以了解到更多NDB API的内容.还有供Apache使用的NDB模块,mod_ndb.
最后,对于某些操作——如图形关系和树遍历——关系型数据并不总是正确的典范,MySQL并不擅长分布式数据处理,因为它缺乏并行执行查询的能力。处于这些目的情况还是建议使用其他工具(可能与MySQL结合).现在想到的例子包括:
- 1.对于简单的键——值存储,在复制严重落后的非常高速的访问场景中,我们建议用Redis替换MySQL.即使MySQL主库可以承担这样的压力,备库的延迟也是非常让人头疼的。Redis也常用来做队列,因为它对队列操作支持得很好
- 2.Hadoop是房间中得大象,一语双关。混合MySQL/Hadoop得部署在处理大型或半结构化数据时非常常见
备份与恢复
概述
如果没有提前做好备份规划,也许以后会发现已经错失了一些最佳得选择。例如,在服务器已经配置好了以后,才想起应该使用LVM,以便可以获取文件系统的快照——但这时已经太迟了。在为别分配置系统参数时,可能没有注意到某些系统配置对性能有着重要影响。如果没有计划做定期的恢复演练,当真的需要恢复时,就会发现并没有那么顺利。在此假设大部分用户主要使用InnoDB而不是MyISAM。也不会涵盖一个精心设计的备份和恢复解决方案的所有部分——而仅涉及与MySQL相关的部分。不打算包括的话题如下:
- 1.安全(访问备份,恢复数据的权限,文件是否需要加密)
- 2.备份存储在哪里,包括它们应该离数据多远(在一块不同的盘上,一台不同的服务器上,或离线存储),以及如何将数据从源头移动到目的地
- 3.保留策略、审计、法律要求,以及相关的条款
- 4.存储解决方案和介质,压缩,以及增量备份
- 5.存储的格式
- 6.对备份的监控和报告
- 7.存储层内置备份功能,或者其他专用设备,例如预制式文件服务器
让我们先澄清几个核心术语。首先,经常可以听到所谓的热备份、暖备份和冷备份。人们经常使用这些词来表示一个备份的影响:例如"热"备份不需要任何的服务停机时间。问题是对这些术语的理解因人而异。有些工具虽然在名字中使用了"热备份",但实际上并不是所认为的那样。我们尽量避开这些术语,而直接说明某个特别的技术或工具对服务器的影响。另外两个让人困惑的词是还原和恢复。还原意味着从备份文件中获取数据,可以加载这些文件到MySQL里,也可以将这些文件放置到MySQL期望的路径中。恢复一般意味着当某些异常发生后对一个系统或其部分的拯救。包括从备份中还原数据,以及使服务器完全恢复功能的所有必要步骤,例如重启MySQL、改变配置和预热服务器的缓存等。
在很多人的概念中,恢复仅意味着修复崩溃后损坏的表。这与恢复一个完整的服务器使不同的。存储引擎的崩溃恢复要求数据和日志文件一致。要确保数据文件中只包含已经提交的事务所做的修改,恢复操作会将日志中还没有应用到数据文件的事务重新执行。这也许是恢复过程的一部分,甚至是备份的一部分。然而,这和一个意外的DROP TABLE事故后需要做的事是不一样的。
为什么要备份?
下面是备份非常重要的几个理由:
- 1.灾难恢复
灾难恢复是下列场景下需要做的事情:硬件故障、一个不经意的Bug导致数据损坏,或者服务器及其数据由于欧协原因不可获取或无法使用等。你需要准备好应付很多问题:某人偶尔连错数据库服务器执行了一个ALTER TABLE的操作,计放大楼被炸毁,恶意的黑客攻击或MySQL的Bug等。尽管遭受任何一个特殊的灾难的几率都非常低,但所有的风险叠加在一起就很有可能会碰到 - 2.人们改变象发
不必惊讶,很多人经常会在删除某些数据后又想要恢复这些数据 - 3.审计
有时候需要知道数据或Schema在过去的某个时间点是什么样的。例如,你也许被卷入一场法律官司,或发现了应用的一个Bug,想知道这段代码之前干了什么(有时候仅仅依靠代码的版本控制还不够) - 4.测试
一个最简单的基于实际数据来测试的方法是,定期用最新的生产环境数据更i性能测试服务器。如果使用备份的方案就非常简单:只要把备份文件还原到测试服务器上即可。
检查你的假设。例如, 你认为共享虚拟主机供应商会提供MySQL服务器的备份?许多主机供应商根本不备份MySQL服务器,另外一些也仅仅在服务器运行时复制文件,这可能会创建一个损坏的没有用处的备份