上个世纪,好远。。。九十年代后,开始,数据开始大量的产生,总之到了快没法弄的程度了。
比如说之前90年代,一个1G的硬盘,传输速度4.4M每秒,读取全盘大概需要5分钟。
现在呢,一个1T的硬盘,传输速度100M每秒,横扫全盘2个半小时,读取全部数据的话。。。。。不知道多长时间。
简单几句带过,也就是说,数据太多了,我们该如何解决快速读取的问题。
那么就提出了分布式。
也就是说,我们用一头牛去拉不动火车,就没必要培养一头又大又壮能拉动火车的牛,只需要多弄些牛就可以了,小孩子都懂。
这样呢,问题就出现了,如何分配合控制这么多牛,就是我们的着手要解决的问题了。那么这个道理就是分布式,一个简单的减少读取数据时间的方法,就是同时从多块硬盘上读取。
如果我们有100块硬盘,每个存储所有数据的1%,然后并行读取,那么几分钟就能操作完成。但是只使用硬盘容量的1%的话,就太浪费资源了。这样,我们可以将数据分为100个数据集,每个数据集1T,并实现共享磁盘的访问。
可以想像,这样便可以大量缩短数据分析的时间。有点像再说P2P下载哈。但是象我刚才说到的,处理多个硬盘数据的并行操作,还有很多问题。
一般来说呢,第一,是如何解决硬盘故障问题,硬盘越多,故障概率越高。
现在解决的方式就是建立副本。比如RAID方式,冗余磁盘阵列。或者在Hadoop中所采用的HDFS,也是一种方式,只是方法不同。
第二个问题,数据分开存储到100块硬盘上,那么,我们使用的时候而必须要合并使用。
在Hadoop中采用MapReduce来提供这个问题的解决方法。
MapReduce和HDFS是Hadoop中的两个重要部分,MapReduce提供了一个编程模型,将磁盘读写问题进行抽象。我们可以理解HDFS像是数据库,而MapReduce那么像是SQL语句和引擎一样运作。
MapReduce将数据抽象成并演变成为对一个数据集(key/value对组成的集合)的计算。这个计算是由map和reduce两部分所完成的,也就是将数据抽象成为map和reduce两个对外的接口。
那么,简而言之,Hadoop能做到提供一个稳定可靠的共享存储和分析系统。
其中,
HDFS实现存储
MapReduce实现分析处理
当然Hadoop还有其他功能,但是这两部分是我们所需要知道的,最重要的。
Hadoop和其他系统的比较
关于MapReduce的每个查询基本上都需要处理整个map(整个数据集)或者至少要用到数据集的一大部分数据。
MapReduce是一个批量查询处理器,它能够在合理的时间范围内处理针对整个数据集的即时查询(Ad hoc)。
注:Ad hoc 查询(即席查询)是信息学的一个术语。是拉丁语常用短语,意思是“特设的、特定目的的(地)、即席的、临时的”
优点:解放了以前存储在磁盘上的数据。能在短时间内处理以前很长时间才能获得的结果。
事例:使用Hadoop处理用户日志。即席查询找出用户的地理分布。通过整合大量数据,并使用MapReduce分析,
可以了解到我们以前不曾留意的数据,运用这些数据可以改善我们现有的服务。
那么,我们需要解释一下,为什么上面的事情一样可以用关系型数据库来做到批量分析,而要用MapReduce。简单的从存储数据开始说起,硬盘是我们存储数据的主要介质,这里面就出现个问题:
首先,硬盘读取数据之前需要寻址,寻找到分散在硬盘上的各个地址上的数据,那么这里产生两个时间问题,
第一是硬盘的寻址时间,第二是硬盘数据的传输时间。
寻址操作需要磁头在硬盘上不断移动而在指定的位置进行读写。随着硬盘技术的发展,寻址时间的提高远远落后于数据传输速率的进步。这导致磁盘大量的寻址操作成为数据存储的瓶颈,而数据传输速率取决于硬盘总线的带宽。
对大量数据进行访问中,包含由大量的磁盘寻址工作,那么读取大量数据集就会花更长的时间。
和关系型数据库比较
那么HDFS和传统的RDBMS各有什么优缺点呢?
HDFS采用的是流式数据读取模式,而流式数据读取模式主要取决于数据的传输速率。RDBMS呢?采用的传统的B树,RDBMS中使用的B树结构,受限制于寻址的比例。
一般来说,对于大数据量的读取流式模式的效率要远远高于B树。但是当,只更新一小部分数据的话,那么传统的B树更有优势。
因为在大数据量更新时,B树需要使用sort/merge(排序/合并)来重建数据库。也就是说,可以将MapReduce看作RDBMS的一个补充。
MapReduce适合以批处理的方式处理需要分析的整个数据集。它适合一次性写入,多次的读取的应用。
RDBMS适用于point query(点查询)和更新,数据集被建立索引后,数据库能够提供快速的数据检索和少量的数据更新。它更适合持续更新的数据集。
RDBMS
MapReduce
数据大小
GB
TB
访问
交互式和批处理
批处理
更新
多次读写
一次写入多次读取
结构
静态模式
动态模式
完整性
高
低
横向扩展
非线性
线性
MapReduce和RDBMS之间的另外一个区别在于他们所操作的数据集的结构化程度。
结构化数据(structured data)是具有既定格式的实体化数据,比如XML等满足特定格式要求的数据表,比如数据库表中的定义好的特定类型的字段。
半结构化数据(semi-structured data)属于比较松散,虽然可能有格式,单常常被视而不见,所以它只能用作数据结构的一般说明。比如,单元格组成的网格中,每个单元都可以保存任何形式的数据。
非结构化数据(unstructured data)没有特定的结构。比如,文本文件,图片,视频。
MapReduce对于非结构化或半结构化数据的读取是非常有效的,这时因为MapReduce只有在读取数据时才对数据进行解释。也就是说,MapReduce输入的key和value并不是固定的属性,而是又分析数据的用户来指定的,就像object map。
而,RDBMS的数据往往是规范的(normalized),以能够保持其数据的完整性且不含冗余。但是这种规范的数据却给MapReduce的读取带来了麻烦,因为它使用异地操作进行记录的读取工作,并且,MapReduce的核心价值之一,就是可以进行高速流式读写操作。
例如:web server上的日志就是一个典型的非结构化非规范化的数据记录,大家都知道,所以MapReduce非常适合分析各种咋样的日志,比如用户登陆日志。MapReduce是一种线性可伸缩的编程模式。
程序猿可以编写两个方法,分别为map和reduce,每个方法定义一个[key/value对集合]到另一个[key/value对集合]的映射。而这些方法并不需要关心数据集及其所用集群的大小,因此可以原封不动地应用到[小规模的数据集]或是 [大规模的数据集]。
注:就是说方法写好后,数据大小无需考虑,方法都是一样的。
另外一点,如果输入的数据量是原来的两倍,那么运行的时间也是原来的两倍,但是,如果把集群的大小扩大到原来的两倍,那么运行的时间就和原来一样了。这个特性比RDBMS好哈,都懂哈!不过现在很多RDBMS开始向着这方面发展,而,MapReduce也开始具有了数据库的一些特性。凌乱了~!
Hadoop与其他传统工作方式的比较
这里大概可以粗略讲到网格计算。
High Performance Computing(HPC高性能计算)和Grid Computing(网格计算)的组织,多年来一直在研究大数据处理方法。一般主要采用类似于消息传递接口MPI(Message Passing Interface)的API。
HPC的方法是将任务分散到集群中的各台计算机上,这些计算机访问由存储区域网络(Storage Area Network,SAN)组成的共享文件系统。
注:储区域网络(Storage Area Network,SAN)是一种连接外接存储设备和服务器的架构。包括磁盘阵列,磁带柜等各种技术实现。该架构的特点是,连接到服务器的存储设备,将被操作系统视为直接连接的存储设备进行使用。
MapReduce实现计算节点数据本地化。
这种组成比较适用于计算密集型任务,但是如果节点需要使用更大量的数据进行计算时,那么很多计算节点(也就是网格中计算单元)会由于网络带宽的瓶颈而变的空闲,且,一直等待数据的到来,这时候MapReduce就开始有用了。
MapReduce可以尽量把计算节点上存储数据,以实现数据的本地快速访问。而数据本地化(data locality)也正是MapReduce的一个核心特性。
当我们现在意识到网络带宽是我们系统架构中最宝贵的资源的时候,MapReduce则通过显式网络拓扑结构来尽量保留带宽资源并且显式网络拓扑结构并没有降低MapReduce的计算密集型的数据分析能力。
MapReduce无需考虑底层数据控制。
消息传递接口MPI给了程序员很大的控制空间,需要程序员显式的控制数据流机制,包括底层的功能模块(soket通信接口)和上层的数据分析算法。
而MapReduce则在更高层次上去运行,也就是程序员只需要考虑如何操作数据集(key/value对)就可以了。
MapReduce无需考虑节点失效。
大规模分布式计算的问题在于,如何很好的协调各进程之间关系。如何在处理一个计算过程处理失效的问题中,在无法知道一个远程的进程是否已经失效的情况下,还要继续去完成整个计算。
而,MapReduce给我们的是,无需考虑系统的部分失效的问题,因为MapReduce的系统实现能够检测到失败的map或者reduce任务,并让某个其他节点正常的机器来重新执行这些失败的任务。
MapReduce采用无共享(shared-nothing)框架来实现失败检测,这样需要在各任务之间彼此独立运行。这样,程序员就无需考虑各任务的执行顺序,至少是无关紧要的事情。
相比之下MPI虽然控制权比较大,但是也同样加大了编程难度。(If there is great power comes great responsibility)
那么,MapReduce是个相当严格的模型,用户被限定于使用操作特定的数据集(key/value对)。相对应的mapper和reducer彼此之间可以做的协调是极其有限度的,仅仅是传递key/value对。
MapReduce适合于普通的分析和计算么?
其实,MapReduce是用于构建搜索引擎的索引,并且能够非常好的完成。许多算法可以使用MapReduce来表达,从图形图像分析到各类机遇图像的分析,再到机器学习,都可以。MapReduce是由Google的工程师开发的,灵感来自于传统的函数式编程,分布式计算和数据库社区。
它的优秀,能够完成我们的大部分需求。
和志愿计算的比较
志愿计算呢,就是很多志愿者将自己的计算机空闲出来的CPU时间志愿贡献出来,用来协助计算一些大型的计算事务。
比较有名的项目:
加利福尼亚大学的SETI@home,
全称:Search for Extra-Terrestrial Intelligence(搜索外星智慧)项目。
志愿者把自己计算机的CPU空闲时间贡献出来分析无线天文射电望远镜的返回数据,借此寻找外星智慧生命信号。
可以通过 http://setiathome.berkeley.edu/ 注册参加,或者式了解这个项目。
其他还有很多类似的项目,可以下载BOINCManager来参加这些项目为人类作出些贡献。
这里用到志愿计算,志愿计算项目就是将需要解决的问题分成多个块,每个块被称为一个工作单元或者(work unit)或者任务(task)。并将他们发到世界各地的电脑上进行分析。
完成分析后,将数据发回到服务器合并,客户端回获得另外一个工作单元。为了防止欺骗星文,每个工作单元被分配到三个不同的机器上进行执行,并且至少收到两个相同的结果才被接受。
这里看来志愿计算和MapReduce看上去很相似,都是将问题分为独立的单元,然后进行并行计算。但,还是由很大的差异。
志愿计算问题是CPU高度密集的,比较适合世界上成千上万的计算机上运行,因为计算时间远远大于传输数据的时间。而,志愿者贡献的是CPU周期,而不是网络带宽。
MapReduce的设计目标在于服务于那些只需要数分钟或者几小时就可以完成的即时任务,并运行于内部通过高速网络相互连接的网络内,并且这个网络内的计算机需要由可靠的,定制的硬件构成。此外,志愿计算需要在接入护两旺的不可信的计算机上长时间运行,这些计算机具有不同的带宽,且对数据本地化没有太多要求。