Hadoop学习笔记(9) ——源码初窥

Hadoop学习笔记(9) java

——源码初窥 node

以前咱们把Hadoop算是入了门,下载的源码,写了HelloWorld,简要分析了其编程要点,而后也编了个较复杂的示例。接下来其实就有两条路可走了,一条是继续深刻研究其编程及部署等,让其功能使用的淋漓尽致。二是停下来,先看看其源码,研究下如何实现的。在这里我就选择第二条路。 linux

研究源码,那咱们就来先看一下整个目录里有点啥: c++

这个是刚下完代码后,目录列表中的内容。 web

目录/文件apache

说明编程

binwindows

下面存放着可执行的sh命名,全部操做都在这里app

confeclipse

配置文件所在目录

ivy

Apache Ivy是专门用来管理项目的jar包依赖的,这个是ivy的主要目录

lib

引用的库文件目录,里面存放用到的jar包

src

这个里面就是主要的源码了

build.xml

用于编译的配置文件。 编译咱们用的是ant

CHANGES.txt

文本文件,记录着本版本的变动历史

ivy.xml

Ivy的配置文件

LICENSE.txt

文件本文件,

NOTICE.txt

文本文件,记录着须要注意的地方

README.txt

说明文件。

 

进入src目录,咱们看到了:

目录/文件

说明

ant

为ant命令编写的扩展指定

benchmarks

笔者也没弄明白L

build

就存放一个打包信息文件

c++

linuxamd64-64位系统以及i386-32位系统提供的库文件集合

contrib

是开源界或第三方为hadoop编写的一些扩展程序,如eclipse插件等

core

Hadoop的核心代码

docs

文档

examples

示例程序

hdfs

HDFS模块的代码

marped

MapReduce模块代码

native

笔者也没弄明白L

test

测试程序

tools

工具集

webapps

网页管理工具的代码,主要是jsp文件。

fixFontsPath.sh

用于修正字体路径的批处理命令。

saveVersion.sh

用于生成打包信息文件批处理命令。

 

这些目录及文件命名及分布仍是很清晰的,基本上根据命名也能猜出其意思来了。当咱们拿到这些文件时,作了两件事,编译运行,接下来咱们一块块仔细来看看。

 

编译

当咱们拿到手时,第一章中讲到,咱们用了如下命令就完成了编译:

~/hadoop-0.20.2$ant

~/hadoop-0.20.2$ant jar

~/hadoop-0.20.2$ant examples

在编译完后,咱们发现,目录中多了一个build文件夹。这个文件夹下,咱们发现有大量的子文件夹,再深刻看,能够找到了N多个.class文件。那这个正是java程序的编译产出物。

咱们在第5章中,简要的描述了java程序与.net的差异。一个.java程序对应一个.class文件,手动的话用javac来编译。咱们要将这么多的java文件都要编译成一个个的.class文件,敲javac命令确定是不行的,咱们得找个打包处理的办法。这个就是ant。简单的说ant就是将编译命名进行打包处理的程序,这个程序有一个配置文件就是build.xml。因此咱们进入hadoop根目录后输入了ant后就开始运行了,由于它在当前目录下找到了build.xml文件。那ant能作啥,其实百度上一搜就有不少了。这里就不详述了。咱们简要的来看一下build.xml。 打开一看,build.xml文件貌似很复杂,有1千8百多行。不要怕,简单看下:

一上来,定义了一个project,看来这是一个工程,有名称和default属性(default后面看是啥)。

接下来发现是一堆的property,而后是name-value的健值。应该猜的出,这些就是后面真正执行用的一些变量或参数。

再往下,看到有这些:

看到有target,而后取了个名,字面意思是目标,而后看看子结点,发现是mkdir,好熟悉的字眼,这不是在建立目录么,看下第一个dir是啥,${build.dir}。而后当即跑回上面property中,看下是否有呢?

果真,这个就是在编译后的产生的目录,第一步建立之,很正常。

既然这样,这个target就是一个个目标,而后往下拖一下,发现下面的都是一个个的目录,全文搜索一下:

发现里面有106个。

继续搜,发现了亮点:

这个target(目标)好眼熟,~/hadoop-0.20.2$ant jar 没错,当时在编译时,输入这个命令后,就产出了一个jar文件。看来这个target就是在造成jar文件,略看下其子命令,的确就是在生成jar包了。

简单了解了这个target后,就能够继续找找,咱们的examples命令了。现回想起来,在编译时第一个命令是~/hadoop-0.20.2$ant,而这个好象没有写target么?又想到了:

难道这个default就是传说中的默认目标? compile。 熬不住了,当即展开搜索:

果真,猜的没错。找到了这个默认目录,而后发现好多target后还有depends,字面意思,依赖吧,而后能够继续找,依赖里面的目录,也是一个个的target。

了解了这个以后,咱们又在想,如今知道的target也就 默认、jar、example,还有哪些呢,咱们就能够搜target name="这个字符。固然会发现有不少,可是不是每一个都对咱们有用,由于好可能是为了编写方便,将一个大的拆成多个小的,以便于维护。至于哪些有用的,这里我就不一一列出。能够本身看看。 好比clean就不错,能够把编译后的结果清理掉,还原到开始状态。

 

编译成.class包括jar包如今都没问题了。咱们知道hadoop是用java写的,在src下可找到大量java类文件。难道这个hadoop就没有引用一个第三方的组件?答案是有的,一开始没看到几个,在lib下就只有几个。 可是在ant完后,在build下搜,发现有好多个jar文件。 哪来的? 下载的。谁负责下载的,为何知道要下载这些文件?

咱们发现,在build.xml中,第一个target init就有depends:

而后就能够一级级查到,是通用ivy进行下载的,至于下载哪些,在ivy.xml中就有配置。好了,这块并非咱们的重点,了解到这里就够了,反正所用到的lib文件都下来了。

 

运行

在第一章中,咱们了解到启用整个hadoop,全到了这个命令:bin/start-all.sh,关闭是用到了bin/stop-all.sh。而这个又是什么文件,咱们来研究一下看。

不急看start-all, 咱们打开bin目录看一下:

在bin下有不少个sh文件,hadoop这个命令,虽然没有后缀,但打开看后,发现跟其余sh文件样,相似的脚本。

什么是sh文件? 在windows中咱们知道bat文件,就是将若干个命令放到一个文件中,依次执行,称之为批处理文件。在Linux中,这个bat文件就是sh文件了。

先不急着打开文件内容,咱们观察下因此文件,看到下面8个,颇有规律,4个startXXX.sh而后4个stopXXX.sh文件。看来这些就是用户启动和关闭hadoop用的。

打开start-all.sh,发现内容并很少,也很好理解:

 

这里,先调了一下hadoop-config.sh,字面意思,设置配置文件。而后再调了start-dfs 和start-mapred。这里就很明显了,start-all是启动整个hadoop,而后里面包含了两个动做,启动dfs和mapreduce。 同理,若是我想只启动dfs,那么只须要运行start-dfs.sh便可。

一样,打开stop-all.sh文件,也能够看到比较简单,

发现是分别调了stop-mapred.sh和stop-dfs.sh这两个文件。

这里咱们就不每一个文件进行分析了,咱们只挑几个关键文件看一下。

 

继续前行,打开start-dfs.sh和stop-dfs.sh文件,发现里面

 

你们能够打开其余全部的startXX和stopXX文件,发现全部的操做都又转入了hadoop-daemon.sh和hadoop-daemons.sh这两个命令,同时传入了参数—config stop/start 名称 (opt参数)。

继续,打开hadoop-daemons.sh,发现内容也很简单:

这里,先调用了slaves.sh后,又调回来hadoop-daemon.sh,因此如今目标焦点就只有两个了hadoop-daemon.sh和slaves.sh了。打开slaves.sh看一下:

这个文件的字面意思应该就是启动各分布式子机的hadoop咯。看一下代码,第一个if与fi之间,能够看到是取得conf文件夹下的slaves文件。记得在配置分配布式里面,在slaves中配置写了是node1 node2用回车换行隔开。 因此第二段代码,for循环slaves中的文件,而后调用ssh命令,调到了子系统中的相应的命令,这里,就彻底能够想通了,为何子系统中部署的hadoop目录须要与主目录相同,而后slaves中配置的是子系统机器的名称。

到这里,整个bin目录的脚本,就集中在剩下的两个hadoop-daemon.sh和hadoop了。胜利在望了。先看hadoop-daemon.sh。

一开始,代码是在取参数,startstop和command,从前面的传入能够看到,startstop参数传的是start和stop,看来是启动和关闭, command是namenode、datanode之类的。

继续往下看:

case语句下进行了分类,将start和stop命令分开处理。在start时,先是建立一个文件夹PID_DIR,具体值能够看上面,而后第一段if,是在判断进程有没有启动,而后最关健是执行nohup nice …. /bin/hadoop。也就是说归根到底又都是在执行hadoop命令了。这里nohup,是指启动进程后不被卡住,即转为后台进程,又称守护进程,因此该sh文件命名为daemon也不为过。

而后stop段时,把进程进行kill掉。这里有疑问了,启动的命令kill里须要知道进程的PID,而kill里哪里获取呢,在启动时,将启动进程后的pid记录在PID文件夹内,而后kill时就能够跟据这些PID来处理了。这块在代码中,也比较清晰的体现了。

 

在执行hadoop命令时,又将namenode、datanode、secondarynamenode等命令传入。因此如今能够打开hadoop命令文件了:(这里直接跳入重点看)

这里,看到有大量的if语句,条件是command判断,而后执行中对class和hadoop_opts进行了赋值。 继续往下看:(在最后)

咱们发现,是在执行java命令,传入的main函数入口正是上面条件处理中的CLASS变量。换句话说,这个CLASS应该对应一个个的main函数咯? 验证一下,找一个,好比dataNode,其CLASS是org.apache.hadoop.hdfs.server.datanode.DataNode。按这路径在src中找到文件DataNode.java,打开,而后搜main:

果真,彻底应正了咱们的想法。

总结一下:整个hadoop程序,是一个java为主的程序,在编译是将.class文件生成在build目录,在运行时,虽然执行的是.sh文件,但一步步,最终都是在执行java命令,传入的入口,就是各个子程序的main函数入口。

 

想法1:看了这个sh命令后,又有一个想法,以前经过starg-all.sh就把整个程序启动起来了,并且是在后台运行的,输出内容只能从log文件夹内看,可否直接从命令行启动呢? 固然行,输入 bin/hadoop namenode试试,果真,启动了namenode程序,而后日志信息也直接打印在屏幕上了。

想法2:既然从hadoop这个sh文件夹内,能够看到全部的入口,那就能够整理一下,全部的入口成一个列表,方便之后找到其main函数。

命令

入口

namenode

org.apache.hadoop.hdfs.server.namenode.NameNode

secondarynamenode

org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode

datanode

org.apache.hadoop.hdfs.server.datanode.DataNode

fs / dfs

org.apache.hadoop.fs.FsShell

dfsadmin

org.apache.hadoop.hdfs.tools.DFSAdmin

mradmin

org.apache.hadoop.mapred.tools.MRAdmin

fsck

org.apache.hadoop.hdfs.tools.DFSck

balancer

org.apache.hadoop.hdfs.server.balancer.Balancer

jobtracker

org.apache.hadoop.mapred.JobTracker

tasktracker

org.apache.hadoop.mapred.TaskTracker

job

org.apache.hadoop.mapred.JobClient

queue

org.apache.hadoop.mapred.JobQueueClient

pipes

org.apache.hadoop.mapred.pipes.Submitter

version

org.apache.hadoop.util.VersionInfo

jar

org.apache.hadoop.util.RunJar

distcp

org.apache.hadoop.tools.DistCp

daemonlog

org.apache.hadoop.log.LogLevel

archive

org.apache.hadoop.tools.HadoopArchives

sampler

org.apache.hadoop.mapred.lib.InputSampler

 

至此整个目录有了一个初步的了解,接下来,那就能够顺着这些入口深刻研究了。且慢,还差个调试环境呢! 下一章来。

相关文章
相关标签/搜索