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

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


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

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


 
    fs.defaultFS
    hdfs://hadoop1:8020
 

 
    hadoop.tmp.dir
    /opt/modules/hadoop-2.7.7/data/tmp
 

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

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

配置hdfs-site.xml


 
    dfs.namenode.secondary.http-address
    hadoop3:50090
 

 

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

配置slaves

hadoop1
hadoop2
hadoop3

 指定HDFS上有哪些DataNode节点

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


   
        yarn.nodemanager.aux-services
        mapreduce_shuffle
   

   
        yarn.resourcemanager.hostname
        hadoop2
   

   
        yarn.log-aggregation-enable
        true
   

   
        yarn.log-aggregation.retain-seconds
        106800
   

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

    yarn.resourcemanager.hostname:指定ResourceManager节点 

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

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

配置mapred-site.xml


 
    mapreduce.framework.name
    yarn
 

 
    mapreduce.jobhistory.address
    hadoop1:10020
 

 
    mapreduce.jobhistory.webapp.address
    hadoop1:19888
 

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

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

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


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

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

   
        org.springframework.data
        spring-data-hadoop-boot
        2.5.0.RELEASE
   

   
        org.apache.hadoop
        hadoop-common
        2.7.1
   

    
       org.apache.hadoop
       hadoop-hdfs
       2.7.1
    

    
           org.apache.hadoop
           hadoop-client
           2.7.1
    

    创建一个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程序处理过后输出键值对
 * 直接写到Context(上下文)中,由shuffle框架自动传给reduce程序进行处理
 * 
 */
public class MyMap extends Mapper {
    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再将处理后的键值对写入到context(上下文)中
 * 由shuffle框架写入到hdfs分布式文件系统中
 * 
 */
public class MyReduce extends Reducer {
    private LongWritable result = new LongWritable();
    
    @Override
    protected void reduce(Text key, Iterable values,Context context) throws IOException, InterruptedException {
        Long sum = 0L;
        
        //收到的都是相同的key,所以对values进行迭代,累积value
        for (LongWritable value : values) {
            sum +=value.get();
        }
        result.set(sum);
        //最后将统计后的数据再生成键值对
        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就是我打包的自己的程序

Hadoop学习心得整理(环境搭建与使用)_第1张图片

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

你可能感兴趣的:(学习)