前言
前面章节部分所分析的可扩展架构方案,基本上都是围绕在数据库自身来进行的,这样是否会使我们在寻求扩展性之路的思维受到“禁锢”,无法更为宽广的发散开来。这一章,我们就将跳出完全依靠数据库自身来改善扩展性的问题,将数据服务扩展性的改善向数据库之外的天地延伸!
可扩展设计的数据库之外延伸
数据库主要就是为应用程序提供数据存取相应的服务,提高数据库的扩展性,也是为了更好的提供数据存取服务能力,同时包括可靠性,高效性以及易用性。所以,我们最根本的目的就是让数据层的存储服务能力得到更好的扩展性,让我们的投入尽可能的与产出成正比。
我们都明白一点,数据本身肯定都会需要有一个可以持久化地方,但是我们是否有必要让我们的所有冗余数据都进行持久化呢?我想读者朋友们肯定都会觉得没有这个必要,只要保证有至少两份冗余的数据进行持久化就足够了。而另外一些为了提高扩展性而产生的冗余数据,我们完全可以通过一些特别的技术来替代需要持久化的数据库,如内存Cache,Search以及磁盘文件Cache和Search等等。
寻求数据库软件本身之外的Cache和Search来解决数据本身的扩展性,已经成为目前各个大型互联网站点都在积极尝试的一个非常重要的架构升级。因为这不仅仅能更大程度的在整个应用系统提升数据处理层本身的扩展性,而且还能更大限度的提升性能。
对于这种架构方式,目前已经比较成熟的解决方案主要有基于对象的分布式内存Cache解决方案Memcached,高性能嵌入式数据库编程库BerkeleyDB,功能强大的全文搜索引擎Lucene等等。
当然,在使用成熟的第三方产品的同时,偶尔自行实现一些特定应用场景下的Cache和Search,也未尝不是一件值得尝试的事情,而且对于公司的技术积累来说也是很有意义的一件事情。当然,决定自行开发实现之前进行全面的评估是绝对必要的,不仅仅包括自身技术实力,对应用的商业需求也需要有一定的评估才行。
其实,不论是使用现成的第三方成熟解决方案还是自主研发,都是需要在开发资源方面有一定投入的。首先要想很好的和现有MySQL数据库更好的结合,就有多种思路存在。可以在数据库端实现和Cache或者Search的数据通讯(数据更新),也可以在应用程序端直接实现Cache与Search的数据更新。数据库和Cache与Search可以处于整体架构中不同的层次,也可以并存于相同的层次。
下面我分别针对使用第三方成熟解决方案以及自主研发来进行一些针对性的分析和架构思路探讨,希望对各位读者朋友有一定的帮助。
合理利用第三方Cache软件
使用较为成熟的第三方解决方案最大的优势就在于在节省自身研发成本的同时,还能够在互联网上面找到较多的文档信息,帮助我们解决一些日常遇到的问题还是非常有帮助的。
目前比较流行的第三方Cache解决方案主要有基于对象的分布式内存Cache软件Memcached和嵌入式数据库编程库BerkeleyDB这两种。下面我将分别针对这两种解决方案做一个分析和架构探讨。分布式内存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服务层的时候的架构简图。
从图中我们可以看到,所有数据都会写入MySQLMaster中,包括数据第一次写入时候的INSERT,同时也包括对已有数据的UPDATE和DELETE。不过,如果是对已经存在的数据,则需要在UPDATE或者DELETEMySQL中数据的同时,删除Memcached中的数据,以此保证整体数据的一致性。而所有的读请求首先会发往Memcached中,如果读取到数据则直接返回,如果没有读取到数据,则再到MySQLSlaves中读取数据,并将读取得到的数据写入到Memcached中进行Cache。
这种使用方式一般来说比较适用于需要缓存对象类型少,而需要缓存的数据量又比较大的环境,是一个快速有效的完全针对性能问题的解决方案。由于这种架构方式和MySQL数据库本身并没有太大关系,所以这里就不涉及太多的技术细节了。
2.和MySQL整合为数据服务层
除了将Memcached用作快速提升效率的工具之外,我们其实还可以将之利用到提高数据服务层的扩展性方面,和我们的数据库整合成一个整体,或者作为数据库的一个缓冲。
我们首先看看如何将Memcached和MySQL数据库整合成一个整体来对外提供服务吧。一般来说,我们有两种方式将Memcached和MySQL数据库整合成一个整体来对外提供数据服务。一种是直接利用Memcached的内存容量作为MySQL数据库的二级缓存,提升MySQLServer的缓存大小,另一种是通过MySQL的UDF来和Memcached进行数据通信,维护和更新Memcached中的数据,而应用端则直接通过Memcached来读取数据。
对于第一种方式,主要用于业务要求非常特殊,实在难以进行数据切分,而且有很难通过对应用程序进行改造利用上数据库之外的Cache的场景。
当然,在正常情况下是肯定无法做到这一点的,之少目前必须借助外界的力量,开源项目WaffleGrid就是我们需要借助的外部力量。
WaffleGrid是国外的几位DBA在工作之余突发奇想出来的一个点子:既然PCServer的低廉成本如此的吸引我们,而其ScaleUp的能力又很难有一个较大的突破,何不利用上现在非常流行的Memcached作为突破单台PCServer的内存上限呢?就在这个想法的推动下,几位小伙子启动了WaffleGrid这个开源项目,利用MySQL和Memcached双双开源的特性,结合Memcached通信协议简单的特点,将Memcached成功实现成为MySQL主机的外部“二级缓存”,目前仅支持用于Innodb的BufferPool。
WaffleGrid的实现原理其实并不复杂,他所做的事情就是当Innodb在本地的BufferPool(我们姑且称其为LocalBufferPool吧)的时候,在从磁盘数据文件读取数据之前,先通过Memcached的通信API接口尝试从Memcached中读取相应的缓存数据(我们称之为RemoteBuffer吧),只有在RemoteBuffer中也不存在需要的数据的时候,Innodb才会访问磁盘文件来读取数据。而且,只有处于InnodbBufferpool中的LRUList中的数据会被发送到RemoteBufferPool中,而这些数据一旦被修改,就会Innodb就会将之移入FLUSHList,WaffleGrid同时会将进入FLUSHList的数据从RemoteBufferPool中清除掉。所以可以说,RemoteBufferPool中永远不会存在DirtyPages,这也保证了当RemoteBufferPool出现故障的时候不会产生数据丢失的问题。
下图是使用WaffleGrid项目时候的架构简图:
如架构图上所示,我们首先在MySQL数据库端应用WaffleGridPatch,通过他连与其他的Memcached服务器通信。为了保证网络通信的性能,MySQL与Memcached之间尽可能用高带宽私有网络。
另外,这里的架构图中并没有再将数据库区分Master和Slave了,并不是说一定不能区分,只是一个示意图。在实际应用过程中,大部分时候只需要在Slave上面应用WaffleGrid即可,Master本身并不需要如此大的内存。
看了WaffleGrid的实现原理,可能有些读者朋友会有些疑问了。这样做不是所有需要产生物理读的Query的性能就会受到直接影响了吗?所有读取RemoteBuffer的操作都需要通过网络来获取,其性能是否足够高呢?对此,我同样使用作者对Waffle的实测数据来接触大家的疑虑:
通过DBT2所得到的这组测试对比数据,在性能我想并不需要太多的担忧了吧。至于WaffleGrid是否适合您的应用场景,那就只能依靠各位读者朋友自己进行评估了。
下面我们再来介绍一下Memcached和MySQL的另外一种整合方式,也就是通过MySQL所提供的UDF功能,自行编写相应的程序来实现MySQL与Memcached的数据通信更新操作。
这种方式和WaffleGrid不一样的是Memcached中的数据并不完全由MySQL来控制维护,而是由应用程序和MySQL一起来维护数据。每次应用程序从Memcached读取数据的时候,如果发现找不到自己需要的数据,则再转为从数据库中读取数据,然后将读取到的数据写入Memcached中。而MySQL则控制Memcached中数据的失效清理工作,每次数据库中有数据被更新或者被删除的时候,MySQL则通过用户自行编写的UDF来调用Memcached的API来通知Memcached某些数据已经失效并删除该数据。
基于上面的实现原理,我们可以设计出如下这样的一个数据服务层架构:
如图中所示,此架构和上面将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语句一样通过某一个(或者多个)关键字条件来读取包含多条数据的结果集,仅适用于通过某个唯一键来获取单条数据的数据读取方式。
嵌入式数据库编程库Berkeley Berkeley
说实话,数据库编程库这个叫法实在有些别扭,但我也实在找不到其他合适的名词来称呼BerkeleyDB了,那就姑且使用网上较为通用的叫法吧。
Memcached所实现的是内存式Cache,如果我们对性能的要求并没有如此之高,在预算方面也不是太充裕的话,我们还可以选择BerkeleyDB这样的数据库型Cache软件。
可能很多读者朋友又会产生疑惑了,我们使用的MySQL数据库,为什么还要再使用一个BerkeleyDB这样的“数据库”呢?
实际上BerkeleyDB在之前也是MySQL的存储引擎之一,只不过后期不知道是何原因(获取与商业竞争有关吧),被MySQL从支持的存储引擎中移除了。之所以在使用数据库的同时还使用BerkeleyDB这样的数据库型Cache,是因为我们可以充分发挥出二者各自的优势,在使用传统通用型数据库的同时,同时可以利用BerkeleyDB高效的键值对存储方式作为高效数据检索的性能补充,以得到更好的数据服务层扩展性和更高的整体性能。
Berkeley DB 自身架构可以分为五个功能模块,五个模块的在整个系统中相对比较独立,而且可以设置使用或者禁用某一个(或者几个)模块,所以可能称之为五个子系统会更为恰当一些。这五个子系统及基本介绍分别如下:
◆ 数据存取 数据存取子系统主要负责最主要也是最基本的数据存与取的工作。而且BerkeleyDB同时支持了以下四种数据的存储结果方式:Hash,B-Tree,FixedLength以及DynamicLength。实际上,这四种方式对应了四种数据文件存储的实际格式。数据存储子系统可以完全单独使用,也是必须开启的一个子系统。
◆ 事务管理 事务管理子系统主要是针对有事务要求的数据处理服务,提供完整的ACID事务属性。在开启事务管理子系统的时候,出了需要开启最基本的数据存取子系统外,还至少需要开启锁管理子系统和日志系统来帮助实现事务的一致性和完整性。
◆ 锁管理 锁管理系统主要就是为了保证数据的一致性而提供的共享数据控制功能。支持行级别和页级别的锁定机制,同时为事务管理子系统提供服务。
◆ 共享内存 共享内存子系统我想大家看到名称就应该基本知道是做什么事情的了,就是用来管理维护共享Cache和Buffer的,为系统提升性能而提供数据缓存服务。
◆ 日志系统
日志系统主要服务于事务管理系统,为保证事务的一致性,BerkeleyDB也采用先写日志再写数据的策略,一般也都是与事务管理系统同时使用同时关闭。
基于BerkeleyDB的特性,我们很难像使用Memcached那样将他和MySQL数据库结合的那么紧密。数据的维护与更新操作主要还是需要通过应用程序来完成。一般来说,在使用MySQL的同时还要使用BerkeleyDB的主要原因就是为了提升系统的性能及扩展性。所以,大多数时候都主要是使用Hash和B-Tree这两种结构的数据存储格式,尤其是Hash格式,是使用最为广泛的,因为这种方式也是存取效率最高的。
在应用程序中,每次数据请求,都先通过预先设定的Key到BerkeleyDB中取查找一次,如果存在数据,则返回取得的数据,如果未检索到数据,则再次到数据库中读取。然后将读取到的数据按照预先设定的Key,整条存入BerkeleyDB中,再返回给客户端。而当发生数据修改的时候,应用程序在修改MySQL中的数据之后必须还要将BerkeleyDB中的数据删除。当然,如果您愿意,也可以直接修改BerkeleyDB中的数据,但是这样就可能引入更多的数据一致性风险并提高系统复杂度了。
从原理来看,使用BerkeleyDB的方式和将Memcached作为纯Cache来使用差别不大嘛,为什么我们不用Memcached来做呢?其实主要有两个原因,一个是Memcached是使用纯内存来存放数据的,而BerkeleyDB则可以使用物理磁盘,两者在成本方面还是有较大差别的。另外一个原因就是BerkeleyDB所能支持的数据存储方式除了Memcached所使用的Hash存储格式之外,同时还可以使用其他存储格式,如B-Tree等。
由于和Memcached的基本使用原理区别不大,所以这里就不再画图示意了。
自行实现Cache 服务
实际上,除了使用比较成熟的现成第三方软件的解决方案之外,如果有一定的技术实力,我们还可以通过自行实现的Cache软件来达到完全相同的效果。
当然,您也不要被上面所说的“技术实力”所吓倒,其实也并没有想象中的那么难。只要您不要一开始就希望作出一个能够解决所有问题,而且包含所有其他第三方Cache软件的所有优点,还不能遗留任何缺点的软件,不要一开始就希望作出一个多么完美的产品花的软件。从小做起,从精做起。千万别希望一口气吃成一个胖子,这样的解决很可能就是被咽死。
自主研发实现Cache服务软件的前提是系统中存在比较特殊的应用场景,通过自主研发可以最大限度的实现比较个性化的需求。当然,也可以针对自己的应用场景进行特定的优化方式来最大限度的提升扩展性和性能。毕竟,只有我们自己才是真正最了解我们的应用系统的人。
决策是否需要自行开发最需要考虑的一个问题就是我的英勇系统场景是否真的如此特别,以至于现成的第三方软件很难解决目前的主要问题?
如果目前的第三方软件已经基本解决了我们系统当前遇到的80%以上的问题,可能就需要考虑是否有必要完全自主研发了。毕竟我们选择的所有第三方软件都是开源的,如果有某些小地方无法满足要求,我们完全可以在第三方软件的基础上增加一些我们自己的东西,来满足一些个性化需求。
当我们选择自主研发Cache服务软件之后,有以下几点内容是需要注意的:
1.功能需求
a)是完全内存还是可以部分磁盘?
b)需要实时同步更新还是可以允许Cache数据有延时?
c)是否需要支持分布式?
这里所说的功能,实际上就是需求范围的设定。在开始研发之前,我们比需要有一个非常清晰的需求范围,而不是天马行空的边开发边调整,想到啥做啥。毕竟任何软件系统,都是需要以第一线的需求为导向,而且一旦开始开发之后,需求的控制也不能马虎。要不然,很可能就会中途夭折,以失败而告终。
2.技术实现
a)数据同步(或异步)更新机制;
b)数据存储方式(HashOrB-Tree);
c)通讯协议;
技术实现可能会成为研发过程中很大的一个难点,能否有稳定可靠的数据同步(或异步)更新机制决定了该Cache软件最终的成败。当然,你可以说数据同步(或异步)更新完全交由需要访问数据的应用程序来自行维护,但是你是否有足够的能力申请在自行研发实现出一个Cache软件的同时,还需要前端应用程序作出巨大的调整来适应这个Cache软件是一个很大的未知数。老板很可能会说,既然你都自行研发实现了,为啥不能完成数据更新维护功能呢?而数据存储方式直接决定数据的访问方式,同时实现算法也直接决定了软件的性能。最后,数据传输的通讯协议可能也会让人伤透脑筋。如何设计一个足够简单,但是又做到尽可能不会限制后期的扩展升级的通讯协议,可能并不是一件太轻松的事情。毕竟,如果每次升级都需要动到数据传输通讯协议,那每次升级所带来的应用改造成本也太大了。而太过复杂呢,很可能又会影响到前端应用使用的便利性,而且对性能可能也会有一定影响。
3.可维护性
a)方便的管理接口;
b)高可用支持(自动或人工切换);
c)基本监控接口;
千万不要忽视了软件系统的维护成本,一个软件一旦开始使用之后,主要工作就是对其进行各种维护。如果可维护性太差,很可能带来极大的维护工作量,甚至带来一线应用人员和运维人员对该软件的信任和使用热情。
使用自行研发的Cache服务基于不同的功能特性,可能会有不同的架构组成,但基本上和上面使用Memcached所使用的架构区别不大了,所以这里也就不再详细讨论了。
最后,我个人有一个建议就是,在使用比较通用Cache服务(也包括自行实现的Cache软件服务)的时候,我们应该尽可能将该Cache软件与我们的MySQL数据库进行一定的整合,让彼此能够互补。而且前端的应用程序尽量不要直接操作后端的数据服务集群,尽量通过一个中间代理层来接受处理所有的数据处理服务,对前端应用透明化。这样才能够尽可能做到后端数据服务(数据库与Cache)层在进行任何扩展的时候,影响到的仅仅只是中间代理层,而对前端完全透明,让我们的数据层拥有真正的高扩展性。
利用Search实现高效全文检索
不论是使用Memcached还是使用BerkeleyDB,大多数时候都只能通过特定的方式来进行数据的检索,只能满足少部分的检索需求。而数据库本身对于全模糊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软件来实现高效的全文检索功能之后,我们的架构可以通过如下这张图来展示:
利用分布式并行计算实现大数据量的高性能运算
说到大规模大数据量的高性能运算的时候,可能很多人都会想到最近风靡整个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语句来玩数据库的分析方法来说,无疑是非常有诱惑力的,更何况这两个系统基本上都不怎么需要开发,已经是一个完整的产品了。
考虑到篇幅以及非本书重点所在,这里就不深入讨论相关的技术细节了,大家如果对这些内容比较感兴趣,可以通过各自官方网站了解更多更为全面的信息。
小结
数据库只是存储数据的一种工具,其特殊性只是能将数据持久化,且提供统一规范的访问接口而已。除了数据库,其实我们还可以很多其他的数据存储处理方式,结合各种数据存储处理方式,充分发挥各自的特性,扬长避短,形成一个综合的数据中心,这样才能让系统的数据处理系统的扩展性得到最大的提升,性能得到最优化。