Hadoop学习-概述与mapreduce

Hadoop

概述

什么是Hadoop

Hadoop是一个适用于海量数据的分布式存储和分布式计算的平台。

Hadoop三大基本组件

YARN、MapReduce、HDFS

分布式文件系统

FS、GFS(谷歌的分布式文件系统)、HDFS(Hadoop专有的分布式文件系统)

为什么需要使用分布式文件系统
  1. 文件存放在一个磁盘上效率肯定是最低的

读取效率低

如果文件特别大会超出单机的存储范围

2. 字节数组

文件在磁盘真实存储文件的抽象概念

数组可以进行拆分和组装,源文件不会收到影响

3. 切分数据

对字节数组进行切分

4. 拼接数据

按照数组的偏移量将数据连接到一起,将字节数组连接到一起

5. 偏移量

当前数据在数组中的相对位置,可以理解为下标

数组都有对应的索引,可以快速定位数据

6. 数据存储的原理

不管文件的大小,所有的文件都是由字节数组构成

如果我们要切分文件,就是将一个字节数组分成多份

我们将切分后的数据拼接到一起,数据还可以继续使用

我们需要根据数据的偏移量将他们重新拼接到一起

Block块

什么是Block块
  1. 是磁盘进行数据 读/写的最小单位,数据被切分后的一个整体被称之为块

  2. .在Hadoop 1默认大小为64M,在Hadoop 2及其之后默认大小为128M块,这么大是为了最小化寻址开销

  3. 同一个文件中,每个数据块的大小要一致除了最后一个节点外不同文件中,块的大小可以不一致,文件大小不同可以设置不同的块的数量,HDFS中小于一个块的大小的文件不会占据整个块的空间

  4. 真实情况下,会根据文件大小和集群节点的数量综合考虑块的大小

  5. 数据块的个数=Ceil(文件大小/每个块的大小)

注意事项
  1. 只要有任意一个块丢失,整个数据文件被损坏

  2. HDFS中一旦文件被存储,数据不允许被修改,修改会影响偏移量,导致数据倾斜(单节点数据量过多)、蝴蝶效应

  3. 但是可以被追加(一般不推荐)追加设置需要手动打开

  4. 一般HDFS存储的都是历史数据.所以将来Map Reduce都用来进行离线数据的处理

  5. 块的大小一旦文件上传之后就不允许被修改 128M-512M

拆分的数据块需要等大(面试)
  1. 数据计算的时候简化问题的复杂度(否则进行分布式算法设计的时候会因为数据量不一很难设计)

  2. 数据拉取的时候时间相对一致

  3. 通过偏移量就知道这个块的位置

  4. 相同文件分成的数据块大小应该相等

端口号

HDFS:50070

YARN:8088

进程管理

HDFS:NameNode、DataNode、SecondaryNameNode(NN、DN、SNN)

NameNode

功能:

1、接受客户端的读/写服务

因为NameNode知道文件与DataNode的对应关系

2、保存文件的时候会保存文件的元数据信息

a. 文件的归属

b. 文件的权限

c. 文件的大小,时间

d. Block信息,但是block的位置信息不会持久化,需要每次开启集群的时候DN向NN汇报。(带同学们画图讲解,引出这4个点)

3、收集Block的位置信息

3.1 系统启动

a. NN关机的时候是不会存储任意的Block与DataNode的映射信息的

b. DN启动的时候会自动将自己节点上存储的Block信息汇报给NN

c. NN接收请求之后会重新生成映射关系

File ----> Block

Block---> DN

d. 如果数据块的副本数小于设置数,那么NN会将这个副本拷贝到其他节点

3.2 集群运行中

a. NN与DN保持心跳机制,三秒钟发送一次

b. 如果客户端需要读取或者上传数据的时候,NN可以知道DN的健康情况

c. 可以让客户端读取存活的DN节点

d. 如果NN与DN三秒没有心跳则认为DN出现异常,此时不会让新的数据写到这个异常的DN中,客户端访问的时候不提供异常DN节点地址

e. 如果超过十分钟没有心跳,那么NN会将当前DN节点存储的数据转移到其他的节点

4、NameNode为了效率,将所有的操作都在内存中进行

a. 执行速度快

b. NameNode不会和磁盘进行任何的数据交换

但是会存在两个问题:

1)数据的持久化

2)数据保存在内存中,断电丢失

DataNode

1、存放的是文件的数据信息,以及验证文件完整性的校验信息

2、数据会存放在硬盘上

a. 1m=1条元数据

b. 1G=1条元数据

c. NameNode非常排斥存储小文件(能存,但是不推荐!!)

一般小文件在存储之前需要进行压缩

3、汇报

1)启动时

汇报之前会验证Block文件是否被损坏

向NN汇报当前DN上block的信息

2)运行中

向NN保持心跳机制

4、当客户端读写数据的时候,首先会先去NN查询file与block与DN的映射,然后直接与DN建立连接,然后读写数据

SecondaryNameNode

1、传统的那日村持久化方案

1)日志机制

a. 做任何操作之前先记录日志

b. 在数据改变之前先记录对应的日志,当NN停止的时候

c. 当我下次启动的时候,只需要重新按照以前的日志“重做一遍”即可

缺点:

a. log日志文件的大小不可控,随着时间的发展,集群启动的时间会越来越长

b. 有可能日志中存在大量的无效日志

优点:

a. 绝对不会丢失数据

2)拍摄快照

a. 我们可以将内存中的数据写出到硬盘上(序列化)

b. 启动时还可以将硬盘上的数据写回到内存中(反序列化)

缺点:

a. 关机时间过长

b. 如果是异常关机,数据还在内存中,没法写入到硬盘

c. 如果写出的频率过高,导致内存使用效率低

优点:

启动时间较短

 

2、SNN的解决方案

1)解决思路

a. 让日志大小可控

b. 快照需要定时保存

c. 日志+快照

2)解决方案

a. 当我们启动一个集群的时候,会产生4个文件 ..../name/current/

image-20220521005240506

b. 我们每次操作都会记录日志

主从节点的进程

master:NameNode、SecondaryNameNode、ResourceManager

node1、2:DataNode、NodeManager

MapReduce

什么是MapReduce

map--->映射

reduce--->归纳

mapreduce必须构建在hdfs之上的一种大数据离线计算框架

在线:实时数据处理

离线:数据处理时效性没有在线那么强,但是相对也需要很快得到结果

mapreduce不会马上得到结果,他会有一定的延时(磁盘IO)

如果数据量小,使用mapreduce反而不合适

杀鸡焉用宰牛刀

原始数据-->map(Key,Value)-->Reduce

分布式i计算

将大的数据切分成多个小数据,交给更多的节点参与运算

计算向数据靠拢

将计算传递给有数据的节点上进行工作

MapReduce流程

原始数据被切分

数据被切分成块存放在HDFS上,每一个块有128M大小

切片Split

目的:动态地控制计算单元的数量

切片是一个逻辑概念

在不改变现在数据存储的情况下,可以控制参与计算的节点数目

通过切片大小可以达到控制计算节点数量的目的

有多少个切片就会执行多少个Map任务

一般切片大小为Block的整数倍(2 1/2)

防止多余创建和很多的数据连接

如果Split大小 > Block大小 ,计算节点少了

如果Split大小 < Block大小 ,计算节点多了

默认情况下,Split切片的大小等于Block的大小 ,默认128M,如果读取到最后一个block块的时候,与前一个blokc块组合起来的大小小于128M*1.1的话,他们结合生一个split切片,生成一个map任务

一个切片对应一个MapTask

MapTask

map默认从所属切片读取数据,每次读取一行(默认读取器)到内存中(map种的逻辑作用在每一行上)

我们可以根据自己书写的分词逻辑(空格,逗号等分隔),计算每个单词出现的次数(wordcount)

这时会产生(Map<String,Integer>)临时数据,存放到内存中

但是内存的大小是有限的,如果每个任务随机的去占用内存,会导致内存不可控。多个任务同时执行有可能内存溢出(OOM)

如果把数据都直接放到硬盘,效率太低

所以想个方案,内存和硬盘结合,我们要做的就是在OOM和效率低之间提供一个有效方案,可以先往内存中写入一部分数据,然后写出到硬盘

环形缓冲区(KV-Buffer)

可以循环利用这块内存区域,减少数据溢写时map的停止时间

每一个Map可以独享的一个内存区域

在内存中构建一个环形数据缓冲区(kvBuffer),默认大小为100M

设置缓冲区的阈值为80%(设置阈值的目的是为了同时写入和写出),当缓冲区的数据达到80M开始向外溢写到硬盘

溢写的时候还有20M的空间可以被使用效率并不会被减缓

而且将数据循环写到硬盘,不用担心OOM问题

分区

根据Key直接计算出对应的Reduce

分区的数量和Reduce的数量是相等的

hash(key) % partation(reduce的数量) = num

默认分区的算法是Hash然后取余

Object的hashCode()—equals()

如果两个对象equals,那么两个对象的hashcode一定相等

如果两个对象的hashcode相等,但是对象不一定equlas

排序

对要溢写的数据进行排序(QuickSort)

按照先Partation后Key的顺序排序–>相同分区在一起,相同Key的在一起

我们将来溢写出的小文件也都是有序的

溢写

将内存中的数据循环写到硬盘,不用担心OOM问题

每次会产生一个80M的文件

如果本次Map产生的数据较多,可能会溢写多个文件

合并

因为溢写会产生很多有序(分区 key)的小文件,而且小文件的数目不确定

后面向reduce传递数据带来很大的问题

所以将小文件合并成一个大文件,将来拉取的数据直接从大文件拉取即可

合并小文件的时候同样进行排序(归并 排序),最终产生一个有序的大文件

组合器
  1. 集群的带宽限制了mapreduce作业的数量,因此应该尽量避免map和reduce任务之间的数据传输,hadoop允许用户对map的输出数据进行处理,用户可自定义combiner函数(如同map函数和reduce函数一般),其逻辑一般和reduce函数一样,combiner的输入是map的输出,combiner的输出作为reduce的输入,很多情况下可以i直接将reduce函数作为conbiner函数来试用(job.setCombinerClass(FlowCountReducer.class))。

  2. combiner属于优化方案,所以无法确定combiner函数会调用多少次,可以在环形缓存区溢出文件时调用combiner函数,也可以在溢出的小文件合并成大文件时调用combiner,但是要保证不管调用多少次,combiner函数都不影响最终的结果,所以不是所有处理逻辑都可以i使用combiner组件,有些逻辑如果试用了conbiner函数会改变最后reduce的输出结果(如求几个数的平均值,就不能先用conbiner求一次各个map输出结果的平均值,再求这些平均值的平均值,那样会导致结果的错误)。

  3. combiner的意义就是对每一个maptask的输出进行局部汇总,以减小网络传输量:

原先传给reduce的数据时a1 a1 a1 a1 a1

第一次combiner组合后变成a(1,1,1,1,1)

第二次combiner后传给reduce的数据变为a(5,5,6,7,23,...)

拉取

我们需要将Map的临时结果拉取到Reduce节点

相同的Key必须拉取到同一个Reduce节点

但是一个Reduce节点可以有多个Key

未排序前拉取数据的时候必须对Map产生的最终的合并文件做全序遍历

而且每一个reduce都要做一个全序遍历

如果map产生的大文件是有序的,每一个reduce只需要从文件中读取自己所需的即可

合并

因为reduce拉取的时候,会从多个map拉取数据

那么每个map都会产生一个小文件,这些小文件(文件与文件之间无序,文件内部有序)

为了方便计算(没必要读取N个小文件),需要合并文件

归并算法合并成2个(qishishilia)

相同的key都在一起

归并

将文件中的数据读取到内存中

一次性将相同的key全部读取到内存中

直接将相同的key得到结果–>最终结果

写出

每个reduce将自己计算的最终结果都会存放到HDFS上

总结

1.每个reduce将自己计算的最终结果都会存放到HDFS上

2、按照我们定义的split逻辑对block进行切分(不是真正意义上的切分,而是逻辑上的切分,读取到定义的大小,就会产生—map任务,hadoop默认split大小是128M,但是如果最后一个block块与前一个block块数据真实大小总和小于128*1.1的话,会生一个map任务

3、map任务的逻辑是作用在每一行会按照我们定义的分隔符进行切分,得到一个Key-value的格式数据

4、map任务产生的数据会进入到一个叫作环形缓冲区的地方,这个环形缓冲区(内存,每一个map任务都会有一个这样的环形缓冲区)的大小默认是100M,当数据写入到默认80%的时候,开始往磁盘溢写,产生一个文件。

5、在溢写之前,也就是在环形缓冲区的时候,会先将数据分区(哈希值%reduce),排序(快速排序)。reduce去拉取的时候,每一个map产生的小文件会先进行一次合并(归并排序),同-个分区的数据被拉取到同一个reduce中。这时候,一个reduce中就计算出每一个map任务的结果reduce再将每一个map任务的结果做合并(归并排序),聚合得到结果最终的结果写出到HDFS中

posted @   wdnmd、  阅读(99)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示