MySQL性能调优与架构设计——第 15 章 可扩展性设计之Cache与Search的利用

第 15 章 可扩展性设计之Cache与Search的利用

前言:

前面章节部分所分析的可扩展架构方案,基本上都是围绕在数据库自身来进行的,这样是否会使我们在寻求扩展性之路的思维受到“禁锢”,无法更为宽广的发散开来。这一章,我们就将跳出完全依靠数据库自身来改善扩展性的问题,将数据服务扩展性的改善向数据库之外的天地延伸!

15.1 可扩展设计的数据库之外延伸

数据库主要就是为应用程序提供数据存取相应的服务,提高数据库的扩展性,也是为了更好的提供数据存取服务能力,同时包括可靠性,高效性以及易用性。所以,我们最根本的目的就是让数据层的存储服务能力得到更好的扩展性,让我们的投入尽可能的与产出成正比。
我们都明白一点,数据本身肯定都会需要有一个可以持久化地方,但是我们是否有必要让我们的所有冗余数据都进行持久化呢?我想读者朋友们肯定都会觉得没有这个必要,只要保证有至少两份冗余的数据进行持久化就足够了。而另外一些为了提高扩展性而产生的冗余数据,我们完全可以通过一些特别的技术来替代需要持久化的数据库,如内存 Cache,Search以及磁盘文件 Cache 和 Search 等等。
寻求数据库软件本身之外的 Cache 和 Search 来解决数据本身的扩展性,已经成为目前各个大型互联网站点都在积极尝试的一个非常重要的架构升级。因为这不仅仅能更大程度的在整个应用系统提升数据处理层本身的扩展性,而且还能更大限度的提升性能。
对于这种架构方式,目前已经比较成熟的解决方案主要有基于对象的分布式内存 Cache 解决方案 Memcached,高性能嵌入式数据库编程库 Berkeley DB ,功能强大的全文搜索引擎 Lucene 等等。
当然,在使用成熟的第三方产品的同时,偶尔自行实现一些特定应用场景下的 Cache 和 Search,也未尝不是一件值得尝试的事情,而且对于公司的技术积累来说也是很有意义的一件事情。当然,决定自行开发实现之前进行全面的评估是绝对必要的,不仅仅包括自身技术实力,对应用的商业需求也需要有一定的评估才行。
其实,不论是使用现成的第三方成熟解决方案还是自主研发,都是需要在开发资源方面有一定投入的。首先要想很好的和现有 MySQL 数据库更好的结合,就有多种思路存在。可以在数据库端实现和 Cache 或者 Search 的数据通讯(数据更新),也可以在应用程序端直接实现 Cache 与 Search 的数据更新。数据库和 Cache 与 Search 可以处于整体架构中不同的层次,也可以并存于相同的层次。
下面我分别针对使用第三方成熟解决方案以及自主研发来进行一些针对性的分析和架构思路探讨,希望对各位读者朋友有一定的帮助。

15.2 合理利用第三方Cache解决方案

使用较为成熟的第三方解决方案最大的优势就在于在节省自身研发成本的同时,还能够在互联网上面找到较多的文档信息,帮助我们解决一些日常遇到的问题还是非常有帮助的。
目前比较流行的第三方 Cache 解决方案主要有基于对象的分布式内存 Cache 软件Memcached 和嵌入式数据库编程库 Berkeley DB 这两种。下面我将分别针对这两种解决方案做一个分析和架构探讨。

15.2.1 分布式内存 Cache 软件 Memcached

相信对于很多读者朋友来说,Memcached 并不会太陌生了吧,他现在的流行程度已经比MySQL 并不会差太多了。Memcached 之所以如此的流行,主要是因为以下几个原因:
◆ 通信协议简单,API接口清晰;
◆ 高效的 Cache 算法,基于 libevent 的事件处理机制,性能卓越;
◆ 面向对象的特性,对应用开发人员来说非常友好;
◆ 所有数据都存放于内存中,数据访问高效;
◆ 软件开源,基于 BSD 开源协议;
对于 Memcached 本身细节,这里我就不涉及太多了,毕竟这不是本书的重点。下面我们重点看看如何通过 Memcached 来帮助我们你提升数据服务(这里如果再使用数据库本身可能会不太合适了)的扩展性。
要将 Memcached 较好的整合到系统架构中,首先要在应用系统中让 Memcached 有一个准确的定位。是仅仅作为提升数据服务性能的一个 Cache 工具,还是让他与 MySQL 数据库较好的融合在一起成为一个更为更为高效理想的数据服务层。
1. 作为提升系统性能的 Cache 工具
如果我们仅仅只是系统通过 Memcached 来提升系统性能,作为一个 Cache 软件,那么更多的是需要通过应用程序来维护 Memcached 中的数据与数据库中数据的同步更新。这时候的 Memcached 基本可以理解为比 MySQL 数据库更为前端的一个 Cache 层。
如果我们将 Memcached 作为应用系统的一个数据 Cache 服务,那么对于 MySQL 数据库来说基本上不用做任何改造,仅仅通过应用程序自己来对这个 Cache 进行维护更新。这样作最大的好处就在于可以做到完全不用动数据库相关的架构,但是同时也会有一个弊端,那就是如果需要 Cache 的数据对象较多的时候,应用程序所需要增加的代码量就会增加很多,同时系统复杂度以及维护成本也会直线上升。
下面是将 Memcached 用为简单的 Cache 服务层的时候的架构简图。
MySQL性能调优与架构设计——第 15 章 可扩展性设计之Cache与Search的利用
从图中我们可以看到,所有数据都会写入 MySQL Master 中,包括数据第一次写入时候的INSERT,同时也包括对已有数据的 UPDATE 和 DELETE。不过,如果是对已经存在的数据,则需要在 UPDATE 或者 DELETE MySQL 中数据的同时,删除 Memcached 中的数据,以此保证整体数据的一致性。而所有的读请求首先会发往 Memcached 中,如果读取到数据则直接返回,如果没有读取到数据,则再到 MySQL Slaves 中读取数据,并将读取得到的数据写入到 Memcached 中进行 Cache。
这种使用方式一般来说比较适用于需要缓存对象类型少,而需要缓存的数据量又比较大的环境,是一个快速有效的完全针对性能问题的解决方案。由于这种架构方式和 MySQL 数据库本身并没有太大关系,所以这里就不涉及太多的技术细节了。
2. 和 MySQL 整合为数据服务层
除了将 Memcached 用作快速提升效率的工具之外,我们其实还可以将之利用到提高数据服务层的扩展性方面,和我们的数据库整合成一个整体,或者作为数据库的一个缓冲。 我们首先看看如何将 Memcached 和MySQL 数据库整合成一个整体来对外提供服务吧。
一般来说,我们有两种方式将 Memcached 和 MySQL 数据库整合成一个整体来对外提供数据服务。一种是直接利用 Memcached 的内存容量作为 MySQL 数据库的二级缓存,提升 MySQL Server 的缓存大小,另一种是通过 MySQL 的UDF 来和 Memcached 进行数据通信,维护和更新 Memcached 中的数据,而应用端则直接通过 Memcached 来读取数据。
对于第一种方式,主要用于业务要求非常特殊,实在难以进行数据切分,而且有很难通过对应用程序进行改造利用上数据库之外的 Cache 的场景。 当然,在正常情况下是肯定无法做到这一点的,之少目前必须借助外界的力量,开源项目 Waffle Grid 就是我们需要借助的外部力量。I
Waffle Grid 是国外的几位 DBA 在工作之余突发奇想出来的一个点子:既然 PC Server 的低廉成本如此的吸引我们,而其 Scale Up 的能力又很难有一个较大的突破,何不利用上现在非常流行的 Memcached 作为突破单台 PC Server 的内存上限呢?就在这个想法的推动下,几位小伙子启动了 Waffle Grid 这个开源项目,利用 MySQL 和 Memcached 双双开源的特性,结合 Memcached 通信协议简单的特点,将 Memcached 成功实现成为MySQL 主机的外部“二级缓存”,目前仅支持用于 Innodb 的 Buffer Pool。
Waffle Grid 的实现原理其实并不复杂,他所做的事情就是当 Innodb 在本地的Buffer Pool(我们姑且称其为 Local Buffer Pool吧)的时候,在从磁盘数据文件读取数据之前,先通过 Memcached 的通信 API 接口尝试从 Memcached 中读取相应的缓存数据(我们称之为 Remote Buffer吧),只有在 Remote Buffer 中也不存在需要的数据的时候, Innodb 才会访问磁盘文件来读取数据。而且,只有处于 Innodb Buffer pool 中的 LRU List 中的数据会被发送到 Remote Buffer Pool 中,而这些数据一旦被修改,就会 Innodb 就会将之移入 FLUSH List ,Waffle Grid 同时会将进入 FLUSH List 的数据从 Remote Buffer Pool 中清除掉。所以可以说,Remote Buffer Pool 中永远不会存在 Dirty Pages, 这也保证了当 Remote Buffer Pool 出现故障的时候不会产生数据丢失的问题。下图是使用Waffle Grid 项目时候的架构简图:
MySQL性能调优与架构设计——第 15 章 可扩展性设计之Cache与Search的利用
如架构图上所示,我们首先在 MySQL 数据库端应用 Waffle Grid Patch,通过他连与其他的 Memcached 服务器通信。为了保证网络通信的性能,MySQL 与 Memcached 之间尽可能用高带宽私有网络。另外,这里的架构图中并没有再将数据库区分 Master 和 Slave 了,并不是说一定不能区分,只是一个示意图。在实际应用过程中,大部分时候只需要在 Slave 上面应用 Waffle Grid 即可,Master 本身并不需要如此大的内存。
看了 Waffle Grid 的实现原理,可能有些读者朋友会有些疑问了。这样做不是所有需要产生物理读的 Query 的性能就会受到直接影响了吗?所有读取 Remote Buffer 的操作都需要通过网络来获取,其性能是否足够高呢?对此,我同样使用作者对 Waffle 的实测数据来接触大家的疑虑:
MySQL性能调优与架构设计——第 15 章 可扩展性设计之Cache与Search的利用
通过 DBT2 所得到的这组测试对比数据,在性能我想并不需要太多的担忧了吧。至于Waffle Grid 是否适合您的应用场景,那就只能依靠各位读者朋友自己进行评估了。
下面我们再来介绍一下 Memcached 和 MySQL 的另外一种整合方式,也就是通过 MySQL 所提供的 UDF 功能,自行编写相应的程序来实现 MySQL 与 Memcached 的数据通信更新操作。
这种方式和 Waffle Grid 不一样的是 Memcached 中的数据并不完全由 MySQL 来控制维护,而是由应用程序和 MySQL 一起来维护数据。每次应用程序从 Memcached 读取数据的时候,如果发现找不到自己需要的数据,则再转为从数据库中读取数据,然后将读取到的数据写入 Memcached 中。而 MySQL 则控制 Memcached 中数据的失效清理工作,每次数据库中有数据被更新或者被删除的时候,MySQL 则通过用户自行编写的 UDF 来调用 Memcached 的 API 来通知 Memcached 某些数据已经失效并删除该数据。
基于上面的实现原理,我们可以设计出如下这样的一个数据服务层架构:
MySQL性能调优与架构设计——第 15 章 可扩展性设计之Cache与Search的利用
如图中所示,此架构和上面将 Memcached 完全和 MySQL 读离开作为常规的 Cache 服务器来比较,最大的区别在于 Memcached 的数据变为由 MySQL 数据库来维护更新,而不是应用程序来更新。首先数据被应用程序写入 MySQL 数据库,这时候将会触发 MySQL 上面用户自行编写的相关 UDF,然后通过该 UDF 调用 Memcached 的相关通信接口,将数据写入 Memcached。而当 MySQL 中的数据被更新或者删除的时候,MySQL 中的相关 UDF 同样会更新或者删除 Memcached 中的数据。当然,我们也可以让 MySQL 做更少一些的事情, 仅仅只是遇到数据被更新或者删除的时候,通过 UDF 来删除 Memcached 中的数据,写入工作则像前面的架构一样由应用程序来作。
由于 Memcached 基于对象的数据存取,以及通过 Hash 进行数据检索的特性,所以所有存储在 Memcached 中的数据都需要我们设定一个用于标识该数据的 Key,所有数据的存取操作都通过该 Key 来进行。也就是说,如果您并不能像 MySQL 的 Query 语句一样通过某一个(或者多个)关键字条件来读取包含多条数据的结果集,仅适用于通过某个唯一键来获取单条数据的数据读取方式。

15.2.2 嵌入式数据库编程库 Berkeley DB

说实话,数据库编程库这个叫法实在有些别扭,但我也实在找不到其他合适的名词来称呼 Berkeley DB 了,那就姑且使用网上较为通用的叫法吧。
Memcached 所实现的是内存式 Cache,如果我们对性能的要求并没有如此之高,在预算方面也不是太充裕的话,我们还可以选择 Berkeley DB 这样的数据库型 Cache 软件。可能很多读者朋友又会产生疑惑了,我们使用的 MySQL 数据库,为什么还要再使用一个 Berkeley DB 这样的“数据库”呢?实际上 Berkeley DB 在之前也是 MySQL 的存储引擎之一,只不过后期不知道是何原因(获取与商业竞争有关吧),被 MySQL 从支持的存储引擎中移除了。之所以在使用数据库的同时还使用 Berkeley DB 这样的数据库型 Cache,是因为我们可以充分发挥出二者各自的优势,在使用传统通用型数据库的同时,同时可以利用Berkeley DB 高效的键值对存储方式作为高效数据检索的性能补充,以得到更好的数据服务层扩展性和更高的整体性能。
Berkeley DB 自身架构可以分为五个功能模块,五个模块的在整个系统中相对比较独立,而且可以设置使用或者禁用某一个(或者几个)模块,所以可能称之为五个子系统会更为恰当一些。这五个子系统及基本介绍分别如下:
◆ 数据存取
数据存取子系统主要负责最主要也是最基本的数据存与取的工作。而且 Berkeley DB 同时支持了以下四种数据的存储结果方式:Hash,B-Tree,Fixed Length以及Dynamic Length。实际上,这四种方式对应了四种数据文件存储的实际格式。数据存储子系统可以完全单独使用,也是必须开启的一个子系统。
◆ 事务管理
事务管理子系统主要是针对有事务要求的数据处理服务,提供完整的 ACID 事务属性。在开启事务管理子系统的时候,出了需要开启最基本的数据存取子系统外,还至少需要开启锁管理子系统和日志系统来帮助实现事务的一致性和完整性。
◆ 锁管理
锁管理系统主要就是为了保证数据的一致性而提供的共享数据控制功能。支持行级别和页级别的锁定机制,同时为事务管理子系统提供服务。
◆ 共享内存
共享内存子系统我想大家看到名称就应该基本知道是做什么事情的了,就是用来管理维护共享 Cache 和 Buffer 的,为系统提升性能而提供数据缓存服务。
◆ 日志系统
日志系统主要服务于事务管理系统,为保证事务的一致性,Berkeley DB 也采用先写日志再写数据的策略,一般也都是与事务管理系统同时使用同时关闭。
基于 Berkeley DB 的特性,我们很难像使用 Memcached 那样将他和 MySQL 数据库结合的那么紧密。数据的维护与更新操作主要还是需要通过应用程序来完成。一般来说,在使用 MySQL 的同时还要使用 Berkeley DB 的主要原因就是为了提升系统的性能及扩展性。所以,大多数时候都主要是使用 Hash 和 B-Tree 这两种结构的数据存储格式,尤其是 Hash 格式,是使用最为广泛的,因为这种方式也是存取效率最高的。
在应用程序中,每次数据请求,都先通过预先设定的 Key 到 Berkeley DB 中取查找一次,如果存在数据,则返回取得的数据,如果位检索到数据,则再次到数据库中读取。然后将读取到的数据按照预先设定的 Key,整条存入 Berkeley DB 中,再返回给客户端。而当发生数据修改的时候,应用程序在修改 MySQL 中的数据之后必须还要将 Berkeley DB 中的数据删除。当然,如果您愿意,也可以直接修改 Berkeley DB 中的数据,但是这样就可能引入更多的数据一致性风险并提高系统复杂度了。
从原理来看,使用 Berkeley DB 的方式和将 Memcached 作为纯 Cache 来使用差别不大嘛,为什么我们不用 Memcached 来做呢?其实主要有两个原因,一个是 Memcached 是使用纯内存来存放数据的,而 Berkeley DB 则可以使用物理磁盘,两者在成本方面还是有较大差别的。另外一个原因就是 Berkeley DB 所能支持的数据存储方式除了 Memcached 所使用的 Hash 存储格式之外,同时还可以使用其他存储格式,如 B-Tree 等。 由于和 Memcached 的基本使用原理区别不大,所以这里就不再画图示意了。

15.3 自行实现Cache服务

实际上,除了使用比较成熟的现成第三方软件的解决方案之外,如果有一定的技术实力,我们还可以通过自行实现的 Cache 软件来达到完全相同的效果。
当然,您也不要被上面所说的“技术实力”所吓倒,其实也并没有想象中的那么难。只要您不要一开始就希望作出一个能够解决所有问题,而且包含所有其他第三方 Cache 软件的所有优点,还不能遗留任何缺点的软件,不要一开始就希望作出一个多么完美的产品花的软件。从小做起,从精做起。千万别希望一口气吃成一个胖子,这样的解决很可能就是被咽死。
自主研发实现 Cache 服务软件的前提是系统中存在比较特殊的应用场景,通过自主研发可以最大限度的实现比较个性化的需求。当然,也可以针对自己的应用场景进行特定的优化方式来最大限度的提升扩展性和性能。毕竟,只有我们自己才是真正最了解我们的应用系统的人。
决策是否需要自行开发最需要考虑的一个问题就是我的应用系统场景是否真的如此特别,以至于现成的第三方软件很难解决目前的主要问题?
如果目前的第三方软件已经基本解决了我们系统当前遇到的80%以上的问题,可能就需要考虑是否有必要完全自主研发了。毕竟我们选择的所有第三方软件都是开源的,如果有某些小地方无法满足要求,我们完全可以在第三方软件的基础上增加一些我们自己的东西,来满足一些个性化需求。
当我们选择自主研发 Cache 服务软件之后,有以下几点内容是需要注意的:
1. 功能需求
a) 是完全内存还是可以部分磁盘?
b) 需要实时同步更新还是可以允许 Cache 数据有延时?
c) 是否需要支持分布式?
这里所说的功能,实际上就是需求范围的设定。在开始研发之前,我们比需要有一个非常清晰的需求范围,而不是天马行空的边开发边调整,想到啥做啥。毕竟任何软件系统,都是需要以第一线的需求为导向,而且一旦开始开发之后,需求的控制也不能马虎。要不然, 很可能就会中途夭折,以失败而告终。
2. 技术实现
a) 数据同步(或异步)更新机制;
b) 数据存储方式(Hash Or B-Tree);
c) 通讯协议;
技术实现可能会成为研发过程中很大的一个难点,能否有稳定可靠的数据同步(或异步) 更新机制决定了该 Cache 软件最终的成败。当然,你可以说数据同步(或异步)更新完全交由需要访问数据的应用程序来自行维护,但是你是否有足够的能力申请在自行研发实现出一个 Cache 软件的同时,还需要前端应用程序作出巨大的调整来适应这个 Cache 软件是一个很大的未知数。老板很可能会说,既然你都自行研发实现了,为啥不能完成数据更新维护功能呢?而数据存储方式直接决定数据的访问方式,同时实现算法也直接决定了软件的性能。最后,数据传输的通讯协议可能也会让人伤透脑筋。如何设计一个足够简单,但是又做到尽可能不会限制后期的扩展升级的通讯协议,可能并不是一件太轻松的事情。毕竟,如果每次升级都需要动到数据传输通讯协议,那每次升级所带来的应用改造成本也太大了。而太过复杂呢,很可能又会影响到前端应用使用的便利性,而且对性能可能也会有一定影响。
3. 可维护性
a) 方便的管理接口;
b) 高可用支持(自动或人工切换);
c) 基本监控接口;
千万不要忽视了软件系统的维护成本,一个软件一旦开始使用之后,主要工作就是对其进行各种维护。如果可维护性太差,很可能带来极大的维护工作量,甚至带来一线应用人员和运维人员对该软件的信任和使用热情。
使用自行研发的 Cache 服务基于不同的功能特性,可能会有不同的架构组成,但基本上和上面使用 Memcached 所使用的架构区别不大了,所以这里也就不再详细讨论了。
最后,我个人有一个建议就是,在使用比较通用 Cache 服务(也包括自行实现的 Cache 软件服务)的时候,我们应该尽可能将该 Cache 软件与我们的 MySQL 数据库 进行一定的整合,让彼此能够互补。而且前端的应用程序尽量不要直接操作后端的数据服务集群,尽量通过一个中间代理层来接受处理所有的数据处理服务,对前端应用透明化。这样才能够尽可能做到后端数据服务(数据库与 Cache)层在进行任何扩展的时候,影响到的仅仅只是中间代理层,而对前端完全透明,让我们的数据层拥有真正的高扩展性。

15.4 利用Search实现高效的全文检索

不论是使用 Memcached 还是使用 Berkeley DB ,大多数时候都只能通过特定的方式来进行数据的检索,只能满足少部分的检索需求。而数据库本身对于全模糊 LIKE 操作的性能大家应该也很清楚,是非常低下的,因为这种操作无法利用索引。虽然 MySQL 的 MyISAM 存 储引擎支持了全文索引,而且官方版本还不支持多字节字符集的数据,所以对于需要存放中文或者需要使用 MyISAM 之外的存储引擎的用户来说,是完全无法使用的。
对于这种情况,我们只有一个办法可以解决,那就是通过全文索引软件,也就是我们常说的Search(搜索引擎)对数据进行全文索引,才能达到较为高效的数据检索效率。
同样,Search 软件的使用也有使用较为成熟的第三方解决方案与自行研发两种方式。
目前最为有名的第三方解决方案主要就是基于 Java 实现的 Lucene,隶属于 Apache 软件基金 Jakarta 项目组下面的一个子项目。当然,他并不是一个完整的搜索引擎工具,而是一个全文检索引擎的框架,他同时提供了完整的用于检索的查询引擎和数据索引引擎。
这里我就不深入讨论 Lucene 本身的技术细节了,感兴趣的读者朋友可以通过访问官方站点(http://lucene.apache.org) 来了解更多也更为权威的细节。我这里主要是介绍一下 Luence 能够给我们带来什么,我们可以怎样来使用他。
由于 Lucene 高效的全文索引和分词算法,以及高效的数据检索实现,我们完全可以很好的利用这一优点来解决数据库和传统的 Cache 软件完全无法解决的全文模糊搜索功能。
我们的需求和传统的通用全网搜索引擎并不一样,并不需要“Spider”到处去爬取互联网上面的数据,只需要将我们数据库中被持久化下来的数据通过应用程序调用 Lucene 的相关API 写入,并利用 Lucene 创建好索引,然后就可以通过调用 Lucene 所提供的数据检索API 得到需要访问的数据,而且可以进行全模糊匹配。由于从数据库到 Lucene 这一过程完全由我们自己来实现,所以我们非常容易控制数据的实时性。可以做到完全实时,同样也可以做到固定(或动态)时间段刷新。
虽然 Lucene 的数据也是存放在磁盘上而不是内存中,但是由于高效的分词算法和索引结构,其效率也是非常的好。看到很多网友在网上讨论,当数据量稍微大一些如几十个 G 之后 Lucene 的效率会下降的非常快,其实这是不科学的说法,就从我亲眼所见的场景中, 就有好几百G的数据在 Lucene 中,性能仍然很出色。这几年性能优化的工作经历及经验中我有一个很深的体会,那就是一个软件性能的好坏,实际上并不仅仅只由其本身所决定,很多时候一个非常高效的软件不同的人使用会有截然不同效果。所以,很多时候当我们使用的第三方软件性能出现问题的时候,不要急着下结论认为是这个软件的问题,更多的是先从自身找找看我们是否真的正确使用了他。
除了使用第三方的 Search 软件如 Lucene 之外,我们也可以自行研发更适用于我们自身应用场景的 Search 软件。就像我目前所供职的公司一样,自行研发了一套纯内存存储的更适合于自身应用场景的高性能分布式 Search 软件,让各个应用系统能够作出很多高效的更为个性化的特色功能。通过多年的技术和经验的积累,现在都已经发展成为和数据库并列的另一个应用系统数据源了。
当然,自行研发 Search 软件的技术门槛可能也比较高,有此技术实力的开发团队并不是很多,所以在决定自行研发之前,一定要做好各方面的评估。不过,如果我们无法实现一个很通用的 Search 软件,但是仅仅只是针对某些特定功能来说,可能实现也并没有想象的那么复杂,更何况如今的开源世界里各种各样的软件数不胜数,利用现有的工具,加上自身个性化定制的二次开发,对于有些特定功能的实现可能就会比较轻松了。
加入了 Search 软件来实现高效的全文检索功能之后,我们的架构可以通过如下这张图
MySQL性能调优与架构设计——第 15 章 可扩展性设计之Cache与Search的利用
来展示:

15.5 利用分布式并行计算实现大数据量的高性能运算

说到大规模大数据量的高性能运算的时候,可能很多人都会想到最近风靡整个 IT 界的一个关键词:云计算,亦或是几年前的“网格计算”。
曾经有朋友建议我将本节标题中的“分布式并行计算”更改为“云计算”,考虑再三之后还是没有更改。说实话,从我个人的理解,不论是“云计算”还是“网格计算”,其实其实质都是一样,都是“分布式并行计算”,只不过是各个商业公司为了吸引大家的眼球所玩的一些“概念游戏”而已,个人认为纯属商业行为。当然,可能有人会认为从“分布式并行计算”到“网格计算”再到“云计算”,每一次“升级”都是在可以利用的计算资源上面有所扩展。可这种扩展都是在概念上面的扩展,而真正技术实现方面所依靠的并不是这些概念,而是各种软硬件的发展。更何况,最初的“分布式并行计算”概念中本就没有限定我们只能以哪种方式使用哪些资源。
目前比较流行的分布式并行计算框架主要就是以 Google 的 MapReduce 和 Yahoo 的 Hadoop 二者。其实更为准确的说应该是 Google的 MapReduce + GFS + BigTable 以及 Yahoo 的 Hadoop + HDFS + HBase 这两大架构体系。二者都是由三个负责不同功能的组件组成,MapReduce 与 Hadoop 同为解决认任务分解与合并的功能,GFS 与 HDFS 都是分布式文件系统,解决数据存储的基础设施问题,最后 BigTable 与 HBase 则同为处理结构化数据存储格式的类数据库模块。三大模块共同协作,最终组成一个分布式并行计算的框架体系整体。
其实这分属于两家互联网巨头的分布式并行计算架构框架体系的实现原理基本上可以说是完全一样的。通过前面端的任务分解合并引擎将计算(或者数据存取)任务分解成多个任务,同时发送给多台计算(或数据)节点来进行计算,而后面的每一个节点利用分布式文件系统来作为存储计算数据的基础平台,当然,不论是计算前还是计算后的数据,都是通过BigTable 或者是 Hbase 这样的模块进行组织。三者组成一个完整的整体,相互依赖。当然, 不得不说的是 Hadoop 本身也是由 Google 最初的一篇关于 MapReduce 的论文原理为思想所开发出来的。只不过 Google 在 Open 思想方面所做的贡献很多时候仅限于论文形式,对于其自身技术架构方面的信息公开的实在是有些少。
其实除了这两个重量级的分布式计算框架之外,完全利用现有开源数据库实现的完整解决方案也有一些,如 Inforbright 与 MySQL 合作实现的 BI 解决方案,Greenplum 公司与Sun 利用 PostGresql 开源数据库实现的 Greenplum 系统,而且两个系统都是依赖MapReduce 理论所实现。
虽然这两个系统目前并没有前面两个分布式计算框架那样大的伸缩性,但是所针对的场景是实实在在的 DB 场景,数据访问接口完全实现了 SQL 规范。对于使用习惯了通过 SQL 语句来玩数据库的分析方法来说,无疑是非常有诱惑力的,更何况这两个系统基本上都不怎么需要开发,已经是一个完整的产品了。
考虑到篇幅以及非本书重点所在,这里就不深入讨论相关的技术细节了,大家如果对这些内容比较感兴趣,可以通过各自官方网站了解更多更为全面的信息。

15.6 小结

数据库只是存储数据的一种工具,其特殊性只是能将数据持久化,且提供统一规范的访问接口而已。除了数据库,其实我们还可以很多其他的数据存储处理方式,结合各种数据存储处理方式,充分发挥各自的特性,扬长避短,形成一个综合的数据中心,这样才能让系统的数据处理系统的扩展性得到最大的提升,性能得到最优化。

摘自:《MySQL性能调优与架构设计》简朝阳

转载请注明出处:

作者:JesseLZJ
出处:http://jesselzj.cnblogs.com

上一篇:MySQL性能调优与架构设计——第 14 章 可扩展性设计之数据切分


下一篇:HTML入门全解