Yahoo的Hadoop教程Word文档格式.docx
《Yahoo的Hadoop教程Word文档格式.docx》由会员分享,可在线阅读,更多相关《Yahoo的Hadoop教程Word文档格式.docx(32页珍藏版)》请在冰豆网上搜索。
3.
4.
适用的问题范围
大规模数据的挑战
摩尔定律
5.
Hadoop方法
与现有其它技术比较
数据分布
MapReduce:
隔离的进程(s)
水平的可扩展性(flatscability)
6.
教程的其它部分
适用问题范围
Hadoop是一个大规模分布式批处理架构,虽然它在单台计算机上也能使用,但它的真正能力是在成百上千计算机上运行时才显现出来,Hadoop可以高效地将大量工作高效地分布到一组计算机上。
它能处理多大量的工作?
Hadoop面对的处理工作比许多现在系统处理要高几个数量级,几百G的数据,只不过在Hadoop眼里不过是小数据量。
实际上Hadoop是设计来对付“We级的”的数据,“Web级”数据大小范围在几百G到T级,甚至P级。
在这种规模下,输入数据很可能甚至不能存入单个计算机的磁盘中,更不用说内在了,所以Hadoop中包括一个分布式文件系统,它将输入文件分成块,将这些块传输到你的集群中的计算机上保存,这样,原问题可以使用集群中所有计算机并行处理,那么得到计算结果的效率也就最高。
大规模的挑战
进行大规模计算是很困难的,要处理大规模数据需要将数据分布到多台机器上并行处理,第当多台机器之间需要协作时,失败的几率就很升高。
在单台机器环境中,失败并不是设计者经常关心的问题,因为机器崩溃了,反正是无法将程序恢复的。
但在分布式环境中,局部失败是经常会发生的,比如网络会因为交换机和路由器崩溃局部失败或全部失败;
数据有可能因为意外的网络阻塞没有按时到达特定结点;
运算结点可能因为过热导致磁盘崩溃或用完了内存或磁盘空间;
数据可能出错,也可能传输时发生错误;
不同实现或不同版本软件在使用协议时有细微的差别;
时钟可能变的不同步;
锁文件可能没释放;
可能在分布式不可打断的传输时受到干扰,导致网络连接中途断开,等等。
在上述每一种情况下,分布式系统的正常工作部分应该可以从失败中恢复,或使用户不需要关心这些错误,也可以继续正常工作。
显然,提供这种弹性是软件工程的巨大挑战。
不同的分布式系统会着重处理不同的几种失败,而不太关注另外的失败类型。
Hadoop没有提供安全模型,也没有防止恶意插入数据的安全机制,比如它无法控制一个在结点间的攻击,然而,它在硬件失败和数据阻塞方面的设计非常健壮,其它的分布式系统数据它们所要处理的问题(比如,高安全性)需求做出了不同的权衡。
在考虑上述的bugs和挑战之外,我们还需要意识到,计算硬件都只有有限的资源,主要的资源包括:
处理器时间
内存
磁盘空间
网络带宽
单台计算机通常只有几G内存,如果输入数据是TB级的,那就需要上千台计算机才能将这些数据放入内存,即便如此,但是单台计算机仍无法处理和寻址这些数据。
磁盘的空间要多的多,单台机器的磁盘空间现在有几TB左右,但在大规模计算中,计算机产生的中间数据通常是输入数据的几倍,这也就将占有输入数据的几倍磁盘空间。
在处理过程中,一些结点磁盘满了,分布式系统也许需要把这些数据传输到其它可以保存这些溢出数据的结点上去。
最后,即使在内网名,带宽也仍是稀缺资源。
假设一组结点用千兆以太网连接,也许它们之间的有很高的传输速度,但如果所有的结点同时传输几G的数据集合,这样很容易使交换机带宽饱和。
另外,如果机器都分在多个主机架中,那么可用以数据传输的带宽就会更少,更严重的是,用这个信道的RPC请求或其它数据传输请求会延时或被丢弃。
故一个成功的分布式系统必须能高效地使用上述资源,更重要的是,它在分配这些资源时,应将系统视为一个整体,将尽可能多的时间用于核心计算。
多台机器之间的同步仍是分布式系统设计的最大挑战,如果结点在分布式系统中可以直接交互,那么设计者必须认识到交互模式所带来的危险,它很容易产生超出系统所能承受的RPC调用!
进行多方数据交换也会引起死锁和竞争。
最后,在面临部分结点失败时,保持继续计算的能力是一个更大的挑战,比如,一个系统中有100个结点,其中一个崩溃了,但其它99个结点仍能继续计算,理想情况下,系统只是损失了1%的计算能力,更进一步,如果在分布架构上采用了复杂的交互网络,那么决定如何重新计算失败结点的任务是最好,和通知网络拓扑的改变信息,也许是实现的重要部分。
为什么要用一个分布式系统呢?
它们听起来麻烦比价值大,随着计算机硬件的快速的设计脚步,似乎单台计算机的硬件会提高到处理更大的数据量,毕竟摩尔定律(以GordonMoore命名,Intel创始人)说道:
集成电路上可容纳的晶体管数目,约每隔18-24个月便会增加一倍,性能也将提升一倍,而价格下降一半。
但现在的事实是芯片的设计趋势改变了,虽然我们仍可以将单位区域的晶体管数量翻倍,但这已经不能提高单线程的计算速度了,新的CPU,如IntelCore2和Itanium2现在在架构上努力将一些小的CPUs或“核”嵌入到一个物理设备上,这会使多线程并行地处理与单线程相比两倍的数据,但是每个线程的速度还是和以前是一样的。
即使将成百上千的CPU核放到一台计算机上,它也无法很快地把数据传输到这些核去处理,单个磁盘读取速度大约为60-100MB/s,虽然磁盘的读取速度一直在提高,但却无法与处理器速度的提高相比,暂且乐观地假设速度为上限100MB/s,并假设有4个I/O通道,也就是有400MB/s的速度,那么一个4TB的数据集要用10,000秒去读大约4小时才能载入数据,但用100台只有两个I/O通道的机器做相同的工作,只需要3分钟。
Hadoop方法设计目的是将许多普通计算机连接起来并行地处理大量信息。
一个上面提到的1000-CPU的机器,比之1000个单核或250个四核机器的价格要高出许多,Hadoop将会将这些小型的低廉的机器连接起来成为一个性价比高的计算机集群。
与现有方法比较
在大规模数据上进行分布式计算以前也是有的。
Hadoop的独特之处在于它简单的编程模型,它可使用户很快地编写和测试分布式系统,和它高效,自动分布数据和工作到不同机器的方式,以及利用多核并行处理。
计算机的网络调度可以用其它系统,比如Condor,但Condor不能自动分布数据:
必须管理一个单独的SAN,不止如此,多个结点的协作也必须管理交互系统,如MPI,这种编程模型极难掌握,并且会引起一些难以理解的错误。
在Hadoop集群中,数据被分布到集群的各个结点,HadoopDistributedFileSystem(HDFS)将大的数据文件分成块,将这些块交由集群中的结点处理,并且每个块都会复制到不同的几个机器上,所以一台机器崩溃不会导致数据丢失,监测系统会对结点崩溃做出反应,重新复制数据,即部分存储(partialstorage)。
即便文件块被复制分布到不同的机器,但它们形成了一个单一的命名空间,所以它们的内容还是全局可访问的。
在Hadoop的编程框架中,概念上来说,数据是面向记录的。
每个输入文件都被以行或其它特定的应用逻辑格式分开。
集群中的每个结点的每个进程都会处理这分开文件的一部分,Hadoop框架再根据分布式文件系统的信息调试进程到数据/记录的位置,因为文件以块的形式存在于分布式文件系统中,每个结点上的每个计算进程处理数据的一个子集。
哪些数据要被一个结点处理是由数据本身的存放位置决定的。
大部分数据是直接地从磁盘读入CPU,这减少了网络带宽的限制,也防止了不必要的网络传输。
这种策略是将计算移动到数据,而不是将数据移动到计算,这使得Hadoop有丰很高的数据本地性,从而它就有着很高的性能。
图1.1
在数据载入时数据分布到各个结点
隔离的进程
Hadoop限制了进程的通信量,因为每个任务所处理的单个记录与其它记录无关,这初看起来似是一个极大的限制,但它是整个框架更可靠,Hadoop不会运行任意一个程序并将它分布到整个集群,程序必须符合一个特定的编程模型,称为MapReduce。
在MapReduce中,Mapper任务是将记录分开,Mapper的输出会作为Reducer任务的输入,Reducer再将不同的Mapper结果合并。
在一个Hadoop集群中,不同的结点仍会相互通信,但是与其它传统的分布式系统通信有所不同,传统的作法是应用设计者要显式地通过socket或MPI缓冲将字节流从一个结点传到另一个结点,但在Hadoop上的通信是隐式的,数据片断都有着key值,通过它Hadoop就知道如何将相关信息位发送到一个目标结点。
Hadoop在内部管理数据传输和集群拓扑。
通过限制结点之间的通信,Hadoop使分布式系统更可靠,单个结点崩溃可以通过其它结点重新开始任务的方式正常工作。
因为用户级任务不需要结点之间显式地通信,所以不需要用户程序交换信息,同样结点不需要回滚到预定义的检测点去部分地重新开始计算,在Hadoop中其它正常结点继续运行,好似没有错误发生,并将部分重新开始程序这个挑战的方面留到Hadoop层处理。
图1.2
在结点上运行的Mapping和Reducing任务,其中记录也在图中有显示
水平的可扩展性
与其它分布式系统相比,使用Hadoop的好处在于它的水平的可扩展性,在少量结点上,用Hadoop处理有限的数据时,不能展示Hadoop的性能,因为开始Hadoop程序相关的代价比较高,其它并行/分布程序方式,比如MPI(MessagePassingInterface)可能在2台,4台或许10多台计算机上有更好的性能,尽管在少量机器上协同工作在这种系统上也许会取得更好的性能,但这种为性能所要付出的努力是非线性的增长。
用其它分布式框架所写的程序在从十台机器的级别到成百上千台机器需要大量的重构工作,这也许要程序重写几次,并且其它框的基础元素会限制应用的规模大小。
但是特别设计的Hadoop有着水平的可扩展性,一个Hadoop程序写完后,在10个结点上运行,如果迁徙到更大的集群上运行,几乎不需要做什么工作,Hadoop平台会管理数据和硬件资源并提供与可用资源成比较的可靠性能。
第二章:
Hadoop分布式文件系统
HDFS,HadoopDistributedFileSystem,是一个设计用来保存大数据量的数据的分布式文件系统(TB级甚至是PB级),并提供快速访问这些数据的能力,数据通过冗余的方式保存在多台机器上,以来保存对失败的容错性和并行应用的高度可用性,本章介绍分布式文件系统的设计以及如何使用它。
本章目标
理解HDFS的基本设计,以及它与基本的分布式系统概念的关系。
学习如何通过命令行建立和使用HDFS。
学习在你的应用上使用HDFS。
分布式文件系统基础
配置HDFS
与HDFS交互
常用操作示例
HDFS命令行参考
HFSAdmin命令行参考
7.
在MapReduce中使用HDFS
8.
编程中使用HDFS
9.
HDFS权限和安全性
10.
其它HDFS任务
块的重新负载
拷贝大的文件集合
停止结点运行
检验文件系统正常度
对主机架的考虑
11.
HDFSWeb接口
12.
参考
分布式文件系统是设计来保存大数据量的数据,并提供客户端可访问分布在网络上数据的方法。
有许多分布式系统以不同的方法来解决这个问题。
NFS,NetworkFileSystem,是最常见的分布式文件系统,它也是仍然在使用的最古老的分布式文件系统,它的设计非常直观,便有很大的局限性,NFS提供远程访问单台机器的单个逻辑卷的能力,一个NFS服务器将它本地的对外部客户端可见,客户端可以将这个远程的文件系统直接挂载到它们自己的Linux文件系统上,再以对本地磁盘相同的方式访问它。
这种模型一个最大的优点是它的透明性,客户端并不需要特别关注它们是在操作远程的数据文件,标准的库函数如open,close,fread等等,都可通过NFS使用。
但作为一个分布式文件系统,它的能力很有限,一个NFS的文件都要存在一台机器上,这意味着它只能保存一台机器所能保存的数据量,并且不提供这台机器崩溃的可靠性保证(比如通过复制文件到其它服务器上),如果大量客户端要操作数据,会使服务器压力很重,并且客户端必需总是将数据读到它们本地机器上才能操作。
HDFS的设计相对其它分布式文系统,比如NFS,对几个问题是健壮的,特别是:
HDFS设计用来保持非常大数据量的信息,这需要将数据分布到大量的机器上,它支持比NFS大得多的文件大小。
HDFS的数据保存是可靠的,如果集群中的机器工作不正常,数据仍然是可用的。
HDFS提供快速,可扩展的数据访问能力。
通过简单地添加一些机器,就可以使集群能服务于更多的客户端是可能的。
HDFS与HadoopMapReduce能很好地集成,它在可能的情况下,能使数据读取,计算本地化。
尽管HDFS有很强的可扩展性,但由于它高性能的设计也使它局限于某些应用范围,它并不是如NFS通用,下面是HDFS做出的一些权衡:
应用程序使用HDFS要使用流的方式读取文件,HDFS对流式读取文件进地了优化,但这时seek到文件的任一位置这种操作代价就高了。
数据是一次写入,多次读取;
Hadoop不支持写操作关闭文件后,再更新文件(Hadoop0.19支持追加文件)。
由于文件很大,并且是流式读取,所以系统并不提供本地缓存机制,如果要取读过的数据,只能再从HDFS文件中再次读取。
Hadoop假设每个机器都极可能失败,或永远或暂时,集群必须能应付多台机器同时失败的情况(比如,主机架倒了),这时集群性能下降应与损失的机器成比例,系统作为一个整体不应变得很慢,也不应该有数据丢失,Hadoop用复制数据的策略来克服这一困难。
HDFS的设计是基于GFS,GoogleFileSystem的设计,它的设计在论文GoogleFileSystem中有描述。
HDFS是块结构的文件系统,单个文件被分成相同大小的块,这些块被分布到集群中的多台机器上,集群中的单个机器被称为数据结点(DataNode),一个文件可由多个块组成,它们并不需要放到同一台机器上,保存每个块的机器是被随机选择的,所以访问一个文件需要多台机器协作,但它所支持的文件大小会比单台机器的DFS大的多,并保持一个台机器存不下的文件。
如果使用多台机器保存一个文件,那么这些机器中任一一台崩溃都会导致文件不可访问,HDFS通过将每块复制到多台机器(默认3台)的方式来解决这个问题。
图2.1
数据结点保存着多个文件的块,复制数为2,名字结点中保存着文件名与块id的关系
大多数基于块的文件系统的块大小为4KB或8KB,与之相比,HDFS中默认使用块大小为64MB,比前者大出几个数量级。
这使得HDFS减少了对每个文件元数据的存储量,不只如些,通过很大量数据连续化存放在磁盘上,就可以快速地流式读取数据,这种设计的结果是HDFS倾向于处理大文件,并顺序地读取不同于诸如NTFS或EXT。
这些要处理许多小文件的文件系统。
HDFS倾向于保存大量超大文件,每个几百M或几G,因为100MB的文件才不过能分成2个块,在你计算机上的文件也许经常被随机访问,即应用程序从一个文件中不同位置读取少量信息,而不是顺序访问,相反,HDFS希望程序从开始顺序读到结尾的方式读,这使它在第四章所介绍的MapReduce形式的编程中特别有用。
HDFS是在一些机器中以块的形式保存文件,但这些文件并不是普通文件系统的一部分,在运行Hadoop服务的数据结点上输入ls命令,可以显示普通文件系统的内容,但它不能显示HDFS中的文件,这是因为HDFS在一个不同的命名空间中运行,它与本地文件内容是隔离的,HDFS中的文件(更准确性,组成这些文件的块)是保存在数据结点服务管理的一个特定目录下,这些文件没有名字,只有块id,你无法通过Linux文件命令与HDFS中的文件交互。
但HDFS有它自己的文件管理命令,并且还与你熟悉的Linux文件命令很相似,本章将在后面部分向你介绍这些命令。
文件系统可靠保存它的元数据是很重要的,更准确地说,因为文件数据是以一次写入,多次读取的方式访问的,元数据结构(比如:
文件名,目录名)会被大量客户端同时修改,元数据结构信息户不使去同步是很重要的,所以这些只由一台机器来处理,它被称为名字结点(NameNode),保存着文件系统中所有元数据。
因为每个文件都有较少的元数据(它只保存文件名,权限,和文件每块的位置),所有的元数据都保存在NameNode的内存中,可以进行快速访问元数据。
要打开一个文件,客户端可从NodeNode取得该文件每个块的位置,即是哪些结点保存着这个文件的块,客户端再直接从DataNode中读取每个块,这个过程可以并行读取,NameNode并不直接参与块数据传输,这可使它的压力减至最小。
当然,即使名字结点失败名字结点的信息也必须保存,所以有多个冗余系统可以使名字结构完全崩溃时,也可以保存元数据信息。
名字结点崩溃比如数据结点崩溃更严重,当单个数据结点崩溃,整个集群也会正常运行,但名字结点崩溃后,集群将不可访问,除非名字结点手工恢复,幸运的是名字结点参与相比是非常少的,所以它崩溃的可能也远低于任一数据结点。
在集群上配置HDFS只需要很短的时间,首先我们来看Hadoop配置有关的部分,再看名字结点的格式。
集群配置
首先要把Hadoop下载并解压,第五章会介绍Hadoop如何运行,第七章介绍如何建立一个大的集群,并为Hadoop做一些预设置,包括下载依赖的软件。
HDFS配置文件是一组XML文件,它们位于Hadoop的配置目录conf下,conf目录在Hadoop的安装目录下(即解压Hadoop后产生的目录)。
conf/hadoop-defaults.xml文件中包含了Hadoop中的所有参数默认值,这个文件一般视为是只读的,你可以在conf/hadoop-site.xml中设置新的值,以覆盖默认值,这个文件会被复制集群中的所有机器上。
配置设置是以一组键-值对的格式:
<
property>
name>
property-name<
/name>
value>
property-value<
/value>
/property>
在配置中加入<
final>
true<
/final>
可防止属性被别的应用覆盖。
这在大多系统范围配置选项中是有用的。
下列的设置在HDFS配置中是必需的:
key
value
example
fs.default.name
protocol:
//servername:
port
hdfs:
//alpha.milkman.org:
9000
dfs.data.dir
pathname
/home/username/hdfs/data
dfs.name.dir
/home/username/hdfs/name
这些设置的描述如下:
fs.default.name,这是集群名字结点的URI(协议,主机名,端口)。
Hadoop系统中的结点都需要知道名字结点的地址才能进行操作,数据结点要与这个名字结点一起注册,才吏它们的数据通过名字结点变为可用的,客户端要通过个地址取得文件块的真正存放地址再去取数据。
dfs.data.dir,这是数据结点保存数据的本地文件系统的路径,因为它们将运行在不同的机器上,并不需要所有的数据结点都将数据保存到相同前缀的本地路径,集群中的机器是不同的,也是可行的。
但如果这个目录在整个系统都是统一的,那么配置也就简单些,Hadoop默认将dfs.data.dir设为/tmp。
这在测试时是没关系的,但在生产环境中,这样做很容易丢失数据,所以必需覆盖。
dfs.name.dir,这是名字结点保存元数据的本地路径,它仅用于名字结点找到它自己的信息,它在数据结点上不存在,它的默认值也是/tmp,所以它也必须覆盖。
另一个上面没有提及的参数dfs.replication,它是文件系统中每个块的默认复制数,在生产环境集群中,一般就用它的默认值3,你可以随意增加复制数,但它会无谓地用去很多空间,如果把它设小,会影响数据的可用性和可靠性。
在单结点上的配置中,可以直接把下面的配置复制到hadoop-site.xml中(译者注:
这是0.18版的做法,在0.20下不会成功,日后我会更新到0.20的方法的)。
configuration>
fs.default.name<
//:
9000<
dfs.data.dir<
/home/username/hdfs/data<
dfs.name.dir<
/home/username/hdfs/name<
/configuration>
当然,和username是需要修改的,而使用端口9000是任意选择的。
将以上配置拷入con/hadoop-site.xml文件后,将con/目录拷到集群中所有机器上。
主结点需要知道所有数据结点机器的地址,因为启动脚本依赖它,同样在con/目录中,编辑文件子结点,使它包含子结点的完整主机名列表,每行一个主机名,主结点(比如localhost)通常不在这个文件中出现。