Hadoop的伪分布式与分布式环境配置

Hadoop

【亲自测试没问题 于是分享给初学者】  

1、Hadoop简介

1、hadoop的诞生

Nutch和Lucene之父Doug Cutting在2006年完成Hadoop项目。

Hadoop并不是一个单词,它来源于DougCutting小儿子对所玩的小象玩具牙牙学语的称呼。就像是google也是由小孩子命名一样。

后又经过5年的开发,hadoop在所有云计算系统是稳居第一。

Hadoop目前使用最广泛的版本为hadoop-0.20版本。目前最新版本为hadoop-1.03

Hadoop运行在Linux系统中。在windows上安装可使用cgywin模拟linux环境。

2、hadoop的组成

hadoop Common – 是hadoop的核心,包括文件系统、远程调用RPC的序列化函数。

HDFS : 提供高吞吐量的可靠分布式文件系统是 GFS的开源实现。

Hadoop的文件系统。必须通过hadoop  fs 命令来读取。支持分布式。

MapReduce : 大型分布式数据处理模型,是Google MapReduce的开源实现。

合并/计算模型。

其他相关组成:

•    Hbase:结构化分部式数据库。BigTable的开源实现。

•    Hive:提供摘要和查询功能的数据仓库。

•    Cassandra:由Facebook开发分布式数据仓库。目前已经捐献给apache。且apache已经将Cassandra应用到了各种云计算系统中。

3、hadoop的体系结构

   NameNode  - 主节点主服务器

   SecondaryNameNode– 是辅助nameNode

   DataNode  -数据保存用的

   TackTracker – 接收任务

       JobTracker  - 分数据 -100M  Datanode1,DataNode2,DataNode3

      

l  NameNode:这是hadoop的守护进程(注意是进程JVM)。负责记录文件是如何分割成数据块,以及这些数据块分别存储到哪些数据节点上。对内存进行集中管理。NameNode在整个hadoop中只有一个。一旦NameNode服务器宕机,整个系统将无法运行。

l  DataNode:集群中的每个从服务器都运行一个DataNode后台程序。这个后台程序负责将HDFS数据块写到本地的文件系统。

l  Secondary NomeNode:用来监控HDFS状态的辅助后台程序。如保存NameNode的快照。

l  JobTracker:用户连接应用程序和hadoop。每一个hadoop集群中只一个 JobTracker,一般它运行在Master节点上。

l  TaskTracker:负责与DataNode进行结合。

4、Hadoop的市场

l  facebook

l  淘宝

l  360完全

l  京东

l  yahoo

l  google

l  暴风

 

2、Hadoop的安装

Core-site.xml:

       官方只提供linux的安装版本:

      

       目前市场上出现了一种window上的可以安装的版本。其实是将Linux与hadoop整合的产物。目的是简化hadoop的安装。此安装程序使用的是hadoop-0.20版本+cgywin:

      

      

1、hadoop的单机安装-hadoop4win的安装方法

       Hadoop的使用包括

n  安装

n  格式化NameNode

n  启动所有节点

 

       Hadoop4win的安装方法非常简单,因为它就是一个setup安装程序,只要会点下一步即可。

      

选择语言:

接收:

选择组件:

选择安装位置:

等待安装:

查看hadoop的安装细节:

安装细节:

安装细节:格式化namenode:

安装细节-测试启动所有节点:

注意下面的停止顺序:

 

Hadoop安装完成以后的目录:

hadoop4win是Linux+jdk+hadoop的安装目录。

Var是namenode格式化以后生成的目录 。即hdfs的目录。

 

 

 

 

 

 

 

进入hadoop4win:

查看hadoop的配置文件:

Hadoop-env.sh:hadoop的环境变量配置文件

 

Core-site.xml:hadoop的核心配置文件

 

Hdfs-site.xml:hadoop的文件系统配置文件

 

Mapred-site.xml:hadoop的map/reduce配置文件。

 

 

查看上面文件的配置信息,你对了解hadoop有帮助。

 

2、启动hadoop

1、直接使用hadoop的start-haoop

2、使用jsp检查java进程

       如果发现有5个java进程,则说明启动成功:

或使用ps命令:

3、单个启动与停止hadoop

       启动和停止hadoop必须要遵循节点的顺序。

       启动时按以下顺序启动:(停止时按相反的顺序停止)

       Namenode

       Datanode

       Secondarynamenode

       Jobtracker

       Tasktracker

      

       使用hadoop-daemon.sh start 启动各节点:

      

检查启动是否成功:

      

停止:

       使用hadoop-daemon.sh stop namenode停止每个节点即可

 

3、测试访问

       Hadoop启动以后,访问50030端口可以访问jobtracker。

       访问50070端口可以访问hdfs文件系统。

       http://localhost:50030 - Jobtracker

       http://localhost:50070 - hdfs

以下是50070

 

3、hdfs概念与命令

       Hdfs是hadoop Distributed file system的缩写,是hadoop的分布式文件系统。

       Hdfs由hadoop来管理,它不同于普通的文件系统,不能直观的查找文件,必须要通过hadoop命令操作hdfs。

 

       HDFS是一个主从结构的体系,一个HDFS集群是由一个名字节点,它是一个管理文件的命名空间和调节客户端访问文件的主服务器,当然还有的数据节点,一个节点一个,它来管理存储。HDFS暴露文件命名空间和允许用户数据存储成文件。

  内部机制是将一个文件分割成一个或多个的块,这些块存储在一组数据节点中。名字节点操作文件命名空间的文件或目录操作,如打开,关闭,重命名,等等。它同时确定块与数据节点的映射。数据节点来负责来自文件系统客户的读写请求。

  数据节点同时还要执行块的创建,删除,和来自名字节点的块复制指示。

  名字节点和数据节点都是软件运行在普通的机器之上,机器典型的都是linux,HDFS是用java来写的,任何支持java的机器都可以运行名字节点或数据节点,利用java语言的超轻便型,很容易将HDFS部署到大范围的机器上。典型的部署时将有一个专门的机器来运行名字节点软件,机群中的其他机器运行一个数据节点实例。体系结构排斥在一个机器上运行多个数据节点的实例,但是实际的部署不会有这种情况。

集群中只有一个名字节点极大地简单化了系统的体系。名字节点是仲裁者和所有HDFS的元数据的仓库。系统设计成用户的实际数据不经过名字节点。

1、hadoop下的文件操作命令

1 :列出hdfs文件

~# hadoop dfs –ls /

~# hadoop fs –ls /

 

2:将文件上传到hdfs

以下命令,将本地目录下的a.txt上传到hdfs下的wj目录下,并重命名为b.txt

Hadoop fs –put a.txt /wj/b.txt

 

也可以使用copyFromLocal命令将本目录下的文件上传到hdfs文件系统中:

 

3:将hdfs中的文件复制到本地系统中

通过get命令,即可以操作文件也可以操作文件夹:

操作一个文件,将hdfs上的文件/wj/a.txt保存到本地,并取名为b.txt

以下下载整个文件到当前目录下来,注意最后的一个点

 

4:删除hdsf下的某个文档

 

5:其他更多操作,可以通过查帮助获取

 

 

2、MapReduce 范例操作-测试字符统计

先向服务器上传一文件:

执行统计:

root@linux:/home/wangjian#hadoop fs -copyFromLocal a.txt /wj/a.txt

root@linux:/home/wangjian#cd /opt/hadoop-0.20.2/

root@linux:/opt/hadoop-0.20.2#hadoop jar hadoop-0.20.2-examples.jar wordcount /wj/a.txt /wj/result2

4、查看结果:

默认情况下结果文件名为:/wj/result2/part-0000

 

root@linux:/opt/hadoop-0.20.2#hadoop fs -cat /wj/result2/part*

 

 

4、Java操作hdfs示例

1、配置Eclipse的插件

       (非分布式,支持本地)

       在eclipse3.6中安装map/redurce插件:

 

选择map/red视图:

 

选择添加新地址:

 

输入以下信息:

 

配置成功后显示在HDFSLocation显示以下信息:

左图显示的都是服务器的hdsf文件系统。可以方便的进行上传和下载。

 

 

2、Java代码

书写代码之前,必须要建立一个新的map/red项目:

1、上传本地文件到HDFS

创建一个Java源代码类:

输入以下代码:(图)

源代码如下:

packagecn.itcast.one;

importorg.apache.hadoop.conf.Configuration;

importorg.apache.hadoop.fs.FileStatus;

importorg.apache.hadoop.fs.FileSystem;

importorg.apache.hadoop.fs.Path;

/**

 * 上传本地文件到hdfs

 */

public class One{

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

              Configuration conf =

                     new Configuration();

              FileSystem hdfs = FileSystem.get(conf);

              Path src = new Path("c:/a.txt");//本地文件

              Path dst = newPath("/wj");//hdfs文件

              hdfs.copyFromLocalFile(src, dst);

              System.err.println("文件上传成功至:"+conf.get("fs.default.name"));

              //列出服务器上目前拥有的文件

              FileStatus[] fs =hdfs.listStatus(dst);

              for(FileStatus f:fs){

                     System.err.println(f.getPath());

              }

       }

}

 

使用map/red运行map方法:

运行完成以后,应该可以/wj/目录下发现一个新的文本文件:

 

2、创建HDFS文件

通过FileSystem.create(Pathf)可以在HDFS上创建文件,其中f为文件的完整路径:

注意是文件,而不是文件夹。

以下是源代码:

packagecn.itcast.one;

importorg.apache.hadoop.conf.Configuration;

importorg.apache.hadoop.fs.FSDataOutputStream;

importorg.apache.hadoop.fs.FileSystem;

importorg.apache.hadoop.fs.Path;

public classCreatePath {

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

              Configuration conf =

                     new Configuration();

              FileSystem fs = FileSystem.get(conf);

              //在HDSF上创建一个文件

              FSDataOutputStreamout=fs.create(new Path("/wj/c.txt"));

              //写入一行数据,必须使用UTF-8

              out.writeUTF("Hell使用UTF-8");

              out.close();

       }

}

 

3、重命名HDFS文件

 

4、删除hdfs文件

       通过FileSystem.delete(Path f,Booleanrecursive)可以删除指定的HDSF文件,其中f 为完整的路径,cecursive用来确定是否进行递归删除:

5、查看hdfs最后修改时间

FileSystem.getModificationTime()可以查看HDFS文件的最后修改时间。

 

6、查看某个HDFS文件是否存在

       FileSystem.exists(Pathf)可以查看某个HDFS文件是否存在。

7、查找某个文件在HDFS集群中的位置

       FileSystem.getFileBlockLocations(FileStatusfile,long start,long len)要查找指定文件在HDFS集群上的位置:

packagecn.itcast.one;

importorg.apache.hadoop.conf.Configuration;

importorg.apache.hadoop.fs.BlockLocation;

importorg.apache.hadoop.fs.FileStatus;

importorg.apache.hadoop.fs.FileSystem;

importorg.apache.hadoop.fs.Path;

public classFindFile {

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

              Configuration conf =

                     new Configuration();

              FileSystem fs =FileSystem.get(conf);

              //必须是一个具体的文件

              Path path = newPath("/wj/a.txt");

              //文件状态

              FileStatus fileStatus =fs.getFileStatus(path);

              //文件块

              BlockLocation[] blockLocations=

                     fs.getFileBlockLocations(fileStatus,0,fileStatus.getLen());

              int blockLen =blockLocations.length;

              System.err.println(blockLen);

              for(int i=0;i<blockLen;i++){

                     //主机名

                     String[] hosts =blockLocations[i].getHosts();

                     for(String host:hosts){

                            System.err.println(host);

                     }

              }

       }

}

 

8、获取 HDFS集群上所有节点名称

       通过DatanodeInfo.getHostName()可以获取HDFS集群上的所有节点名称:

packagecn.itcast.one;

importorg.apache.hadoop.conf.Configuration;

importorg.apache.hadoop.fs.FileSystem;

importorg.apache.hadoop.hdfs.DistributedFileSystem;

importorg.apache.hadoop.hdfs.protocol.DatanodeInfo;

/**

 * 获取所有主机节点

 */

public class GetNodes{

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

              Configuration conf =

                     new Configuration();

              FileSystem fs =FileSystem.get(conf);

              //强转成分布式文件对象

              DistributedFileSystem hdfs =

                     (DistributedFileSystem) fs;

              //获取节点信息-数组

              DatanodeInfo[] dis =hdfs.getDataNodeStats();

              for(DatanodeInfo info : dis){

                     String name =info.getHostName();

                     System.err.println(name);

              }

       }

}

 

 

 

Configuration

FileSystem

 

Mapper

Redurcer

 

 

3、Map/red的java代码-wordcount

其实WordCount并不难,只是一下子接触到了很多的API,有一些陌生,还有就是很传统的开发相比,map-reduce确实是一种新的编程理 念,为了让各位新手少走弯路,我将WordCount中的很多API都做了注释,其实这些方法搞明白了以后程序就很简单了,无非就是将一句话分词,先用 map处理再用reduce处理,最后再main函数中设置一些信息,然后run(),程序就结束了。好了,不废话,直接上代码:

 

       主要的几个核心类说明:

l Mapper<T,T,T,T>- 用于mapper分组处理数据

它可以设置的泛型包括:

n Text :hadoop的Text对应java.lang.String类型

n IntWritable :对应的为Integer类型。

n LongWritable :对应的为Long类型。

 

l Reducer类用于对mapper以后结果进行合并处理:

 

1、以下自己实现的wordcount代码:

以下是完整源代码:

packagecn.itcast.count;

importjava.io.IOException;

importjava.util.StringTokenizer;

import org.apache.hadoop.conf.Configuration;

import org.apache.hadoop.fs.Path;

import org.apache.hadoop.io.IntWritable;

import org.apache.hadoop.io.Text;

import org.apache.hadoop.mapreduce.Job;

import org.apache.hadoop.mapreduce.Mapper;

import org.apache.hadoop.mapreduce.Reducer;

importorg.apache.hadoop.mapreduce.lib.input.FileInputFormat;

importorg.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

public class MyWordCount {

       //Mapper<KEYIN,VALUEIN, KEYOUT, VALUEOUT>//参数说明

       publicstatic class MyMapper extends Mapper<Object,Text,Text, IntWritable>{

              privatefinal static IntWritable one = new IntWritable(1);//类似于int类型

              privateText word = new Text();                         //可以理解成String类型

              publicvoid map(Object key, Text value, Context context)

                                      throws IOException ,InterruptedException {

                     System.err.println(key+","+value);

                     //默认情况下即根据空格分隔字符串

                     StringTokenizeritr = new StringTokenizer(value.toString());

                     while(itr.hasMoreTokens()){

                            word.set(itr.nextToken());

                            context.write(word,one);

                     }

              };

       }

       //Reducer<KEYIN,VALUEIN, KEYOUT, VALUEOUT>

       publicstatic class MyReducer

                                    extends Reducer<Text,IntWritable,Text, IntWritable>{

              privateIntWritable result = new IntWritable();

              protectedvoid reduce(Text key, Iterable<IntWritable> values,

                                                                      Contextcontext)

                                                   throws IOException ,InterruptedException {

                     System.err.println(key+","+values);

                     intsum=0;

                     for(IntWritableval:values){

                            sum+=val.get();

                     }

                     result.set(sum);

                     context.write(key,result);//这是最后结果

              };

       }

       publicstatic void main(String[] args) throws Exception {

              //声明配置信息

              Configurationconf = new Configuration();

              //声明Job

              Jobjob = new Job(conf,"Word Count");

              //设置工作类

              job.setJarByClass(MyWordCount.class);

              //设置mapper类

              job.setMapperClass(MyMapper.class);

              //可选

              job.setCombinerClass(MyReducer.class);

              //设置合并计算类

              job.setReducerClass(MyReducer.class);

              //设置key为String类型

              job.setOutputKeyClass(Text.class);

              //设置value为int类型

              job.setOutputValueClass(IntWritable.class);

              //设置或是接收输入输出

              FileInputFormat.setInputPaths(job,newPath("/wj/b.txt"));

              FileOutputFormat.setOutputPath(job,newPath("/wj/out5"));

              //执行

              System.exit(job.waitForCompletion(true)?0:1);

       }

}

 

2、用Eclipse运行的结果

3、将文件打成jar包用hadoop jar命令运行的结果

 

4、在Eclipse中运行时出现的问题解决方案

Cannot run program “chmod”: CreateProcesserror=2

这个是说,不能执行chmod这个命令。

解决方案非常简单。

1:关闭Eclipse。

2:将cgywin\bin加入到windows的path环境变量中。

3:启动eclipse再用hadoop运行即可。

 

5、在Linux上安装hadoop

在Linux中安装hadoop包括在独立的linux系统中安装hadoop和在linux虚拟机下安装hadoop。我本人使用后面的方式安装。即在虚拟机上先安装linux,然后再将hadoop安装到linux下。

1、安装VirtualBox VM虚拟机

(执行setup.exe安装即可)

2、在Vbox中安装Linux系统

(略,相信大家都应该会)

 

3、设置linux与windows的共享目录

1、在没有插入网线的情况下选择网络模式为:HostOnly

2、选择共享目录:

3、挂载

Linux系统的/mnt目录是挂载其他共享目录的位置:

执行以下命令:

在linux上创建一个挂载目录

挂载:挂载成功以后显示不同的颜色:

 

4、安装ssh

       Hadoop运行过程需要管理远程hadoop守护进程。

       1、inux上安装ssh使用以下命令:在网络情况下执行一命令即可以安装

       ~# sudo apt-get install ssh

如果是在非网络情况下,则需要.deb或是.gz的安装包:

(关于如果安装deb包,请参考ubuntu.doc)

2、设置ssh无密码登录

~# ssh-keygen

输入上面的命令后一路回车即可。

       3、拷贝生成的密码文件,默认生成的密码文件在用户名目录下的.ssh目录下

       ~# cd ~/.ssh

    ~# cat id_rsa.pub authorized_keys

       4、测试是否可以无密码登录

       ~# ssh localhost

       ~# who

       一般情况下,第一次登录会给出一个错误提示,退出后再次登录即可。

配置好ssh以后,建议使用xshell远程操作linux这样更加方便。

       5、启动以后输入以下命令登录:

      

5、安装hadoop

1、进入目录,将hadoop-0.20.2.tar.gz拷贝到/opt的根目录下去:

2、进入/opt目录安装hadoop

~tar –zxf       hadoop-0.20.2.tag.gz

安装成功后多了一个hadoop-0.20.2目录:

3、设置linux环境变量

配置文件:/etc/profile

使用vim进行编辑:

~# vim        /etc/profile

 

在最后面的部分追加hadoop的bin目录:

可以直接拷贝下面的配置,要根据具体情况做出修改:

exportJAVA_HOME=/usr/local/java/jdk1.7.0_02

exportJRE_HOME=/usr/local/java/jdk1.7.0_02/jre

exportCLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH

exportPATH=$JAVA_HOME/bin:$JRE_HOME/bin:$JAVA_HOME:$PATH

exportPATH=/opt/hadoop-0.20.2/bin:$PATH

 

4、配置完成以后,关闭窗口再将打开一个新的窗口,建议使用xshell进行操作,

输入hadoop:

如果给出以下提示,说明配置成功:

 

6、配置hadoop

1、修改$hadoop_home/conf/core-site.xml

使用vim打开编辑:

<configuration>

<property>

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

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

</property>

<property>

       <name>hadoop.tmp.dir</name>

       <value>/var/hadoop/hadoop-${user.name}</value>

</property>

</configuration>

编辑完成后,使用:wq保存退出。

 

2、修改$hadoop_home/conf/hdfs.site.xml

<configuration>

<property>

       <name>dfs.replication</name>

        <value>1</value>

</property>

</configuration>

 

               

3、修改mepred-site.xml配置文件:

 mapred.child.tmp可以是其他目录。

<configuration>

       <property>

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

              <value>localhost:9001</value>

       </property>

       <property>

              <name>mapred.child.tmp</name>

              <value>/opt/temp</value>

       </property>

</configuration>

7、启动hadoop

 

1、在启动hadoop之前必须要先格式化namenode

输入:

root@linux:/opt/hadoop-0.20.2/bin#hadoop namenode -format

2、使用start-all.sh一次全部启动

在linux环境下,使用start-all.sh可以一次全部启动所有的节点,这一点优于在cygwin环境下。可见hadoop确实适合在linux环境下运行:

执行以下命令:

root@linux:/opt/hadoop-0.20.2/bin#start-all.sh

查看是否都启动成功,使用jps命令:

root@linux:/opt/hadoop-0.20.2/bin#jps

如果5个节点都启动成功,则可以正常访问了。

3、测试字符统计

先向服务器上传一文件:

执行统计:

root@linux:/home/wangjian#hadoop fs -copyFromLocal a.txt /wj/a.txt

root@linux:/home/wangjian#cd /opt/hadoop-0.20.2/

root@linux:/opt/hadoop-0.20.2#hadoop jar hadoop-0.20.2-examples.jar wordcount /wj/a.txt /wj/result2

4、查看结果:

默认情况下结果文件名为:/wj/result2/part-0000

 

root@linux:/opt/hadoop-0.20.2#hadoop fs -cat /wj/result2/part*

8、停止hadoop

root@linux:/opt/hadoop-0.20.2#stop-all.sh

9、逐个启动节点

启动节点按以下顺序进行:

Hadoop-daemon.sh负责单个启动hadoop的节点:

root@linux:/opt/hadoop-0.20.2# hadoop-daemon.sh start namenode

starting namenode, logging to /opt/hadoop-0.20.2/bin/../logs/hadoop-root-namenode-linux.out

root@linux:/opt/hadoop-0.20.2#hadoop-daemon.sh start datanode

starting datanode, logging to /opt/hadoop-0.20.2/bin/../logs/hadoop-root-datanode-linux.out

root@linux:/opt/hadoop-0.20.2#hadoop-daemon.sh start secondarynamenode

starting secondarynamenode, logging to/opt/hadoop-0.20.2/bin/../logs/hadoop-root-secondarynamenode-linux.out

root@linux:/opt/hadoop-0.20.2#hadoop-daemon.sh start jobtracker

starting jobtracker, logging to/opt/hadoop-0.20.2/bin/../logs/hadoop-root-jobtracker-linux.out

root@linux:/opt/hadoop-0.20.2#hadoop-daemon.sh start tasktracker

starting tasktracker, logging to/opt/hadoop-0.20.2/bin/../logs/hadoop-root-tasktracker-linux.out

 

 

启动时参数为start即:

Hadoop-daemon.sh start namenode

关闭时参数为stop:

Hadoop-daemon.sh stop namenode

 

(安装好以后,在Eclipse中写好代码,将打好的jar文件,放到hadoop的主服务器上,执行。)

 

 

6、两个示例

1、单词计数:

~# hadoop jar hadoop-example-0.20.2.jar  wordcount  /data/word.txt  /data/out1

2、对一亿个uuid进行排序

~# hadoop jar contrib/streamming/hadoop-0.20.2-streamming.jar  -mapper ‘cat’ –reducer  ‘wc -l’

-input /data/bigdata.txt  -output   /data/out2

 

                                                                                                                                                   杨文华

                                                                                                                                                  wallsky@sina.cn

                                                                                                                                                  18024582664

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

经纬方略

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值