Hadoop的三大组件的描述和操作

HDFS(分布式文件存储系统)

NameNode与Datanode的总结概述

HDFS有主节点(namenode)和从节点(datanode)
在这里插入图片描述

3.1.namenode 元数据管理

我们把描述信息的信息叫做元数据。Namenode 负责维护整个hdfs文件系统的目录树结构,以及每一个文件所对应的 block 块信息(block 的id,及所在的datanode 服务器)。

3.2.Datanode 数据存储

文件的各个 block 的具体存储管理由 datanode 节点承担。每一个 block 都可以在多个datanode 上。Datanode 需要定时向 Namenode 汇报自己持有的 block信息。 存储多个副本(副本数量也可以通过参数设置 dfs.replication,默认是 3)。

HDFS的架构图

在这里插入图片描述

HDFS的执行过程

在这里插入图片描述

HDFS的文件读取过程

在这里插入图片描述
详细步骤解析

1、 Client向NameNode发起RPC请求,来确定请求文件block所在的位置;

2、 NameNode会视情况返回文件的部分或者全部block列表,对于每个block,NameNode 都会返回含有该 block 副本的 DataNode 地址; 这些返回的 DN 地址,会按照集群拓扑结构得出 DataNode 与客户端的距离,然后进行排序,排序两个规则:网络拓扑结构中距离 Client 近的排靠前;心跳机制中超时汇报的 DN 状态为 STALE,这样的排靠后;

3、 Client 选取排序靠前的 DataNode 来读取 block,如果客户端本身就是DataNode,那么将从本地直接获取数据(短路读取特性);

4、 底层上本质是建立 Socket Stream(FSDataInputStream),重复的调用父类 DataInputStream 的 read 方法,直到这个块上的数据读取完毕;

5、 当读完列表的 block 后,若文件读取还没有结束,客户端会继续向NameNode 获取下一批的 block 列表;

6、 读取完一个 block 都会进行 checksum 验证,如果读取 DataNode 时出现错误,客户端会通知 NameNode,然后再从下一个拥有该 block 副本的DataNode 继续读。

7、 read 方法是并行的读取 block 信息,不是一块一块的读取;NameNode 只是返回Client请求包含块的DataNode地址,并不是返回请求块的数据;

8、 最终读取来所有的 block 会合并成一个完整的最终文件。

HDFS基本Shell操作

创建文件夹(支持多级创建):

hadoop fs -mkdir -p /xxx

查看目录:

hadoop fs -ls /xxx

递归查看多级目录:

hadoop fs -ls -R /xxx

上传文件到HDFS:

hadoop fs -put xxx.txt /xxx

下载文件到本地当前目录:

hadoop fs -get /xxx/xxx/xxx.txt

删除文件:

hadoop fs -rm /xxx/xxx/xxx.txt

删除文件夹(文件夹必须为空):

hadoop fs -rmdir /xxx/xxx

强制删除文件夹或文件

Hadoop fs -rm -r /xxx

HDFS的api操作

0.前期准备:解决winutils.exe的问题

1)把hadoop2.7.7(windows版)文件目录放到一个没有中文没有空格的路径下
​2)在window中配置handoop的环境变量,并且加入path中。
  1. 创建maven项目:CGBTN2108
  2. 创建子项目:HADOOPSTDY
  3. 在子项目的pom文件中添加
<dependency>
  <groupId>org.apache.hadoop</groupId>
  <artifactId>hadoop-common</artifactId>
  <version>2.7.7</version>
</dependency>
<dependency>
  <groupId>org.apache.hadoop</groupId>
  <artifactId>hadoop-hdfs</artifactId>
  <version>2.7.7</version>
</dependency>
<dependency>
  <groupId>org.apache.hadoop</groupId>
  <artifactId>hadoop-client</artifactId>
  <version>2.7.7</version>
</dependency>
  1. 获取FileSystem的方式
package cn.tedu;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;

import java.io.IOException;

public class HDFSTest {
    public static void main(String[] args) throws IOException {
    
        //实例化一个配置对象,通过conf可以配置关于hdfs的相关参数
        Configuration conf = new Configuration();
        //fs.default.name是老版本的属性,就是指定了hdfs的访问路径
        //fs.defaultFS是新版本的属性
        conf.set("fs.default.name", "hdfs://hadoop01:8020");
        //定义一个文件系统对象
        FileSystem fileSystem = FileSystem.get(conf);
        System.out.println(fileSystem.toString());
    }
}
  1. 创建文件夹
@Test
public void mkdirs() throws  Exception{
    FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.65.101:8020"), new Configuration());
    boolean mkdirs = fileSystem.mkdirs(new Path("/hello/mydir/test"));
    fileSystem.close();
}
  1. 上传文件
@Test
public void putData() throws  Exception{
  	Configuration configuration=new Configuration();
		configuration.set("fs.defaultFS","hdfs://192.168.65.101:8020");
	FileSystem fileSystem=FileSystem.get(configuration);
    fileSystem.copyFromLocalFile(new Path("file:///c:\\install.log"),new Path("/hello/mydir/test"));
    fileSystem.close();
}
  1. 文件下载
@Test
public void getFileToLocal()throws  Exception{
   Configuration configuration=new Configuration();
		configuration.set("fs.defaultFS","hdfs://192.168.65.101:8020");
	FileSystem fileSystem=FileSystem.get(configuration);
    FSDataInputStream open = fileSystem.open(new Path("/test/input/install.log"));
    FileOutputStream fileOutputStream = new FileOutputStream(new File("c:\\install.log"));
    IOUtils.copy(open,fileOutputStream );
    IOUtils.closeQuietly(open);
    IOUtils.closeQuietly(fileOutputStream);
    fileSystem.close();
}

Mapreduce(分布式计算组件)

MapReduce的思想核心是“分而治之”,适用于大量复杂的任务处理场景(大规模数据处理场景)

Hadoop MapReduce设计构思

MapReduce是一个分布式运算程序的编程框架,核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序,并发运行在Hadoop集群上。

既然是做计算的框架,那么表现形式就是有个输入(input),MapReduce操作这个输入(input),通过本身定义好的计算模型,得到一个输出(output)。

如何对付大数据处理:分而治之

l 构建抽象模型:Map和Reduce

MapReduce借鉴了函数式语言中的思想,用Map和Reduce两个函数提供了高层的并行编程抽象模型。

Map: 对一组数据元素进行某种重复式的处理;

Reduce: 对Map的中间结果进行某种进一步的结果整理。

MapReduce中定义了如下的Map和Reduce两个抽象的编程接口,由用户去编程实现:

map: (k1; v1)[(k2; v2)]

reduce: (k2; [v2])[(k3; v3)]

在这里插入图片描述

WordCount实例

先定义一个WordMapper类

package cn.tedu;

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;

public class WordMapper extends Mapper<LongWritable, Text,Text, IntWritable> {
    @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),new IntWritable(1));
        }
    }
}

再定义一个WordReducer类

package cn.tedu;

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

import java.io.IOException;

/*
* 完成数据的聚合操作
* Text:k2 词
* IntWritable:v2 出现的一次
* Text:k3 词
* IntWritable:v3 一共出现多少次
* */
public class WordReducer extends Reducer<Text, IntWritable,Text,IntWritable> {
    /*
    * 按照k2,value聚合在一起,相同的key只会调用一次方法
    * @param key:k2,需要的聚合的词
    * @param value:v2的聚合
    * @param context
    * */
    @Override
    protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
        //完成数据聚合,词出现的次数
        int total=0;
        for (IntWritable value : values) {
            total += value.get();
        }
        context.write(key, new IntWritable(total));
    }
}

最后定义一个WordCountJob类

package cn.tedu;

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.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;

import java.io.IOException;

public class WordCountJob {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
        //实例化一个job对象,通过job提交作业
        Configuration configuration = new Configuration();
        Job job = Job.getInstance(configuration, WordCountJob.class.getSimpleName());
        job.setJarByClass(WordCountJob.class);
        //1.先指定读取数据的TextInputFormat
        job.setInputFormatClass(TextInputFormat.class);
        TextInputFormat.addInputPath(job,
                new Path("hdfs://hadoop01:8020/test/input/wordcount.text"));
        //2.设置mapper,并且指定k2,v2的类型
        job.setMapperClass(WordMapper.class);
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);
        
        //7.设置reduce,指定k3,v3的类型
        job.setReducerClass(WordReducer.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);
        //8.设置输出TextOutputFormat
        job.setOutputFormatClass(TextOutputFormat.class);
        TextOutputFormat.setOutputPath(job,
                new Path("hdfs://hadoop01:8020/test/output"));
        job.waitForCompletion(true);
    }
}

yarn(资源调度管理器)

yarn是hadoop集群当中的资源管理系统模块,yarn主要就是为了调度资源,管理任务等,在hadoop2.x才开始引入的

yarn当中的调度器介绍

第一种调度器:FIFO Scheduler (队列调度器)

FIFO Scheduler是最简单也是最容易理解的调度器,也不需要任何配置,但它并不适用于共享集群。大的应用可能会占用所有集群资源,这就导致其它应用被阻塞。在共享集群中,更适合采用Capacity Scheduler或Fair Scheduler,这两个调度器都允许大任务和小任务在提交的同时获得一定的系统资源。
在这里插入图片描述

第二种调度器:capacity scheduler(容量调度器,apache版本默认使用的调度器)

Capacity 调度器允许多个组织共享整个集群,每个组织可以获得集群的一部分计算能力。通过为每个组织分配专门的队列,然后再为每个队列分配一定的集群资源,这样整个集群就可以通过设置多个队列的方式给多个组织提供服务了。除此之外,队列内部又可以垂直划分,这样一个组织内部的多个成员就可以共享这个队列资源了,在一个队列内部,资源的调度是采用的是先进先出(FIFO)策略。
在这里插入图片描述

第三种调度器:Fair Scheduler(公平调度器,CDH版本的hadoop默认使用的调度器)

Fair调度器的设计目标是为所有的应用分配公平的资源(对公平的定义可以通过参数来设置)。公平调度在也可以在多个队列间工作。举个例子,假设有两个用户A和B,他们分别拥有一个队列。当A启动一个job而B没有任务时,A会获得全部集群资源;当B启动一个job后,A的job会继续运行,不过一会儿之后两个任务会各自获得一半的集群资源。如果此时B再启动第二个job并且其它job还在运行,则它将会和B的第一个job共享B这个队列的资源,也就是B的两个job会用于四分之一的集群资源,而A的job仍然用于集群一半的资源,结果就是资源最终在两个用户之间平等的共享
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值