大数据实训第六天笔记

构建适配于Windows系统的Hadoop环境

在Windows中编写自定义的Mapreduce,如果需要测试代码,则需要在Windows中构建Hadoop环境
首先将Hadoop文件复制一份,在其中将shera目录删掉,该目录包含了Hadoop所有的对外网页服务内容,但是在测试代码的Hadoop中不需要这一部分,删除后可以加快从虚拟机导出的过程
在这里插入图片描述
从虚拟机中将处理好的Hadoop文件下载出来
在这里插入图片描述
在其中的bin目录下,添加一系列Hadoop的Windows的本地化依赖
在这里插入图片描述
同时在系统目录C:\Windows\System32下将Hadoop的依赖也进行添加
在这里插入图片描述
前往Windows的环境变量配置下,添加HADOOP_HOME
在这里插入图片描述
在cmd命令行中输入hadoop,如上述操作配置成功,则会有以下命令行
在这里插入图片描述
回到Hadoop文件夹的bin目录下,点击winutils.exe文件。
如cmd窗口一闪而过而没有提示报错信息,则Hadoop的Windows环境配置成功
在这里插入图片描述


通过java代码操作HDFS

在idea中配置一个空的maven项目
在这里插入图片描述
添加maven的项目配置

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.example</groupId>
  <artifactId>hadoop_study1</artifactId>
  <version>1.0-SNAPSHOT</version>
  <name>Archetype - hadoop_study1</name>
  <url>http://maven.apache.org</url>
  <properties/>
          <dependencies>
            <dependency>
              <groupId>junit</groupId>
              <artifactId>junit</artifactId>
              <version>4.13.2</version>
            </dependency>
            <dependency>
              <groupId>org.apache.hadoop</groupId>
              <artifactId>hadoop-common</artifactId>
              <version>3.1.3</version>
            </dependency>
            <dependency>
              <groupId>org.apache.hadoop</groupId>
              <artifactId>hadoop-hdfs</artifactId>
              <version>3.1.3</version>
            </dependency>
            <dependency>
              <groupId>org.apache.hadoop</groupId>
              <artifactId>hadoop-client</artifactId>
              <version>3.1.3</version>
            </dependency>
          </dependencies>
</project>

java通过hdfs的api进行的各种操作

package org.hadoop;


import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.io.IOUtils;
import org.apache.kerby.xdr.util.IOUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

//使用hdfs的java api操作hdfs
public class HdfsApiTest {
    //文件系统对象
    FileSystem fileSystem=null;


//    初始化文件系统
    @Before
    public void init() throws URISyntaxException, IOException, InterruptedException {

        //创建配置对象
        Configuration conf = new Configuration();

        //指定hdfs中的namenode地址
        URI uri = new URI("hdfs://bigdata04:8020");

        //用户名称
        String username="root";

        //创建文件对象
        fileSystem =FileSystem.get(uri,conf,username);

        System.out.println("hdfs文件系统对象已经初始化完成");
    }

    @Test
    //创建hdfs的路径
    public void createPath() throws IOException {

        Path path=new Path("/hdfs_api");
        boolean result= fileSystem.mkdirs(path);


        System.out.println(result ? "创建目录成功":"创建目录失败");

    }
    @Test
    //删除hdfs上的路径
    public void deletePath() throws IOException {

        //要删除的路径
        Path path=new Path("/my_jps.sh");
        //是否递归删除
        boolean recursive=false;

        //判断要删除的目录是否存在

        if(fileSystem.exists(path)){
            boolean result= fileSystem.delete(path,recursive);
            System.out.println(result ? "目标文件或文件夹已删除":"目标文件删除失败");

        }else {
            System.out.println("目标文件不存在");
        }



    }

    @Test
    //在hdfs上创建文件,并写入指定的内容
    public void createFile() throws IOException {
        //创建要指定的文件名
        Path path=new Path("/api_file.txt");

        FSDataOutputStream fsDataOutputStream=fileSystem.create(path);

        //要输出到文件的内容
        String line="今天是周二";

        fsDataOutputStream.write(line.getBytes());

        //手动刷新
        fsDataOutputStream.flush();

        //关闭流
        fsDataOutputStream.close();
    }

    @Test
    //对hdfs上的文件进行目录调整与名称修改
    public void moveFile() throws IOException {

        //文件源路径
        Path src=new Path("/api_file.txt");

        //文件新路径
        Path dest=new Path("/hdfs_api/api_file_new.txt");

        boolean result= fileSystem.rename(src,dest);
        System.out.println(result ? "目标文件或文件夹已修改":"目标文件修改失败");
    }

    @Test
    //读取hdfs上的文件内容
    public void renameFile() throws IOException {
        //hdfs上的文件源路径
        Path src=new Path("/hdfs_api/api_file_new.txt");

        FSDataInputStream fsDataInputStream=fileSystem.open(src);

        IOUtils.copyBytes(fsDataInputStream,System.out,2048,false);
    }

    @Test
    //从本地上传文件到hdfs上
    public void uploadFile() throws IOException {

        //本地上传的文件路径
        Path src=new Path("E:\\TencentFile\\beijingTime.txt");

        //文件上传到hdfs上的路径
        Path dest=new Path("/hdfs_api/");

        //文件上传成功后是否删除本地的文件

        boolean delSrc=true;

        fileSystem.copyFromLocalFile(delSrc,src,dest);

    }

    @Test
    public void downloadFile() throws IOException {
        //文件在hdfs上的路径
        Path src=new Path("/hdfs_api/api_file_new.txt");
        //文件下载到本地的路径
        Path dest=new Path("E:\\TencentFile\\");

        //文件下载后 是否删除hdfs上的源文件
        boolean delSrc=false;

        //是否使用本地文件模式
        boolean useLocal=false;


        fileSystem.copyToLocalFile(delSrc,src,dest,useLocal);
    }

    @Test
    //查询hdfs上的元数据
    public void queryFile() throws IOException {
        //设置查询起始路径
        Path src=new Path("/");

        //设置是否递归
        boolean recursive=true;

        RemoteIterator<LocatedFileStatus> listFiles=fileSystem.listFiles(src,recursive);

        //进行迭代
        while(listFiles.hasNext()){

            //获取元素
            LocatedFileStatus fileStatus=listFiles.next();

            //获取文件路径
            System.out.println(fileStatus.getPath());

            //获取文件权限
            System.out.println(fileStatus.getPermission());

            //获取文件所属用户
            System.out.println(fileStatus.getOwner());

            //获取文件所属用户组
            System.out.println(fileStatus.getGroup());

            //获取文件副本数
            System.out.println(fileStatus.getReplication());

            //获取文件的block size
            long bilocksize=fileStatus.getBlockSize();
            System.out.println(bilocksize/1024/1024+"MB");

            System.out.println("--------------------");

            System.out.println();
        }

    }

    @After
    public  void close() throws IOException {
        if(fileSystem!=null){
            fileSystem.close();
        }

    }
}

运行结果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


编写Mapreduce

创建一个空的maven项目
在这里插入图片描述
编写WordCountMapper.java

package mapreduce.wordcount;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

import java.io.IOException;

/**
 * LongWritable:map 阶段输入的key类型 表示一行文本的偏移量
 * 第一个Text:map阶段输入的value 表示一行文本中的内容
 *
 * 第二个Text:map阶段输出的key类型 表示一个单词
 * IntWritable:mao阶段输出的value类型,表示该单词出现的次数(1次)
 *
 */
public class WordCountMapper extends Mapper<LongWritable,Text, Text, IntWritable> {

    //创建Text对象,作为map阶段的输出key
    private Text keyOut = new Text();

    //创建intWritable对象 作为map阶段输出的value
    private IntWritable valueOut = new IntWritable(1);


    //重写map() 实现map阶段的业务处理
    //重写的map()的调用次数是每有一行文本调用一次map()
    @Override
    protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, IntWritable>.Context context) throws IOException, InterruptedException {
       //获取一行文本数据
       String line = value.toString();

       //根据单词间的分隔符进行拆分
        String[] words = line.split(" ");



        //对数组进行遍历
        for (String word : words) {

            //进行赋值
            keyOut.set(word);

            //map输出
            context.write(keyOut, valueOut);

        }

    }
}

编写WordCountReducer.java

package mapreduce.wordcount;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

import java.io.IOException;

/**
 * 第一个Text:reduce阶段的输入key类型 表示一个单词
 * 第一个IntWritable: reduce阶段的输入value类型 表示该单词出现的次数
 *
 *
 * 第二个Text:reducer阶段输出key类型 表示一个单词
 * 第二个Intwritable:reducer阶段输出的value类型 表示该单词出现的总次数
 */
public class WordCountReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
    //创建IntWritable对象 作为reduce阶段输出的value
    IntWritable valueOut = new IntWritable();


    //重写reduce() 实现数据的归约
    //reduce方法的调用次数 是由kv键值对中有多少不同的key决定的,一个key调用一次reduce
    public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {

        //定义该单词出现的总次数
        int sum = 0;


        //对迭代器进行遍历
        for (IntWritable count : values) {
            sum+=count.get();

        }


        //对于reduce输出阶段的value进行赋值
        valueOut.set(sum);

        //reduce阶段的输出
        context.write(key, valueOut);
    }
}

编写WordCountDriver.java

package mapreduce.wordcount;

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.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

import java.io.IOException;

public class WordCountDriver {
    public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {
        //获取配置对象和job对象
        Configuration conf = new Configuration();
        Job job = Job.getInstance(conf);

        //设置Driver类对象
        job.setJarByClass(WordCountDriver.class);

        //设置mapper和reducer类对象
        job.setMapperClass(WordCountMapper.class);
        job.setReducerClass(WordCountReducer.class);

        //设置mapper阶段输出的key,value类对象
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);

        //设置最终输出的kv类对象
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);

        //设置读取文件的路径 和 结果文件输出路径

        FileInputFormat.setInputPaths(job, new Path(args[0]));

        //设置输出路径为目录 且目录必须不存在
        FileOutputFormat.setOutputPath(job, new Path(args[1]));

        //提交job
        boolean result = job.waitForCompletion(true);
        System.out.println(result ? "Job Finished" : "Job Failed");


    }
}

运行结果
在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值