Hadoop技术内幕:深入解析HadoopCommon和HDFS架构设计与实现原理(txt+pdf+epub+mobi电子书下载)


发布时间:2020-07-16 19:33:19

点击下载

作者:蔡斌,陈湘萍

出版社:机械工业出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

Hadoop技术内幕:深入解析HadoopCommon和HDFS架构设计与实现原理

Hadoop技术内幕:深入解析HadoopCommon和HDFS架构设计与实现原理试读:

前言

为什么写本书

互联网使得信息的采集、传播速度和规模达到空前的水平,实现了全球的信息共享与交互,它已经成为信息社会必不可少的基础设施,同时也带来了多方面的新挑战。2003年,Google发表了《Google File System》,介绍了Google海量数据处理使用的文件系统,使互联网时代的数据存储发生了革命性的变化。而Doug Cutting等人在Nutch项目上应用GFS和MapReduce思想,并演化为Hadoop项目,经过多年的发展,最终形成了包含多个相关项目的软件生态系统,开创了海量数据处理的新局面。

Hadoop正是为了解决互联网时代的海量数据存储和处理而设计、开发的。简单地讲,Hadoop是一个可以更容易开发和并行处理大规模数据的分布式计算平台,它的主要特点是:扩展能力强、成本低、高效率、可靠。目前,Hadoop的用户已经从传统的互联网公司,扩展到科学计算、电信行业、电力行业、生物行业以及金融公司,并得到越来越广泛的应用。

Hadoop作为一个优秀的开源项目,提供了一些文档和所有的源代码,但是,对于很多开发人员,仅仅通过一些简单的例子或教程学习使用Hadoop的基本功能是远远不够的。同时,随着云计算和大数据的发展,产业界正在经历一次重大变革,特别是基于云计算的海量数据处理,改变着我们思考的方式和习惯,开发者们越来越有必要去了解Hadoop的架构与设计原理。

本书从源代码的层面上对Hadoop的公共工具Common和Hadoop的分布式文件系统HDFS进行了介绍,帮助广大开发者从架构与设计原理的角度去理解Hadoop,从而为更好地使用和扩展Hadoop打下坚实的基础。同时,Hadoop是一个使用Java语言实现的优秀系统,从事Java和分布式计算相关技术的开发者们能从它的源码实现中看到许多优秀的设计思想、对各种设计模式的灵活运用、语言的使用技巧以及编程规范等。这些都有助于加深开发者们对Java相关技术,尤其是Hadoop的理解,从而提高自己的开发水平,拓展自己的技术视野,为工作带来帮助。

读者对象

❑Hadoop开发人员

对这部分读者来说,本书的内容能够帮助他们加深对Hadoop的理解,通过全面了解Hadoop,特别是HDFS的实现原理,为进一步优化、定制和扩展Hadoop提供坚实基础。

❑学习分布式技术的读者

Hadoop是一个得到广泛应用的大型分布式系统,开放的源代码中包含了大量分布式系统设计原理和实现,读者可以通过本书,充分学习、体验和实践分布式技术。

❑学习Java语言的中高级读者

Hadoop使用Java语言实现,它充分利用了Java的语言特性,并使用了大量的标准库和开源工具,很多功能的设计和实现非常优秀,是极佳的学习Java技术的参考资料。

本书的主要内容

本书主要分为三个部分。

第一部分(第1章)对如何建立Hadoop的开发、分析环境做了简单的介绍。对于Hadoop这样复杂、庞大的项目,一个好的开发环境可以让读者事半功倍地学习、研究源代码。

第二部分(第2~5章)主要对Hadoop公共工具Common的实现进行研究。分别介绍了Hadoop的配置系统、面向海量数据处理的序列化和压缩机制、Hadoop使用的远程过程调用,以及满足Hadoop上各类应用访问数据的Hadoop抽象文件系统和部分具体文件系统。

第三部分(第6~9章)对Hadoop分布式文件系统进行了详细的分析。这部分内容采用总-分-总的结构,第6章介绍了HDFS各个实体和实体间接口,第7章和第8章分别详细地研究了数据节点和名字节点的实现原理,第9章通过对客户端的解析,回顾HDFS各节点间的配合,完整地介绍了一个大规模数据存储系统的实现。

通过本书,读者不仅能全面了解Hadoop的优秀架构和设计思想,而且还能从Hadoop,特别是HDFS的实现源码中一窥Java开发的精髓和分布式系统的精要。

勘误和支持

由于作者的水平有限,编写时间跨度较长,同时开源软件的演化较快,书中难免会出现一些错误或者不准确的地方,恳请读者批评指正。如果大家有和本书相关的内容需要探讨,或有更多的宝贵意见,欢迎通过caibinbupt@qq.com和我们联系,希望能结识更多的朋友,[1]大家共同进步。书中的源代码文件可以从华章网站下载。

[1]参见华章网站www.hzbook.com——编辑注

致谢

感谢机械工业出版社华章公司的编辑杨福川和白宇,杨老师的耐心和支持让本书最终得以出版,白老师的很多建议使本书的可读性更强。

感谢腾讯数据平台部的张文郁、赵重庆和徐钊,作为本书的第一批读者和Hadoop专家,他们的反馈意见让本书增色不少。

感谢和我们一起工作、研究和应用Hadoop的腾讯数据平台部,以及IBM中国研究中心和中山大学的领导和同事们,本书的很多内容是对实际项目的总结。

最后,作者向支持本书写作的家人深表谢意,感谢他们的耐心和理解。第一部分环境准备第1章源代码环境准备

数据!数据!数据!

今天,我们正被数据包围。全球43亿部电话、20亿位互联网用户每秒都在不断地产生大量数据,人们发送短信给朋友、上传视频、用手机拍照、更新社交网站的信息、转发微博、点击广告等,使得机器产生和保留了越来越多的数据。数据的指数级增长对处于市场领导地位的互联网公司,如Facebook、谷歌、雅虎、亚马逊、腾讯等提出了挑战。它们需要对TB级别和PB级别的数据进行分析处理,以发现哪些网站更受欢迎,哪些商品更具有吸引力,哪些广告更吸引用户。传统的工具对于处理如此规模的数据集越来越无能为力。

现在,Hadoop应运而生,庞大的信息流有了新的处理平台。1.1 什么是Hadoop

Hadoop是Apache基金会下的一个开源分布式计算平台,以Hadoop分布式文件系统(Hadoop Distributed File System, HDFS)和MapReduce分布式计算框架为核心,为用户提供了底层细节透明的分布式基础设施。HDFS的高容错性、高伸缩性等优点,允许用户将Hadoop部署在廉价的硬件上,构建分布式系统;MapReduce分布式计算计算框架则允许用户在不了解分布式系统底层细节的情况下开发并行、分布的应用程序,充分利用大规模的计算资源,解决传统高性能单机无法解决的大数据处理问题。

Apache Hadoop是目前分析海量数据的首选工具。1.1.1 Hadoop简史

谈到Hadoop的历史,就不得不提到Lucene和Nutch。Hadoop开始时是Nutch的一个子项目,而Nutch又是Apache Lucene的子项目。这3个项目都是由Doug Cutting创立,每个项目在逻辑上都是前一个项目的演进。

Lucene是引擎开发工具包,提供了一个纯Java的高性能全文索引,它可以方便地嵌入各种实际应用中实现全文搜索/索引功能。Nutch项目开始于2002年,是以Lucene为基础实现的搜索引擎应用。Lucene为Nutch提供了文本搜索和索引的API, Nutch不光有搜索功能,还有数据抓取的功能。

但很快,Doug Cutting和Mike Calarella(Hadoop和Nutch的另一位创始人)就意识到,他们的架构无法扩展以支持拥有数十亿网页的网络。这个时候,Google的研究人员在2003年的ACM SOSP(Symposium on Operating Systems Principles)会议上发表的描述Google分布式文件系统(简称GFS)的论文及时地为他们提供了帮助。GFS或类似的系统可以解决他们在网络抓取和索引过程中产生的大量文件存储需求。于是,在2004年,他们开始写GFS的一个开源实现,即Nutch分布式文件系统(NDFS)。

2004年,在OSDI(Operating Systems Design and Implementation)会议上,Google发表了论文,向全世界介绍了MapReduce。2005年初,Nutch的开发者在Nutch上有了一个可工作的MapReduce应用,到当年的年中,所有主要的Nutch算法被迁移到MapReduce和NDFS上。

在Nutch0.8.0版本之前,Hadoop还属于Nutch的一部分,而从Nutch0.8.0开始,Doug Cutting等人将其中实现的NDFS和MapReduce剥离出来成立了一个新的开源项目,这就是Hadoop。同时,对比以前的Nutch版本,Nutch0.8.0在架构上有了根本性的变化,它完全构建在Hadoop的基础之上了。这个时候,已经是2006年2月,大约在同一时间,Doug Cutting加入雅虎,Yahoo投入了专门的团队和资源将Hadoop发展成一个可在网络上运行的系统。

值得一提的是Hadoop名字的来源。

为软件项目命名时,Doug Cutting似乎总会得到家人的启发。Lucene是他妻子的中间名,也是她外祖母的名字。他的儿子在咿呀学语时,总把所有用于吃饭的词叫成Nutch。Doug Cutting如此解释Hadoop的得名:“这是我的孩子给一头吃饱了的棕黄色大象起的名字。我的命名标准就是简短,容易发音和拼写,没有太多的意义,并且不会被用于别处。小孩子是这方面的高手,Googol就是由小孩命名的。”

2008年1月,Hadoop已成为Apache顶级项目,证明它是成功的。通过这次机会,Hadoop成功地被雅虎之外的很多公司应用,如Facebook、纽约时报等。特别是纽约时报,它使用运行在亚马逊的EC2云计算上的Hadoop,将4TB的报纸扫描文档压缩,转换为用于Web的PDF文档,这个过程历时不到24小时,使用100台机器运行,这成为Hadoop一个良好的宣传范例。

2008年2月,雅虎宣布其索引网页的生产系统采用了在10 000多个核的Linux集群上运行的Hadoop。Hadoop真正达到了万维网的规模。2008年4月,在一个900节点的Hadoop集群上,雅虎的研究人员运行1TB的Jim Gray基准排序,只用了209秒,而到了2009年4月,在一个1400节点的集群上对500GB数据进行排序,只用了59秒,这显示了Hadoop强大的计算能力。

2008年开始,Hadoop迈向主流,开始了它的爆发式发展,出现了大量的相关项目,如2008年的HBase、ZooKeeper和Mahout,2009年的Pig、Hive等。同时,还出现了像Cloudera(成立于2008年)和Hortonworks(以雅虎的Hadoop业务部门为基础成立的公司)这样的专注于Hadoop的公司。

经过多年的发展,Hadoop已经从初出茅庐的小象变身为行业巨人。1.1.2 Hadoop的优势

将Hadoop运用于海量数据处理,主要有如下几个优势:

❑方便:Hadoop可以运行在一般商业机器构成的大型集群上,或者是亚马逊弹性计算云(Amazon EC2)等云计算服务上。

❑弹性:Hadoop通过增加集群节点,可以线性地扩展以处理更大的数据集。同时,在集群负载下降时,也可以减少节点,以高效使用计算资源。

❑健壮:Hadoop在设计之初,就将故障检测和自动恢复作为一个设计目标,它可以从容处理通用计算平台上出现的硬件失效的情况。

❑简单:Hadoop允许用户快速编写出高效的并行分布代码。

由于Hadoop具有上述优势,使得Hadoop在学术界和工业界都大受欢迎。今天,Hadoop已经成为许多公司和大学基础计算平台的一部分。学术界如内布拉斯加大学通过使用Hadoop,支持紧凑型m子螺旋形磁谱仪实验数据的保存和计算;加州大学伯克利分校则对Hadoop进行研究,以提高其整体性能;在国内,中国科学院计算技术研究所在Hadoop上开展了数据挖掘和地理信息处理等的研究。在工业界,Hadoop已经成为很多互联网公司基础计算平台的一个核心部分,如雅虎、Facebook、腾讯等;传统行业,如传媒、电信、金融,也在使用这个系统,进行数据存储与处理。

如今,Hadoop分布式计算基础架构这把“大伞”下,已经包含了多个子项目。而海量数据处理也迅速成为许多程序员需要掌握的一项重要技能。1.1.3 Hadoop生态系统

经过几年的快速发展,Hadoop现在已经发展成为包含多个相关项目的软件生态系统。狭义的Hadoop核心只包括Hadoop Common、Hadoop HDFS和Hadoop MapReduce三个子项目,但和Hadoop核心密切相关的,还包括Avro、ZooKeeper、Hive、Pig和HBase等项目,构建在这些项目之上的,面向具体领域、应用的Mahout、X-Rime、Crossbow和Ivory等项目,以及Chukwa、Flume、Sqoop、Oozie和Karmasphere等数据交换、工作流和开发环境这样的外围支撑系统。它们提供了互补性的服务,共同提供了一个海量数据处理的软件生态系统,Hadoop生态系统如图1-1所示。

图 1-1 Hadoop生态系统

下面详细介绍生态系统的组成。

1.Hadoop Common

从Hadoop 0.20版本开始,原来Hadoop项目的Core部分更名为Hadoop Common。Common为Hadoop的其他项目提供了一些常用工具,主要包括系统配置工具Configuration、远程过程调用RPC、序列化机制和Hadoop抽象文件系统FileSystem等。它们为在通用硬件上搭建云计算环境提供基本的服务,并为运行在该平台上的软件开发提供了所需的API。

2.Avro

Avro由Doug Cutting牵头开发,是一个数据序列化系统。类似于其他序列化机制,Avro可以将数据结构或者对象转换成便于存储和传输的格式,其设计目标是用于支持数据密集型应用,适合大规模数据的存储与交换。Avro提供了丰富的数据结构类型、快速可压缩的二进制数据格式、存储持久性数据的文件集、远程调用RPC和简单动态语言集成等功能。

3.ZooKeeper

在分布式系统中如何就某个值(决议)达成一致,是一个十分重要的基础问题。ZooKeeper作为一个分布式的服务框架,解决了分布式计算中的一致性问题。在此基础上,ZooKeeper可用于处理分布式应用中经常遇到的一些数据管理问题,如统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。ZooKeeper常作为其他Hadoop相关项目的主要组件,发挥着越来越重要的作用。

4.HDFS

HDFS(Hadoop Distributed File System, Hadoop分布式文件系统)是Hadoop体系中数据存储管理的基础。它是一个高度容错的系统,能检测和应对硬件故障,用于在低成本的通用硬件上运行。HDFS简化了文件的一致性模型,通过流式数据访问,提供高吞吐量应用程序数据访问功能,适合带有大型数据集的应用程序。

5.MapReduce

MapReduce是一种计算模型,用以进行大数据量的计算。Hadoop的MapReduce实现,和Common、HDFS一起,构成了Hadoop发展初期的三个组件。MapReduce将应用划分为Map和Reduce两个步骤,其中Map对数据集上的独立元素进行指定的操作,生成键-值对形式中间结果。Reduce则对中间结果中相同“键”的所有“值”进行规约,以得到最终结果。MapReduce这样的功能划分,非常适合在大量计算机组成的分布式并行环境里进行数据处理。

6.HBase

Google发表了BigTable系统论文后,开源社区就开始在HDFS上构建相应的实现HBase。HBase是一个针对结构化数据的可伸缩、高可靠、高性能、分布式和面向列的动态模式数据库。和传统关系数据库不同,HBase采用了BigTable的数据模型:增强的稀疏排序映射表(Key/Value),其中,键由行关键字、列关键字和时间戳构成。HBase提供了对大规模数据的随机、实时读写访问,同时,HBase中保存的数据可以使用MapReduce来处理,它将数据存储和并行计算完美地结合在一起。

7.Hive

Hive是Hadoop中的一个重要子项目,最早由Facebook设计,是建立在Hadoop基础上的数据仓库架构,它为数据仓库的管理提供了许多功能,包括:数据ETL(抽取、转换和加载)工具、数据存储管理和大型数据集的查询和分析能力。Hive提供的是一种结构化数据的机制,定义了类似于传统关系数据库中的类SQL语言:Hive QL,通过该查询语言,数据分析人员可以很方便地运行数据分析业务。

8.Pig

Pig运行在Hadoop上,是对大型数据集进行分析和评估的平台。它简化了使用Hadoop进行数据分析的要求,提供了一个高层次的、面向领域的抽象语言:Pig Latin。通过Pig Latin,数据工程师可以将复杂且相互关联的数据分析任务编码为Pig操作上的数据流脚本,通过将该脚本转换为MapReduce任务链,在Hadoop上执行。和Hive一样,Pig降低了对大型数据集进行分析和评估的门槛。

9.Mahout

Mahout起源于2008年,最初是Apache Lucent的子项目,它在极短的时间内取得了长足的发展,现在是Apache的顶级项目。Mahout的主要目标是创建一些可扩展的机器学习领域经典算法的实现,旨在帮助开发人员更加方便快捷地创建智能应用程序。Mahout现在已经包含了聚类、分类、推荐引擎(协同过滤)和频繁集挖掘等广泛使用的数据挖掘方法。除了算法,Mahout还包含数据的输入/输出工具、与其他存储系统(如数据库、MongoDB或Cassandra)集成等数据挖掘支持架构。

10.X-RIME

X-RIME是一个开源的社会网络分析工具,它提供了一套基于Hadoop的大规模社会网络/复杂网络分析工具包。X-RIME在MapReduce的框架上对十几种社会网络分析算法进行了并行化与分布式化,从而实现了对互联网级大规模社会网络/复杂网络的分析。它包括HDFS存储系统上的一套适合大规模社会网络分析的数据模型、基于MapReduce实现的一系列社会网络分析分布式并行算法和X-RIME处理模型,即X-RIME工具链等三部分。

11.Crossbow

Crossbow是在Bowtie和SOAPsnp基础上,结合Hadoop的可扩展工具,该工具能够充分利用集群进行生物计算。其中,Bowtie是一个快速、高效的基因短序列拼接至模板基因组工具;SOAPsnp则是一个重测序一致性序列建造程序。它们在复杂遗传病和肿瘤易感的基因定位,到群体和进化遗传学研究中发挥着重要的作用。Crossbow利用了Hadoop Stream,将Bowtie、SOAPsnp上的计算任务分布到Hadoop集群中,满足了新一代基因测序技术带来的海量数据存储及计算分析要求。

12.Chukwa

Chukwa是开源的数据收集系统,用于监控大规模分布式系统(2000+以上的节点,系统每天产生的监控数据量在T级别)。它构建在Hadoop的HDFS和MapReduce基础之上,继承了Hadoop的可伸缩性和鲁棒性。Chukwa包含一个强大和灵活的工具集,提供了数据的生成、收集、排序、去重、分析和展示等一系列功能,是Hadoop使用者、集群运营人员和管理人员的必备工具。

13.Flume

Flume是Cloudera开发维护的分布式、可靠、高可用的日志收集系统。它将数据从产生、传输、处理并最终写入目标的路径的过程抽象为数据流,在具体的数据流中,数据源支持在Flume中定制数据发送方,从而支持收集各种不同协议数据。同时,Flume数据流提供对日志数据进行简单处理的能力,如过滤、格式转换等。此外,Flume还具有能够将日志写往各种数据目标(可定制)的能力。总的来说,Flume是一个可扩展、适合复杂环境的海量日志收集系统。

14.Sqoop

Sqoop是SQL-to-Hadoop的缩写,是Hadoop的周边工具,它的主要作用是在结构化数据存储与Hadoop之间进行数据交换。Sqoop可以将一个关系型数据库(例如MySQL、Oracle、PostgreSQL等)中的数据导入Hadoop的HDFS、Hive中,也可以将HDFS、Hive中的数据导入关系型数据库中。Sqoop充分利用了Hadoop的优点,整个数据导入导出过程都是用MapReduce实现并行化,同时,该过程中的大部分步骤自动执行,非常方便。

15.Oozie

在Hadoop中执行数据处理工作,有时候需要把多个作业连接到一起,才能达到最终目的。针对上述需求,Yahoo开发了开源工作流引擎Oozie,用于管理和协调多个运行在Hadoop平台上的作业。在Oozie中,计算作业被抽象为动作,控制流节点则用于构建动作间的依赖关系,它们一起组成一个有向无环的工作流,描述了一项完整的数据处理工作。Oozie工作流系统可以提高数据处理流程的柔性,改善Hadoop集群的效率,并降低开发和运营人员的工作量。

16.Karmasphere

Karmasphere包括Karmasphere Analyst和Karmasphere Studio。其中,Analyst提供了访问保存在Hadoop里面的结构化和非结构化数据的能力,用户可以运用SQL或其他语言,进行即时查询并做进一步的分析。Studio则是基于NetBeans的MapReduce集成开发环境,开发人员可以利用它方便快速地创建基于Hadoop的MapReduce应用。同时,该工具还提供了一些可视化工具,用于监控任务的执行,显示任务间的输入输出和交互等。需要注意的是,在上面提及的这些项目中,Karmasphere是唯一不开源的工具。

正是这些项目的发展,带来了廉价的处理大数据的能力,让Hadoop成为大数据行业发展背后的驱动力。如今,Hadoop已成为分布式大数据处理事实上的标准。1.2 准备源代码阅读环境

在研究一个开源项目之前,都需要安装与配置基本的开发环境和源代码的阅读环境。这一系列内容包括:安装与配置JDK、安装开发调试IDE、安装与配置相关辅助工具等。1.2.1 安装与配置JDK

在分析Hadoop的源代码前,需要做一些准备工作,其中搭建Java环境是必不可少的。Hadoop的运行环境要求Java 1.6以上的版本。打开http://www.oracle.com/technetwork/java/javase/downloads/index.html页面,可以下载最新的JDK安装程序,下载页面如图1-2所示。

图 1-2 JDK下载首页

安装完后,要检查JDK是否配置正确。

某些第三方的程序会把自己的JDK路径加到系统PATH环境变量中,这样,即便安装最新版本的JDK,系统还是会使用第三方程序所带的JDK。在Windows环境中,需要正确配置的Java运行时环境变量有JAVA_HOME、CLASSPATH和PATH等。

方便起见,我们往往为操作系统本身指定一个系统级别的环境变量。例如,Windows平台上的系统环境变量可以在“系统属性”的“高级”选项卡中找到,可在其中配置JAVA_HOME、PATH和CLASSPATH值。图1-3是Windows XP操作系统中为系统添加JAVA_HOME环境变量的例子。

图 1-3 Windows XP上添加JAVA_HOME环境变量

安装并配置完成后,可以在命令行窗口中输入"java-version"命令检测当前的JDK运行版本。如果配置完全正确,会显示当前客户端的JRE运行版本,如图1-4所示。

图 1-4 JDK安装成功1.2.2 安装Eclipse

在成功安装和配置JDK后,还需要安装进行Java开发调试的IDE(Integrated Development Environment,集成开发环境),因为一个好的开发环境和源代码阅读环境可以使工作效率事半功倍。目前比较常用的Java开发IDE主要有Eclipse和NetBeans等,读者可以任意选择自己习惯的IDE作为开发工具。本书以Eclipse集成开发环境为例,着重介绍在Eclipse中开发与调试源码的方法。读者也可以举一反三,在其他IDE中做相应的尝试。

Eclipse是一个界面友好的开源IDE,并支持成千上万种不同的插件,为代码分析和源码调试提供了极大的便利。可以在Eclipse官方网站(http://www.eclipse.org/downloads/)找到Eclipse的各个版本(对Hadoop源码进行分析,只需要下载Eclipse IDE for Java SE Developers)并下载安装。Eclipse下载页面如图1-5所示。Eclipse是基于Java的绿色软件,解压下载得到ZIP包后就能直接使用。关于Eclipse的基本使用已超出了本书的范围,因此下面仅向读者简要介绍如何使用Eclipse进行一些基本的源代码分析工作。

1.定位某个类、方法和属性

在分析源代码的过程中,有时候需要快速定位光标位置的某个类、方法和属性,在Eclipse中可通过按F3键,方便地查看类、方法和变量的声明和定义的源代码。

有时候在查看一些在JDK库中声明/定义的类、方法和变量的源代码时,打开的却是相应的CLASS文件(字节码),为此Eclipse提供了一个功能,把字节码和源代码关联起来,这样,就可以查看(提供源代码)第三方库的实现了。

图 1-5 Eclipse下载页

Eclipse打开字节码文件时,可以单击"Attach Source"按钮进行字节码和源代码关联,如图1-6所示。

图 1-6 字节码和源代码关联

在查看java.net.URL时,Eclipse提示代码关联,将JDK中附带的JDK源文件压缩包(在安装目录下可以找到,名字是"src.zip")绑定到"rt.jar",以后,只要访问该JAR包中的字节码文件,Eclipse就会自动显示相应的源代码文件。

其他第三方Java插件的源代码文件的载入方法类似。

2.根据类名查找相应的类

如果知道希望在编辑器中打开的Java类的名称,则找到并打开它的最简单的方法是使用快捷键Ctrl+Shift+T(或者单击Navigate→Open Type)打开Open Type窗口,在该窗口中输入名称,Eclipse将显示可以找到的匹配类型列表。图1-7显示了Hadoop 1.0中名字包含"HDFS"的所有类。

图 1-7 在Eclipse中查看名字包含HDFS的所有类

注意 除了输入完整的类名之外,还可以使用和通配符来分别匹配“任何”或“单个”字符。

3.查看类的继承结构

Java是面向对象的程序设计语言,继承是面向对象的三大特性之一,了解类、接口在继承关系上的位置,可以更好地了解代码的工作原理。选中某个类并使用Ctrl+T快捷键(或单击Navigate→Quick Type Hierarchy)可以显示类型层次结构。

层次结构将显示所选元素的子类型。如图1-8所示,该列表显示已知的所有org.apache.hadoop.fs.FileSystem子类。

图 1-8 在Eclipse中显示类型层次结构

4.分析Java方法的调用关系

在Eclipse中可以分析Java方法的调用关系,具体做法如下:在代码区中选择相应的方法定义,然后用鼠标右键选取Open Call Hierarchy项或者使用快捷键Ctrl+Alt+H,则可以在Call Hierarchy视图中看到方法的调用关系,该视图还提供了一层一层的方法调用追溯功能,对查找方法的相互调用关系非常有用,如图1-9所示。

图 1-9 在Eclipse中查看方法的调用关系

注意 快捷键是日常开发调试中最为便捷的技巧。Eclipse中的快捷键也可谓是博大精深,这里不一一列举。读者可以在实际开发中不断摸索并牢记这些快捷键,因为它们也是日常开发中必不可少的内容。读者也可参照Eclipse中的这些快捷键,在其他IDE中找到相应的快捷键设置。1.2.3 安装辅助工具Ant

在安装和配置了JDK和Eclipse后,为了编译Hadoop,还需要安装辅助工具Ant。

对Hadoop这样复杂的项目进行构建,不是仅仅将Java源文件编译并打包这么简单,项目中使用到的各种资源都需要得到合理的安排,如有些文件需要拷贝到指定位置,有些类需要放入某个JAR归档文件,而另外一些类则需要放入另外一个JAR归档文件等,这些工作如果全部由手工执行,项目的构建部署将会变得非常困难,而且难免出错。Ant是针对这些问题推出的构建工具,在Java的项目中得到了最广泛的使用。

Ant跨平台、可扩展,而且运行高效,使用Ant,开发人员只需要编写一个基于XML的配置文件(文件名一般为build.xml),定义各种构建任务,如复制文件、编译Java源文件、打包JAR归档文件等,以及这些构建任务间的依赖关系,如构建任务“打包JAR归档文件”需要依赖另外一个构建任务“编译Java源文件”。Ant会根据这个文件中的依赖关系和构建任务,对项目进行构建、打包甚至部署。

和Hadoop一样,Ant也是Apache基金会支持的项目,可以在http://ant.apache.org/bindownload.cgi下载,下载页面如图1-10所示。

和Eclipse类似,Ant也是绿色软件,不需要安装,解压缩下载的文件后需要做一些配置,用户需要添加环境变量ANT_HOME(指向Ant的根目录),并修改环境变量PATH(在Windows环境下,添加%ANT_HOME%\bin到PATH中)。安装并配置完成后,可以在命令行窗口中输入"ant-version"命令来检测Ant是否被正确设置。

图 1-10 Apache Ant下载页面

Hadoop的Ant还使用了一个工具:Apache Ivy,它是Ant的一个子项目,用于管理项目的外部构建依赖项。外部构建依赖项是指软件开发项目的构建需要依靠来自其他项目的源代码或JAR归档文件,例如,Hadoop项目就依靠log4j作为日志记录工具,这些外部依赖项使得构建软件变得复杂。对于小项目而言,一种简单可行的方法是将其依赖的全部项目(JAR文件)放入一个目录(一般是lib)中,但当项目变得庞大以后,这种方式就会显得很笨拙。Apache的另外一个构建工具Maven中,引入了JAR文件公共存储库的概念,通过外部依赖项声明和公开的公共存储库(通过HTTP协议)访问,自动查找外部依赖项并下载,以满足构建时的依赖需要。

Ivy提供了Ant环境下最一致、可重复、易于维护的方法,来管理项目的所有构建依赖项。和Ant类似,Ivy也需要开发人员编写一个XML形式的配置文件(一般文件名为ivy.xml),列举项目的所有依赖项;另外还要编写一个ivysettings.xml文件(可以随意为此文件命名),用于配置下载依赖关系的JAR文件的存储库。通过Ant的两个Ivy任务ivy:settings和ivy:retrieve,就可以自动查找依赖项并下载对应的JAR文件。1.2.4 安装类UNIX Shell环境Cygwin

对于在Windows上工作的读者,还需要准备类UNIX Shell环境的Cygwin。

注意 在Linux等类UNIX系统中进行Hadoop代码分析、构建的读者可以略过这一节。

Cygwin是用于Windows的类UNIX Shell环境,由两个组件组成:UNIX API库(它模拟UNIX操作系统提供的许多特性),以及在此基础上的Bash Shell改写版本和许多UNIX实用程序,它们一起提供了大家熟悉的UNIX命令行界面。

Cygwin的安装程序setup.exe是一个标准的Windows程序,通过它可以安装或重新安装软件,以及添加、修改或升级Cygwin组件。其下载页面为http://cygwin.com/index.html,如图1-11所示。

图 1-11 Cygwin下载页面

执行安装程序setup.exe,并在安装程序的步骤4(Cygwin Setup-Select Package)中选择UNIX的在线编辑器sed,如图1-12所示(可以利用Search输入框快速找到sed)。

图 1-12 Cygwin中选择在线编辑器sed

在安装sed时,setup.exe会自动安装它依赖的包。在Cygwin中,可用的包超过1000个,所以只需选择需要的类别和包,以后随时可以通过再次运行setup.exe,添加整个类别或单独的包。在Windows下构建Hadoop,只需要文本处理工具sed。

安装完成后,使用Start菜单或双击Cygwin图标启动Cygwin。可以在Shell环境中执行"ant-version|sed"s/version/Version/g""命令验证Cygwin环境,如图1-13所示。

图 1-13 Cygwin安装验证

成功安装JDK、Eclipse、Ant和Cygwin之后,就可以开始准备Hadoop源代码分析的Eclipse环境了。1.3 准备Hadoop源代码

在Hadoop的官方网站(http://hadoop.apache.org/)中,可以找到Hadoop项目相关的信息,如图1-14所示。

图 1-14 Apache Hadoop官方网站1.3.1 下载Hadoop

前面在介绍Hadoop生态系统的时候,已经了解到Hadoop发展初期的系统中包括Common(开始使用的名称是Core)、HDFS和MapReduce三部分,现在这些子系统都已经独立,成为Apache的子项目。但在Hadoop 1.0的发行包中,Common、HDFS和MapReduce还是打包在一起,我们只需要下载一个hadoop-1.0.0.tar.gz包即可。注意,Hadoop官方也提供Subversion(SVN)方式的代码下载,SVN地址为http://svn.apache.org/repos/asf/hadoop/common/tags/release-0.1.0/。

熟悉Subversion的读者,也可以通过该地址下载Hadoop1.0版本代码,该Tag也包含了上述三部分的代码。

Apache提供了大量镜像网站,供大家下载它的软件和源码,上面提到的hadoop-1.0.0.tar.gz的一个下载地址为http://apache.etoak.com/hadoop/common/hadoop-1.0.0,如图1-15所示。

图 1-15 Apache Hadoop 1.0的一个下载页

该地址包含了Hadoop 1.0的多种发行方式,如64位系统上的hadoop-1.0.0-1.adm64.rpm、不包含源代码的发行包hadoop-1.0.0.bin.tar.gz等。下载的hadoop-1.0.0.tar.gz是包括源代码的Hadoop发行包。1.3.2 创建Eclipse项目

解压下载的hadoop-1.0.0.tar.gz包,假设解压后Hadoop的根目录是E:\hadoop-1.0.0,启动Cygwin,进入项目的根目录,我们开始将代码导入Eclipse。Hadoop的Ant配置文件build.xml中提供了eclipse任务,该任务可以为Hadoop代码生成Eclipse项目文件,免去创建Eclipse项目所需的大量配置工作。只需在Cygwin下简单地执行"ant eclipse"命令即可,如图1-16所示。

图 1-16 创建Eclipse项目文件

注意 该过程需要使用UNIX的在线编辑器sed,所以一定要在Cygwin环境里执行上述命令,否则会出错。

命令运行结束后,就可以在Eclipse中创建项目了。打开Eclipse的File→New→Java Project,创建一个新的Java项目,选择项目的位置为Hadoop的根目录,即E:\hadoop-1.0.0,然后单击"Finish"按钮,就完成了Eclipse项目的创建,如图1-17所示。

图 1-17 创建Eclipse项目

完成上述工作以后,Eclipse提示一个错误:"Unbound classpath variable:'ANT_HOME/lib/ant.jar'in project'hadoop-1.0.0'"。

显然,我们需要设置系统的ANT_HOME变量,让Eclipse能够找到编译源码需要的Ant库,选中项目,然后打开Eclipse的Project→Properties→Java Build Path,在Libraries页编辑(单击"Edit"按钮)出错的项:ANT_HOME/lib/ant.jar,创建变量ANT_HOME(在接下来第一个对话框里单击"Varliable",第二个对话框里单击"New"按钮),其值为Ant的安装目录,如图1-18所示。

由于本书只分析Common和HDFS两个模块,在Project→Properties→Java Build Path的Source页只保留两个目录,分别是core和hdfs,如图1-19所示。

完成上述操作以后,创建Eclipse项目的任务就完成了。

图 1-18 创建ANT_HOME变量

图 1-19 保留core和hdfs两个源码目录1.3.3 Hadoop源代码组织

打开已经解压的Hadoop 1.0源代码,进入src目录,该目录包含了Hadoop中所有的代码,如图1-20所示。

前面已经提到过,Hadoop 1.0的发行包中,Common、HDFS和MapReduce三个模块还是打包在一起的,它们的实现分别位于core、hdfs和mapred子目录下。源代码目录src下还有若干值得关注的子目录,具体如下。

❑tools:包含Hadoop的一些实用工具的实现,如存档文件har、分布式拷贝工具distcp、MapReduce执行情况分析工具rumen等。

❑benchmarks:包含对Hadoop进行性能测试的两个工具gridmix和gridmix2,通过这些工具,可以测试Hadoop集群的一些性能指标。

❑c++:需要提及的是libhdfs,它通过Java的C语言库界面,实现了一套访问HDFS的C接口。

❑examples:为开发人员提供了一些使用Hadoop的例子,不过这些例子只涉及MapReduce的API,本书中不会讨论这部分内容。

❑contrib:是contribution的缩写,包含大量Hadoop辅助模块的实现,如在亚马逊弹性计算云上部署、运行Hadoop所需的脚本就在contrib\ec2目录下。

❑test:包含项目的单元测试用例,在该目录中能找到Common、HDFS和MapReduce等模块的单元测试代码。

图 1-20 Hadoop源码组织1.4 小结

大数据以及相关的概念、技术是业界和学界最近关注的热点内容,Hadoop在其中扮演了十分重要的角色。本节首先对Hadoop进行了简单的介绍,展示了蓬勃发展的Hadoop生态系统和Hadoop的简单历史。并在此基础上,向读者介绍了阅读分析Hadoop所必需的开发环境的搭建过程,包括:安装与配置JDK、安装与配置Eclipse、安装与配置辅助工具的工作。最后,在上述环境中,从零开始建立了一个包含Hadoop Common和HDFS的源码环境,为进一步学习Hadoop源代码做好准备。第二部分Common的实现第2章Hadoop配置信息处理

任何一个复杂的软件系统,为了提高其适应性和扩展性,一般都会有一个配置模块或配置系统,作为其扩展、定制的手段和方式。Hadoop使用配置文件将系统中的重要属性以文件的形式进行持久化,使得这些属性可以被重启后的进程或者不同的进程使用。2.1 配置文件简介

配置文件是一个灵活系统不可缺少的一部分,虽然配置文件非常重要,但却没有标准。本节我们来了解Windows操作系统和Java环境中的配置文件。2.1.1 Windows操作系统的配置文件

Windows系统广泛使用一种特殊化的ASCII文件(以"ini"为文件扩展名)作为它的主要配置文件标准。下面是INI文件的片段:

;最后修改时间:2012.10.12

[owner]

name=John Doe

organization=Acme Widgets Inc.

[database]

server=192.0.2.62;使用IP地址,在域名解析不能使用时还能正常工作

port=143

file="payroll.dat"

[ftp]

该文件也称为初始化文件(Initialization File,它的扩展名就是initialization的前三个字母)或概要文件(profile),应用程序可以拥有自己的配置文件,存储应用的设置信息,也可以访问Windows的基本系统配置文件win.ini中存储的配置信息。INI文件将配置信息分为“节”,节标题放在方括号中。如上面例子中的[database],就是database节的节标题。节用于对配置数据做一个归类,每一个节可以包含一些与之相关的“项”(ENTRY),并通过等号对其进行赋值(VALUE)。一般的形式如下:

[SECTION]

ENTRY=VALUE

其中VALUE值可以有两种类型:数型或字符串。上面给出的INI文件片段中,database节中包含3个项,分别是server、port和file。其中,配置项port可以以数型的形式读取。

INI文件中的注释以分号开始,到行尾结束。

Windows操作系统同时还提供了一些API,用来对配置文件进行读、写。如使用GetProfileString()函数可以从配置文件win.ini中获取字符串型配置,使用GetPrivateProfileInt()函数可以从私有的配置文件中读取一个配置整数型项。该函数的原型如下:

UINT WINAPI GetPrivateProfileInt(

__in LPCTSTR lpAppName,

__in LPCTSTR lpKeyName,

__in INT nDefault,

__in LPCTSTR lpFileName

);

其中,参数LPCTSTR lpFileName是INI文件的文件名,LPCTSTR lpAppName和LPCTSTR lpKeyName分别是上述的“节”和“项”,INT nDefault是默认值,也就是说,如果在配置文件中找不到配置信息,就返回该默认值。2.1.2 Java配置文件

JDK提供了java.util.Properties类,用于处理简单的配置文件。Properties很早就被引入到Java的类库中,并且一直没有什么变化。它继承自Hashtable,如图2-1所示,表示了一个持久的属性集,该集可保存在流中或从流中加载。属性列表中每个键及其对应值都是字符串类型。

图 2-1 Properties的继承关系

相对于INI文件,Properties处理的配置文件格式非常简单,它只支持键-值对,等号左边为键,右边为值。形式如下:

ENTRY=VALUE

由于Properties基于Hashtable,它并不能支持INI文件中的“节”,对配置项进行分类。

java. util.Properties中用于处理属性列表的主要方法如下,其中,getProperty()用于在属性列表中获取指定键(参数key)对应的属性,它有两个形式,一个不提供默认值,另一个可以提供默认值。Properties.setProperty()用于在属性列表中设置/更新属性值。相关代码如下:

//用指定的键在此属性列表中搜索属性

public String getProperty(String key)

//功能同上,参数defaultValue提供了默认值

public String getProperty(String key, String defaultValue)

//最终调用Hashtable的方法put

public synchronized Object setProperty(String key, String value)

Properties中的属性通过load()方法加载,该方法从输入流中读取键-值对,而store()方法则将Properties表中的属性列表写入输出流。使用输入流和输出流,Properties对象不但可以保存在文件中,而且还可以保存在其他支持流的系统中,如Web服务器。J2SE 1.5版本以后,Properties中的数据也可以以XML格式保存,对应的加载和写出方法是loadFromXML()和storeToXML()。

下面是以XML格式存在的Properties配置文件的例子。

<?xml?version=“1.0”?encoding="UTF-8"?>

<!DOCTYPE?properties?SYSTEM

"http://java.sun.com/dtd/properties.dtd">

<properties>

<comment>Hi</comment>

<entry?key="foo">bar</entry>

<entry?key="fu">baz</entry>

</properties>

由于java.util.Properties提供的能力有限,Java社区中出现了大量的配置信息读/写方案,其中比较有名的是Apache Jakarta Commons工具集中提供的Commons Configuration。Commons Configuration中的PropertiesConfiguration类提供了丰富的访问配置参数的方法。Commons Configuration支持文本、XML配置文件格式;支持加载多个配置文件;支持分层或多级的配置;同时提供对单值或多值配置参数的基于类型的访问。应该说,Commons Configuration是一个功能强大的配置文件处理工具。2.2 Hadoop Configuration详解

Hadoop没有使用java.util.Properties管理配置文件,也没有使用Apache Jakarta Commons Configuration管理配置文件,而是使用了一套独有的配置文件管理系统,并提供自己的API,即使用org.apache.hadoop.conf.Configuration处理配置信息。2.2.1 Hadoop配置文件的格式

Hadoop配置文件采用XML格式,下面是Hadoop配置文件的一个例子:

<?xml version=“1.0”?>

<?xml-stylesheet type="text/xsl"href="configuration.xsl"?>

<configuration>

<property>

<name>io.sort.factor</name>

<value>10</value>

<description>The number of streams to merge at once while sorting

files.This determines the number of open file handles.</description>

</property>

<property>

<name>dfs.name.dir</name>

<value>${hadoop.tmp.dir}/dfs/name</value>

<description>Determines where on the local filesystem the DFS name

nodeshould store the name table(fsimage).……</description>

</property>

<property>

<name>dfs.web.ugi</name>

<value>webuser, webgroup</value>

<final>true</final>

<description>The user account used by the web interface.

Syntax:USERNAME, GROUP1,GROUP2,……</description>

</property>

</configuration>

Hadoop配置文件的根元素是configuration,一般只包含子元素property。每一个property元素就是一个配置项,配置文件不支持分层或分级。每个配置项一般包括配置属性的名称name、值value和一个关于配置项的描述description;元素final和Java中的关键字final类似,意味着这个配置项是“固定不变的”。final一般不出现,但在合并资源的时候,可以防止配置项的值被覆盖。

在上面的示例文件中,配置项dfs.web.ugi的值是"webuser, webgroup",它是一个final配置项;从description看,这个配置项配置了Hadoop Web界面的用户账号,包括用户名和用户组信息。这些信息可以通过Configuration类提供的方法访问。

在Configuration中,每个属性都是String类型的,但是值类型可能是以下多种类型,包括Java中的基本类型,如boolean(getBoolean)、int(getInt)、long(getLong)、float(getFloat),也可以是其他类型,如String(get)、java.io.File(getFile)、String数组(getStrings)等。以上面的配置文件为例,getInt("io.sort.factor")将返回整数10;而getStrings("dfs.web.ugi")返回一个字符串数组,该数组有两个元素,分别是webuser和webgroup。

合并资源指将多个配置文件合并,产生一个配置。如果有两个配置文件,也就是两个资源,如core-default.xml和core-site.xml,通过Configuration类的loadResources()方法,把它们合并成一个配置。

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载