编写可扩展、分布式的数据密集型程序的基础知识

为什么数据量很大?

在当今社会,我们正在被数据包围,人们上传视频、用手机照相、发短信给朋友、更新Facebook、网上留言以及点击广告等,都产生大量的数据。重要的是,服务提供者不能不这些数据随便的删除,如何存储这些数据就成为了难题。


数据以指数级的增长!~也就是U的右半边

数据的增长首先对像谷歌、雅虎、亚马逊、微软、Facebook、腾讯、百度、阿里等等公司提出了挑战。如何存储、如何分析,他咩的。

 

存储这些数据是有必要的,但是干嘛要进行分析呢?

你可能有这样的需求,遍历所有的数据发现哪些网站更受欢迎,哪些书籍有需求,哪种广告吸引人。如果知道了以上这些,对公司的商业发展会有很大帮助,会产生很多利润。但是数据的量级却是TB或者PB级别(1TB=1024GB、 1PB=1024TB),你需要在这么大的数据上进行遍历。

 

他们怎么做了?

谷歌率先推出了MapReduce计算模型,针对自己公司的业务需求。

Doug Cutting看到机会,参考Google的论文,领导开发了一个开源版本的MapReduce,称为Hadoop

雅虎等公司纷纷响应,为其提供支持。

现在Hadoop已经成为许多互联网公司的基础计算平台的一个核心部分,如雅虎、Facebook、LinkedIn和Twitter。

许多传统行业、传媒业和电信业也开始采用这个系统,如《纽约时报》、中国移动和IBM等公司

 

作为程序员我感觉鸭梨好大呀!~

Hadoop及大规模分布式数据处理,正在迅速成为许多程序员的一项重要技能,传统的关系数据库、网络和安全也需要掌握,作为一个高效的程序员的必修课。

斯坦福和卡内基-梅隆等一流的大学已经开始将Hadoop引入他们的计算机科学课程。


什么是Hadoop

Hadoop是一个开源框架,可编写和运行分布式应用处理大规模数据。

 

Hadoop与众不同之处是?

方便:一般商用机器构成的大型集群或者其他云计算服务,俗称:一群屌丝顶个高富帅

健壮:容错机制,因为是一般的商用机器,所以硬件故障不能保证。Hadoop认为一台主机故障是常态,但不会影响集群的运行。

可扩展:通过增加集群的节点,可以线性的扩展以处理更大的数据集。

简单:Hadoop允许用户快速、高效的编写出并行代码,而不需要关注具体并行的实现,只要按她的模式走即可。

亚马逊的弹性计算云(EC2)等云计算服务是啥?


Hadoop集群是什么?

同一地点用网络互联的一组通用机器,因为有很多机器,所以也称为"机器云" "云"

另外:通常在一个Hadoop集群中的机器都是相对同构的X86 Linux服务器,而且它们集合总是位于同一个数据中心,并通常在同一组机架里。


什么是机架?

载计算机的架子,一个机架里面有很多计算机。


什么是摩尔定律?

摩尔定律是由英特尔(Intel)创始人之一戈登·摩尔(Gordon Moore)提出来的。其内容为:当价格不变时,集成电路上可容纳的晶体管数目,约每隔18个月便会增加一倍,性能也将提升一倍。换言之,每一美元所能买到的电脑性能,将每隔18个月翻一倍以上。

 

摩尔定律说明硬件性能的提升,就可以解决大规模计算的问题吗?

当然可以,但不能全靠超级计算机,因为这种难度会很大,古代的中国人在使用牛拉木头的时候,会使用多个牛来拉木头,而不是培养出更强壮的牛。

有一种替代方案已经获得普及,即把许多低端、商用的机器组织在一起,形成一个功能专一的分布式系统。


分布式系统(俗称向外扩展)与大型单机服务器(俗称向上扩展)之间的对比?

一台拥有4个I/O通道的高端机,即使每个通道的吞吐量各位100MB/s,读取4TB数据也需要3个小时。

利用Hadoop,同样的数据集会被划分为较小的块 (通常64MB),通过Hadoop分布式文件系统(HDFS)分布在集群内多台机器上。集群可以并行读取数据,进而提供很高的吞吐量。

而这样一组通用机器比一台高端服务器更加便宜。


SETI@home 是什么?

SETI@home 是一项利用全球联网的计算机共同搜索外星生命的科学实践计划。

在世界各地计算机屏保的时候协助寻找外星生命,这样不会影响用户的使用。

在SETI@home ,一台中央服务器存储来自太空的无线电信号,并在上网发布给世界各地的客户端台式机去寻找异常的迹象。经过客户端的计算后,再将返回的数据结果存储起来。


什么是CPU bound(计算密集型)?

CPU bound与I/O密集型相反

 

什么是I/O bound(I/O密集型)?

I/O bound指的是系统的CPU效能相对硬盘/内存的效能要好很多,此时,大部分的状况是CPU在等待I/O的读写

 

Hadoop与其他分布式系统架构进行比较?

SETI@home 需要客户端和服务器之间重复传输数据,但由于数据规模太大,数据迁移变得十分困难。

Hadoop是代码向数据迁移的理念,Hadoop集群内部既包含数据又包含计算环境,客户端仅需要发送待执行的MapReduce程序,而这些程序一般很小。并且,数据被拆分后再集群中分布,并且尽可能让一段数据的计算发生在同一台机器上。


代码向数据迁移的优势?

让数据不动(数据很大),让代码移动到数据所在的机器上。

 

传统SQL数据库与Hadoop比较一下?

关于设计理念

SQL(结构化查询语言)是针对结构化数据设计的。

Hadoop是针对文本这种非结构化数据设计的。

这样看来Hadoop提供了一种更为通用的模式。

更加详细的比较:

1、用向外扩张代替向上扩展

扩展商用关系型数据库的代价非常昂贵,性能4倍于标准的PC的机器,成本将大大超过同样的4台PC放在一个集群中。一个Hadoop集群的标配是十至数百台计算机。

2、用键/值对代替关系表

关系型数据库的一个基本原则是按某种模式存放具有关系型数据结构的表中,但是不能很好的适合文本、图片、和XML文件等数据类型。

大型数据集往往是非结构化或半结构化的,在Hadoop中数据的来源可以是任何形式,但最终会转化为键/值对。

3、用函数式编程(MapReduce)代替声明式查询(SQL

SQL使用查询语句,声明想要查询的结果,让数据库引擎判定如何获取数据。

MapReduce使用脚本和代码,比SQL查询更为一般化的数据处理方式,例如,你可以建立复杂的数据统计模型,或者改变图像数据的格式。而SQL就不能很好的适应这些任务。

4、用离线批量处理代替在线处理

Hadoop是专为离线处理和大规模数据分析而设计的,它并不适合那种对几个记录随机读写的在线事务处理模式。

Hadoop最适合一次写入,多次读取的数据存储需求,在这方面它就像SQL的数据仓库。

 

什么是管道数据处理模型,什么是消息队列数据处理模型?


什么是MapReduce数据处理模型?

这种模型最大的优点是容易扩展到多个计算节点上处理数据。在MapReduce模型中,数据的处理原语被称为mapper和reducer


练习,统计一组文档中的每个单词出现的次数?

考虑这样一种场景:一个文件,文件里只有一句话 Do as I say, not as do. ,统计单词出现的次数。

define wordCount as Multiset;
for each document in documentSet {
       T = tokenize (document);
       for each token in T {
              wordCount[token]++;
       }
}

display(wordCount);

单词

计数

as

2

Do

2

i

1

not

1

say

1

改程序循环遍历所有文档。对于每个文档,使用分词过程逐个地提取单词。对于每个单词,在多重集合wordCount中的相应项上加1.最后display()函数打印出wordCount中的所有条目。

这个程序只适合少量的文档,使用单台计算机反复遍历所有文档将会非常费时。

 

那么,如何解决该问题?

可以让工作分布到多台机器上,每台机器处理这些文档的不同部分,当所有的机器都完成时,将合并这些结果。

第一阶段分布到多台机器:

// 伪代码
define wordCount as Multiset;
for each document in documentSet {
       T = tokenize (document);
       for each token in T {
              wordCount[token]++;
       }
}
sendToSecondPhase(wordCount);
第二阶段合并这些结果
// 伪代码
for each wordCount received from firstPhase {
       multisetAdd (totalWordCount, wordCount);
}

上边的代码不是很难对么?但是忽略了一些细节。

缺陷1:我们忽略了文档读取的性能要求,如果文件存在一个中央存储服务器上,那么瓶颈就是该服务器的带宽。因此,你需要将文档分开存放,使每台机器可以仅处理自己所存储的文档。(这也呼应了数据密集型分布式应用中存储和处理不得不紧密地绑定在一起)

缺陷2:忽略了wordCount被存储在内存中,当处理大型文档集时,一个特定单词的数量就会超过一台机器的内存。所以我们不得不改写程序,以便在磁盘上存储该散列表。这意味着我们将实现一个基于磁盘的散列表,其中设计大量的编码。

缺陷3: 第二阶段只有一台计算机,它将处理来自所有计算机在第一个阶段计算的wordCount的结果。wordCount的处理任务原本就相当繁重,第二阶段的单台计算机将成为瓶颈。

 

那么,针对以上缺陷将如何应对?

解决缺陷3,我们能否按分布模式重写第二阶段,以便它可以通过增加更多的计算机来实现扩展?

需要在第一阶段之后将wordCount分区,使得第二阶段的每台计算机仅需处理一个分区。

举个例子,假设我们在第二阶段有26台计算机。我们让每台计算机上的wordCount只处理以特定字母开头的单词。例如,计算机A在第二阶段统计以字母a开头的单词。为了在第二阶段中实现这种划分,我们需要对第一阶段稍微修改。不再采用基于磁盘的散列表实现wordCount,而是划分出26个表:wordCount-a、wordCount-b等。每个表统计以特定字母开头的单词。经过第一阶段,来自该阶段所有计算机的wordCount-a结果将被发送到第二阶段的计算机A上,所有wordCount-b的结果将被发送到计算机B上,依次类推。第一阶段中的每台计算机都会将结果洗牌到第二阶段计算机上。

 

现在单词统计程序正变得复杂,为了使它工作在一个分布式计算机集群上,我们发现需要添加以下功能:

存储文件到许多台计算机上 (第一阶段)

编写一个基于磁盘的散列表,使得处理不受内存容量限制

划分来自第一阶段的中间数据 (即wordCount)

洗牌这些分区到第二阶段中合适的计算机上


为什么使用Hadoop

即使对于单词统计这样简单的程序,这都是繁重的工作,而我们甚至还没有涉及容错的问题。

(如果在任务执行过程中一个计算机失效该怎么办?)这就是我们需要一个像Hadoop一样的框架。当你用MapReduce模型来写应用程序,Hadoop将替你管理所有与可扩展性相关的底层问题。