0614 hadoop03

Hadoop第三天

1. HDFS读数据流程

 

1.客户端通过Distributed FileSystemNameNode请求下载文件,NameNode通过查询元数据,找到文件存放的DataNode地址.

2.挑选一台近的DataNode节点,请求下载数据.

3.DataNode传输数据到客户端,(以某个单位来读取数据的)

4.先保存到本地缓存,然后合并写入本地磁盘.

2. NNSNN 工作流程

 

第一阶段:NameNode启动

1.第一次启动NameNode要进行格式化,创建Fsimageedits日志文件,如果不是第一次启动,编辑原来格式化的文件进行记录.

2.客户端对元数据进行修改或删除操作

3.NameNode会更新滚动记录日志

4.NameNode同步内存与磁盘edit文件

第二阶段: SecondaryNameNode

  1. SecondaryNameNode询问NodeNode是否需要checkpoint操作.
  2. SecondaryNameNode请求进行checkpoint操作
  3. 因为NameNode会更新滚动记录日志,当进行checkpoint操作时,它会生成一个新的日志edit文件.
  4. SecondaryNameNode下载需要checkpoint日志文件到本地
  5. SecondaryNameNode在内存中对editfsimage文件进行合并操作.
  6. 生成新的fsimage.chkpoint文件
  7. 远程复制到NameNode节点上.
  8. 把复制完成的fsimage.chkpoint重名命为fsimage--version版本

2.1. 修改默认checkpoint的配置

<!-- 默认checkpoint最长时间-->

<property>

  <name>dfs.namenode.checkpoint.period</name>

  <value>3600</value>

</property>

<!-- 默认checkpoint的记录大小-->

<property>

  <name>dfs.namenode.checkpoint.txns</name>

  <value>1000000</value>

</property>

 

3. DataNode工作机制

 

  1. 一个数据块在DataNode中以文件的形式存储在磁盘上,包括有数据本身和信息记录文件.
  2. DataNode在启动时,NameNode注册自已,通过周期性上报所有的块信息.
  3. NameNode通过心跳的连接,来检测DataNode是否存活,当心跳第一次失败时,那么会间隔一段时间再重复,当超过来0分钟心跳还是失败,就认为该节点不可用.
  4. 在集群中NameNode会管理节点信息(安全加入和退出机器)

 

3.1. 服役节点

  1. 准备机器
  2. hadoop初始化环境配置好,jdk,免密码登录,修改主机名和ip,防火墙关闭
  3. 在/opt/module/hadoop-2.7.2/etc/hadoop目录下创建一个文件: dfs.hosts

dfs.hosts:

hadoop01

hadoop02

hadoop03

hadoop04

......

 

  1. 在/opt/module/hadoop-2.7.2/etc/hadoop/hdfs-site.xml加入服役配置

<property>

  <name>dfs.hosts</name>

  <value>/opt/module/hadoop-2.7.2/etc/hadoop/dfs.hosts</value>

</property>

 

  1. 同步所有集群的配置 --xsync要加入新的主机
  2. 刷新nameNode节点

# hdfs dfsadmin -refreshNodes

提示成功!

  1. nameNode节点的slaves加入自已股径的节点

hadoop01

hadoop02

hadoop03

hadoop04

.....

  1. 可以启动整个集群/或单节点启动即可.

 

3.2. 退役节点

  1. 在/opt/module/hadoop-2.7.2/etc/hadoop目录下,创建dfs.hosts.exclude

添加退役服点:

hadoop04

  1. namenode节点上/opt/module/hadoop-2.7.2/etc/hadoop/hdfs-site.xml

<property>

  <name>dfs.hosts.exclude</name>

  <value>/opt/module/hadoop-2.7.2/etc/hadoop/dfs.hosts.exclude</value>

</property>

 

  1. 刷新nameNode节点

# hdfs dfsadmin -refreshNodes

提示刷新成功信息..

  1. web界面中,你可以看到副本正在复制的信息,当成功时,该退役的机器在集群中不存在了.

4. MapReduce入门

4.1. 定义

MapReduce是一个分布式运算框架,hadoop的运算核心.

4.2. 离线计算和实时计算

离线计算: 统计一部分结果,是旧的信息产生的结果.

实时计算: 通过产生的信息,实时得到想要的结果.

MapReduce是离线计算框架,不能做实时运算.

4.3. MapReduce优缺点

4.3.1. 优点

  1. MapReduce易于编程:它简单的实现一些接口,即可实现分布式运算.
  2. 良好的扩展性: 当运算资源不够时,可以通过添加计算资源满足要求.
  3. 高可靠性(容错能力): 在一台机器上运算不成功,它会启动另一台机器来进行运行,直到运算成功为止.
  4. 适合大数据场景 (PB级) 1PB=1024T =1T*1024台
  5. 实时运算: MapReduce不像mysql执行一样,能够立即出结果.
  6. 流式计算: 流式计算的数据是动态变化的.只能实现一次计算一次结果.
  7. MapReduce需要大量读写磁盘,运算性能很低.

4.3.2. 缺点

4.4. 集群的启动

启动yarn

[root@hadoop01 hadoop-2.7.2]# sbin/start-yarn.sh

全启动: HDFS Yarn

[root@hadoop01 hadoop-2.7.2]# sbin/start-all.sh

启动成功后存在以下节点:

ResourceManager : 资源管理器(老大)

NodeManager: 节点运算管理(小弟)

 

访问resourceManager的管理页面:

http://192.168.254.101:8088/cluster

 

4.5. 单词统计

[root@hadoop01 hadoop-2.7.2]# bin/hadoop jar /opt/module/hadoop-2.7.2/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.2.jar wordcount hdfs://hadoop01:9000/words.txt hdfs://hadoop01:9000/countout

 

在进行mapreduce运算时,会动态显示进程:

RunJar

MRAppMaster

YarnChild

 

结果:

 

 

4.6. MapReduce中的进程

一个完整的mapreduce运行会出现三个进程:

MRAppMaster: 负责整个mapreduce的资源调度与状态协调.

mapTask: 负责map阶段的整个数据处理流程.

reduceTask: 负责reduce阶段的整个数据处理流程.

RunJar: 运算mapreduce程序需要运行jar,RunJar进程是在JVM虚拟机中运行java程序的开启一块运资源.

YarnChild: mapreduce计算所需要开启的一块计算资源(JVM虚拟机用到的资源)

4.7. MapReduce编程规范

用户编写mapreduce程序分为三个部分: Driver,MapReduce

一. Driver阶段

整个程序需要一个Driver进行提交,提交的是一个job的描述信息(MapReduce).

二. Map阶段

1) 用户需要自定义map运算,必须继承原来的map接口实现方法

2) Map对数据的输入类型K,V 进行自定义,当然附合序列化规则

3) 编写局部统计算法

4) Map对数据的输出类型K,V 进行自定义,当然附合序列化规则

5) map()方法:对每一个kv会调用一次.

 

三. Reduce阶段

1) 用户需要自定义reduce运算,必须继承原来的reduce接口实现方法

2) ReduceMap阶段输出作为自已输入进行kv结构运算,类型要匹配map输入类型

3) Reduce的任务汇总数据,会调用reduce()方法,有多少个分区,就会有多个个reduceTask进行汇总.

4) 每个分区会调一次reduce方法

4.8. 编写Mapreduce程序

需求: 有一堆文本数据,要求统计文本数据内的单词个数.

4.8.1. 导入依赖

<dependencies>
    <!--单元测试-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    <!--导入日志依赖-->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.13.3</version>
    </dependency>

    <!-- hadoop-common 公共依赖-->
    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-common</artifactId>
        <version>2.7.2</version>
    </dependency>

    <!-- hadoop-client 客户端依赖-->
    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-client</artifactId>
        <version>2.7.2</version>
    </dependency>

    <!-- hadoop-hdfs 依赖-->
    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-hdfs</artifactId>
        <version>2.7.2</version>
    </dependency>

    <!-- hadoop-mapreduce依赖-->
    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-mapreduce-client-core</artifactId>
        <version>2.7.2</version>
    </dependency>

</dependencies>

4.8.2. 分析实现过程

 

4.8.3. 编写map阶段


public class WordCountMapper extends Mapper<LongWritable, Text,Text, IntWritable> {

    Text k = new Text();

    IntWritable v = new IntWritable(1);

    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        //1.获取一行的内容
        String line = value.toString();//<1,"hadoop kafka spark stop start">

        //2.切割
        String[] words = line.split(" "); //切割后数据类型 String

        //3.获取每个单词
        for (String word : words){ // hadoop
            //对类型转换hadoop类型
            k.set(word);
            context.write(k,v);//--> <"hadoop",1>
        }

    }
}

4.8.4. 编写Reduce阶段


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

import java.io.IOException;

public class WordCountReduce extends Reducer<Text, IntWritable,Text, IntWritable> {

    int sum;

    IntWritable v =new IntWritable();

    @Override
    protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
        //1.累加求和
        sum=0;
        for (IntWritable count: values){
            sum+=count.get();
        }

        //2.输出
        v.set(sum);
        context.write(key,v);
    }
}

 

 

4.8.5. 编写Driver运行类


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.FileInputStream;

public class WordCountDriver {

    public static void main(String[] args) throws Exception {
        // 获取集群信息
        Configuration configuration = new Configuration();
        // 构造job任务
        Job job = Job.getInstance(configuration);

        // 设置job类路径
        job.setJarByClass(WordCountDriver.class);

        // 设置mapreduce
        job.setMapperClass(WordCountMapper.class);
        job.setReducerClass(WordCountReduce.class);

        // 设置mapk,v类型
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);

        // 设置reducek,v类型
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);

        // 设置输入与输出路径
        FileInputFormat.setInputPaths(job,new Path(args[0]));
        FileOutputFormat.setOutputPath(job,new Path(args[1]));

        // 提交工作
        boolean result = job.waitForCompletion(true);

        System.exit(result?0:1);

    }
}

 

4.8.6. 运行方式

  1. 在本机上运行调试

 

  1. 打包运行

1) 配置打包插件

<build>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.3.2</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <archive>
                    <manifest>
                        <mainClass>com.hotdas.mr.WordCountDriver</mainClass>
                    </manifest>
                </archive>
            </configuration>
            <executions>
                <execution>
                    <id>make-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

 

2) 打包方式

 

3) 打包结果

 

 

5. Hadoop的序列化

5.1. 什么是序列化

 

 

5.2. JDK的序列化

 

 

JDK序列化词 Serializable

Hadoop序列化词: Writable

5.3. hadoop优点

1) 紧凑

2) 快速

3) 可扩展强

4) 互操作强

5.4. 常见的序列化类型

 

5.5. hadoop的序列化体系

 

6. 作业题

统计每个手机号消耗的流量: 上传流量   下载流量   总流量

 

posted @   linzm14  阅读(56)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端
点击右上角即可分享
微信分享提示