Hadoop学习心得整理(环境搭建与使用)

本文详细介绍了如何在三台虚拟机上搭建Hadoop环境,包括配置core-site.xml、hdfs-site.xml、slaves、yarn-site.xml、mapred-site.xml等文件,以及HDFS的使用。此外,还讲解了通过MyEclipse操作HDFS,MapReduce的Map和Reduce类实现,以及Job提交器的创建。最后,提到了如何打包并运行自定义的MapReduce程序。

准备环境:三台虚拟机,hadoop安装包,JDK1.8。(安装过程借鉴https://blog.csdn.net/hliq5399/article/details/78193113博客)


下载hadoop的压缩包到linux解压,进入解压目录下的etc/hadoop目录下,设置相关配置

配置core-site.xml(核心配置文件)

<configuration>
  <property>
    <name>fs.defaultFS</name>
    <value>hdfs://hadoop1:8020</value>
  </property>
  <property>
    <name>hadoop.tmp.dir</name>
    <value>/opt/modules/hadoop-2.7.7/data/tmp</value>
  </property>
</configuration>

    fs.defaultFS:设置NameNode的地址(namenode负责管理所有hdfs文件的目录)

    hadoop.tem.dir:NameNode和DataNode的实际数据存储地址(注:不是临时存储路径,是真实数据存储地址,此目录必须存在,若不存在先创建

配置hdfs-site.xml

<configuration>
  <property>
    <name>dfs.namenode.secondary.http-address</name>
    <value>hadoop3:50090</value>
  </property>
</configuration> 

     设置secondaryNameNode的地址和端口(辅助NameNode完成数据目录管理)

配置slaves

hadoop1
hadoop2
hadoop3

 指定HDFS上有哪些DataNode节点

配置yarn-site.xml(yarn:资源管理器)

<configuration>

<!-- Site specific YARN configuration properties -->
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>
    <property>
        <name>yarn.resourcemanager.hostname</name>
        <value>hadoop2</value>
    </property>
    <property>
        <name>yarn.log-aggregation-enable</name>
        <value>true</value>
    </property>
    <property>
        <name>yarn.log-aggregation.retain-seconds</name>
        <value>106800</value>
    </property>

</configuration>

    shuffle(一个框架服务,用于协调mapreduce的数据交换)

    yarn.resourcemanager.hostname:指定ResourceManager节点 

    yarn.log-aggregation-enable:配置是否启用日志聚集功能

    yarn.log-aggregation.retain-seconds:配置聚集的日志在HDFS上保存的时间

配置mapred-site.xml

<configuration>
  <property>
    <name>mapreduce.framework.name</name>
    <value>yarn</value>
  </property>
  <property>
    <name>mapreduce.jobhistory.address</name>
    <value>hadoop1:10020</value>
  </property>
  <property>
    <name>mapreduce.jobhistory.webapp.address</name>
    <value>hadoop1:19888</value>
  </property>
</configuration>

    mapreduce.framework.name:指定mapreduce程序运行在yarn上

    mapreduce.jobhistory.address:指定mapreduce的历史服务器

    mapreduce.jobhistory.webapp.address:设置历史服务器的页面和端口号


 一、HDFS(分布式文件存储系统,NameNode管理文件存放目录,DataNode保存实际文件数据)

    通过MyEclipse进行hdfs操作,在pom.xml中引入相应的包

    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-hadoop-boot</artifactId>
        <version>2.5.0.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-common</artifactId>
        <version>2.7.1</version>
    </dependency>
    <dependency>
       <groupId>org.apache.hadoop</groupId>
       <artifactId>hadoop-hdfs</artifactId>
       <version>2.7.1</version>
    </dependency>
    <dependency>
           <groupId>org.apache.hadoop</groupId>
           <artifactId>hadoop-client</artifactId>
           <version>2.7.1</version>
    </dependency>

    创建一个HdfsUtil工具类

public class HdfsUtil {
    
    private static final String hdfsPath = "hdfs://192.168.152.101:8020";
    private static final String userName = "root";
    
    
    public static Configuration getConfiguration(){
        Configuration conf = new Configuration();
        conf.set("fs.defaultFS", hdfsPath);
        return conf;
    }
    
    public static FileSystem getFileSystem() throws Exception{
        FileSystem fs = FileSystem.get(new URI(hdfsPath), getConfiguration(), userName);
        return fs;
    }
        
}

    在工具类中设置hdfs的地址和操作用户,否则默认为windows的当前用户,会报错permissiondenied

    使用时通过获取工具类的FIleSystem对象就可以进行HDFS操作

    /**
     * @param path 
     * @throws Exception
     */
    public void listPath(Path path) throws Exception{
        FileSystem fs = HdfsUtil.getFileSystem();
        FileStatus[] fileStatus = fs.listStatus(path);
        for(FileStatus files:fileStatus){
            System.out.println(">"+files.getPath());
        }
        fs.close();
    }
    
    /**
     * 
     * @param path 文件路径
     * @throws Exception
     */
    public void downLoad(Path path) throws Exception{
        FileSystem fs = HdfsUtil.getFileSystem();
        if(fs.exists(path)){
            FSDataInputStream in = fs.open(path);
            FileOutputStream out = new FileOutputStream("e:/"+path.getName());
            IOUtils.copyBytes(in, out, 1024, true);
        }else{
            System.out.println("file not exists!");
        }
    }
    
    /**
     * 
     * @param input 源文件路径
     * @param output 目标路径(包括文件名)
     * @throws Exception
     */
    public void upLoad(String input,Path output) throws Exception{
        FileSystem fs = HdfsUtil.getFileSystem();
        FileInputStream in = new FileInputStream(input);
        FSDataOutputStream out = fs.create(output);
        IOUtils.copyBytes(in, out, 1024, true);
    }

注意 :要在windows环境下进行hdfs操作,还必须在本地下载一个hadoop的资源包,并且设置HADOOP_HOME环境变量,否则报错(这是一个大坑,当初在这浪费好长时间,不知道需要在本地下载资源包)


二、MapReduce

创建自己的Map类

 /**
 * shuffle框架读取一行信息,然后给map程序,
 * map程序处理过后输出<Key,Value>键值对
 * 直接写到Context(上下文)中,由shuffle框架自动传给reduce程序进行处理
 * 
 */
public class MyMap extends Mapper<LongWritable,Text,Text,LongWritable> {
    private LongWritable one = new LongWritable(1L);
    
    @Override
    protected void map(LongWritable key, Text value,Context context) throws IOException, InterruptedException {
        
        //将获取到的行数据进行分割
        String line = value.toString();
        String[] words = line.split(" ");
        
        //生成键值对
        for (String word : words) {
            context.write(new Text(word), one);
        }
    }
}

创建自己的Reduce类 

/**
 * shuffle框架将map传来的键值对求key的hash值,然后进行模运算
 * 使得模相同的键值对都分发到同一个reduce程序中进行处理,
 * reduce再将处理后的<key,value>键值对写入到context(上下文)中
 * 由shuffle框架写入到hdfs分布式文件系统中
 * 
 */
public class MyReduce extends Reducer<Text, LongWritable, Text, LongWritable> {
    private LongWritable result = new LongWritable();
    
    @Override
    protected void reduce(Text key, Iterable<LongWritable> values,Context context) throws IOException, InterruptedException {
        Long sum = 0L;
        
        //收到的<key,value>都是相同的key,所以对values进行迭代,累积value
        for (LongWritable value : values) {
            sum +=value.get();
        }
        result.set(sum);
        //最后将统计后的数据再生成<key,value>键值对
        context.write(key, result);
    }
}

最后创建自己的Job提交器 

/**
 * Job就是一个yarn集群客户端,将自己写的MR程序打包成一个jar包,一起提交给yarn
 * 由yarn去启动程序中的master
 * 
 */
public class MyJob {

    public static void main(String[] args) throws Exception {
        //因为MapReduce程序是运行在yarn上的,所以必须设置ResourceManager节点的位置
        Configuration conf = new Configuration();
        conf.set("yarn.resourcemanager.hostname","hadoop2");

        //也可以通过自己的类设置读取源文件的方式
        
        //创建job提交器
        Job job = Job.getInstance(conf,"MyJob");
        
        //告诉客户端提交器mr程序的jar包
        job.setJarByClass(MyJob.class);
        
        //设置map和reduce的实现类
        job.setMapperClass(MyMap.class);
        job.setReducerClass(MyReduce.class);
        
        //可以手动设置reduce程序启动的数量,设置多少个reduce,hdfs中每个node节点上的数据就会被分成几份
        //job.setNumReduceTasks(3);
        
        //告诉master,程序在map和reduce阶段的输出数据类型
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(LongWritable.class);
        
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(LongWritable.class);
        
        //设置要处理的数据所在目录,以及处理后数据要保存的目录(保存的目录必须为空,否则会报错)
        FileInputFormat.setInputPaths(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));
        
        boolean res = job.waitForCompletion(true);    //true 将返回的信息打印出来
        System.exit(res?0:1);
        
    }

}

然后打包上传到linux中,通过hadoop jar命令执行

 

MRTest.jar就是我打包的自己的程序

至此,表示自己写的MapReduce程序运行成功~yeah!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值