Hadoop有几个组件:



===========================



NameNode



Hadoop 在分布式计算与存储中都采用 主/从结构。分布式存储被称为 HDFS.



NameNode 位于 HDFS 的主机端,它指导从机端的DateNode 执行底层的数据传输.



NameNode跟踪文件如何被划分,以及这些划分后的块分别存在哪些节点上.



这些工作会水泵大量的内存和I/O.



DateNode



集群中,每个从节点都会驻留一个 DataNode进程,来执行分布式文件系统的工作,将HDFS数据块写到本地文件系统的实际文件中。当要对HDFS的文件进行读写时,文件被分割成多个块,由NameNode 告诉客户端每个数据块在哪个 DataNode 上.客户端直接与 DataNode 进程通信. 然后 DataNode再与其它的 DataNode 通信,复制这些数据块,冗余保存,来实现备份.



SecondaryNameNode



SSN 用来监测HDFS状态的辅助进程。每个集群里都有一个SNN,它和NameNode 不同的是,它不接收或记录HDFS的任何实时变化。它只和 NameNode通信,根据配置文件里设定的时间间隔获取HDFS数据快照.



JobTracker



应用程序和 Hadoop之间的纽带.一旦代码提交到集群上,JobTracker就会确定执行计划,包括决定处理哪些文件,为不同的任务分配节点以及监控所有的任务运行。如果任务失败,它会自动重启任务,但分配的节点可能会不同。重试次数是可配置的。



TaskTracker



JobTracker是主节点,监测作业的执行过程。TaskTracker 管理各个任务在各节点上的执行情况。



TaskTracker 负责执行 JobTracker分配的单个任务。虽然每个从节点上公有一个 TaskTracker, 但每个 TaskTracker 可以生成多个 JVM来并行地处理许多的 map 或 reduce 任务。



TaskTracker 还要持续不断地和 JobTracker通信。如果 JobTracker 在指定时间内没有收到 TaskTracker的回复,则判断它已经崩溃,则会重新安排任务到其它节点。




hadoop工作有三种模式:





单机模式



===========================



只在一台机器上运行.可以用来学习,调试之用。



安装完后,在 conf目录下可以看到有一些配置文件。其中有:





core-site.xml



mapred-site.xml



hdfs-site.xml



masters



slaves





刚安装完后,该三个文件都是空的。





伪分布模式



===========================



要在一台机器上模拟集群进行功能的调试,我们可以进行如下配置:





core-site.xml



--------------------------------------------------------



<?xmlversion="1.0"?>



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





<!-- Putsite-specific property overrides in this file.-->



<configuration>



<property>



<name>fs.default.name</name>



<value>hdfs://localhost:9000</value>



<description>文件系统NameNode</description>



</property>



</configuration>





mapred-site.xml



--------------------------------------------------------



<?xmlversion="1.0"?>



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





<!-- Putsite-specific property overrides in this file.-->





<configuration>



<property>



<name>mapred.job.tracker</name>



<value>hdfs://localhost:9001</value>



<description>任务分配相关</description>



</property>



</configuration>





hdfs-site.xml



--------------------------------------------------------



<?xmlversion="1.0"?>



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





<!-- Putsite-specific property overrides in this file.-->





<configuration>



<property>



<name>dfs.replication</name>



<value>1</value>



<description>默认副本数</description>



</property>



</configuration>





masters



--------------------------------------------------------



localhost





slaves



--------------------------------------------------------



localhost





因为是单机调试,所以,所有进程都运行在同一节点上,但进程之间还是和在集群中一样,通过SSH进行通信。所以,这里需要能通过SSH不输密码直接登录到localhost 上。





格式化HDFS:



[root@localhost hadoop]# bin/hadoopnamenode -format





装载守护进程:



[root@localhost hadoop]#bin/start-all.sh





验证是否成功启动:



[root@localhost hadoop]# jps



13673 NameNode



13792 DataNode



14037 JobTracker



14281 Jps



13940 SecondaryNameNode



14165 TaskTracker





关闭所有的进程可以通过:








全分布模式



===========================



配置一个真实的集群环境:



还是从配置文件着手:





core-site.xml



--------------------------------------------------------



<?xmlversion="1.0"?>



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





<!-- Putsite-specific property overrides in this file.-->



<configuration>



<property>



<name>fs.default.name</name>



<value>hdfs://master:9000</value>



<description>文件系统NameNode</description>



</property>



</configuration>





mapred-site.xml



--------------------------------------------------------



<?xmlversion="1.0"?>



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





<!-- Putsite-specific property overrides in this file.-->





<configuration>



<property>



<name>mapred.job.tracker</name>



<value>master:9001</value>



<description>任务分配相关</description>



</property>



</configuration>





hdfs-site.xml



--------------------------------------------------------



<?xmlversion="1.0"?>



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





<!-- Putsite-specific property overrides in this file.-->





<configuration>



<property>



<name>dfs.replication</name>



<value>3</value>



<description>默认副本数</description>



</property>



</configuration>





masters



--------------------------------------------------------



backup





slaves



--------------------------------------------------------



hadoop1



hadoop2



hadoop3





把上面这些配置文件复制到集群上所有的节点,然后每个节点都要格式化HDFS,以准备好存储数据



[root@localhost hadoop]# bin/hadoopnamenode -format



然后分别启动:



[root@localhost hadoop]#bin/start-all.sh





安装完成后,hadoop 提供一些用于监控的页面。



NameNode 通过 50070提供报告,描绘HDFS的状态。



如:http://ip:50070/





而 JobTracker 是通过 50030 提供监控的:



http://ip:50030/





HDFS:



===========================



专为 MapReduce之类框架的大规则颁布式数据处理而设计的。它可以把一个大数据集(可能有 100TB)在 HDFS中存储为单个文件。而其它的文件系统是不可能的。而且,HDFS 提供的是冗余的存储,也就是可以保证了数据的高可用性。由于 HDFS不是天生的 Unix 文件系统,所以不用使用 ls, cp 这种标准的 Unix 文件命令。也不支持如 fopen(),fread() 这样的标准文件读写操作。Hadoop 提供了一套自己的命令行工具.格式是: hadoop fs-cmd<args>



如:



1.添加文件和目录



[root@localhost bin]# ./hadoop fs-mkdir /home/hdfs



[root@localhost bin]# ./hadoop fs-ls /home/



Found 1 items



-root supergroup           02013-08-15 12:56 /home/hdfs





要注意的是,这时直接用 Unix 命令 ls 是无法看到/home/hdfs 的。因为前面也说了 HDFS 不是标准的 Unix 文件系统。





想看所有的子目录:



[root@localhost bin]# ./hadoop fs-lsr /



-root supergroup           02013-08-15 12:56 /home



-root supergroup           02013-08-15 12:56 /home/hdfs





从本地文件系统创建一个名为 test.txt 的文本文件,然后将它放到HDFS中。



[root@localhost bin]# touchtest.txt



[root@localhost bin]# ./hadoop fs-put test.txt .



前一个参数是存放在本地的路径,后一个参数是要存放到 HDFS 中的文件路径。 .表示当前目录。






[root@localhost bin]# ./hadoop fs-lsr /



-root supergroup           02013-08-15 12:56 /home



-root supergroup           02013-08-15 13:02 /home/hdfs



1root supergroup           02013-08-15 13:02 /home/hdfs/test.txt





2.查看文件



上面使用 put 命令,将本地文件系统中的文件放到 HDFS中。



get 命令和 put 相反,是将 HDFS中的文件复制到本地文件系统。



前一个参数是 HDFS 中的文件路径,后一个参数是存放到本地的路径。 . 表示本地文件系统的当前目录。



[root@localhost bin]# ./hadoop fs-get /home/hdfs/test.txt .





3.删除文件



[root@localhost bin]# ./hadoop fs-rm /home/hdfs/test.txt



Deletedhdfs://localhost:9000/home/hdfs/test.txt





4.删除目录



[root@localhost bin]# ./hadoop fs -rmr /home/hdfs



Deleted hdfs://localhost:9000/home/hdfs





合并日志文件案例:



************************



常用的使用方式是使用 hadoop 来进行日志分析。虽然我们可以将各个小日志都复制到 HDFS中,但通常,需要将小文件合并成一大巨大的文件(TB)。一种是先在本地文件系统中合并,然后再放入HDFS,这种办法会很消耗本地磁盘空间,比如现在有10TB 的分散日志文件,在本地合并时,起码还需要额外的 10TB空间来存储合并后的文件。还有一种是在往HDFS复制的过程中合并。由于 HDFS没有直接的命令行实现该功能,所以需要用它的API通过其它方式组合实现了。JAVA的实现方式:





import java.io.IOException;





import org.apache.hadoop.conf.Configuration;



import org.apache.hadoop.fs.FSDataInputStream;



import org.apache.hadoop.fs.FSDataOutputStream;



import org.apache.hadoop.fs.FileStatus;



import org.apache.hadoop.fs.FileSystem;



import org.apache.hadoop.fs.Path;





public class PutMerge {



public static void main(String[] args) throws IOException{



Configuration conf = new Configuration();



FileSystem hdfs = FileSystem.get(conf);



FileSystem local = FileSystem.getLocal(conf);





Path inputDir = new Path(args[0]);



Path hdfsFile = new Path(args[1]);





FileStatus[] inputFiles = local.listStatus(inputDir);



FSDataOutputStream out = hdfs.create(hdfsFile);





for (int i = 0; i < inputFiles.length; i++){



System.out.println(inputFiles[i].getPath().getName());



FSDataInputStream in =local.open(inputFiles[i].getPath());



byte buffer[] = new byte[256];



int bytesRead = 0;



while ((bytesRead = in.read(buffer)) > 0){



out.write(buffer, 0, bytesRead);



}



in.close();



}



out.close();





}



}





编译:



javac -classpath /home/hadoop/hadoop-core-1.2.0.jar -dputmerge/classes putmerge/src/PutMerge.java



打包 JAR:



[root@localhost sunyutest]# jar -cvf putmerge/putmerge.jar -Cputmerge/classes/ .



added manifest



adding: PutMerge.class(in = 1732) (out= 870)(deflated49%)



运行JAR:



[root@localhost putmerge]# /home/hadoop/bin/./hadoop jarputmerge.jar PutMerge /home/wwwlogs/ ./putmerg.txt



cars.txt



run.easymobi.cn.log



nginx_error.log



moniter.easymobi.cn.log



access.log





看结果:



[root@localhost putmerge]# /home/hadoop/bin/./hadoop fs -lsr/



- root supergroup          0 2013-08-15 12:56 /home



- root supergroup          0 2013-08-15 14:21/home/hdfs



1 root supergroup 





复制到本地系统中:



[root@localhost putmerge]# /home/hadoop/bin/./hadoop fs -getputmerg.txt .



查看当前目录:



[root@localhost putmerge]# ls -l



total 88896



  4096 Aug 15 14:12 classes



  1331 Aug 15 14:14 putmerge.jar



-rw-r--r--. 1 root root 91014095 Aug 15 14:45putmerg.txt



  4096 Aug 15 14:10 src