Hadoop学习 | 青训营笔记

166 阅读5分钟

这是我参与「第四届青训营 」笔记创作活动的第5天

1. HDFS

配置文件优先级 hdfs-default.xml < hdfs-site.xml < 项目资源下的配置 < 代码中的配置

节点距离 结点距离计算=到共同祖先的距离总和

机架感知

  • 第一个副存放在client local
  • 第二个副本存放在remote
  • 第三个副本存放在和第二个副本同一机架上

HDFS读取数据

多个block是串行读的,不是并行读取

NameNode

  • FsImage镜像文件记录hdfs中的文件关系,树形结构
  • Edits记录的是编辑日志,用户具体对hdfs做了哪些操作,只能追加。
  • 2NN没有NN中的edits_inprogress文件

DataNode
每次通电,datanodenamenode汇报block信息

2. MapReduce

\

提交流程:
切片个数决定了未来MapTask的个数

\

作业提交重点:

  • MapReduce会在本地创建临时文件夹进行任务提交,三个东西:
    • 切片信息
    • jar包(集群模式)
    • xml文件(记录环境的配置)
  • MR job提交成功后,临时文件夹会清空。P88 MapReduce job提交源码

\

切片重点:

  • 切片原则是按照文件单独切片
  • 切片大小由块大小minsizemaxsize决定 Math.max(minSize, Math.min(maxSize,blocksize))
  • 文件切片会计算且多少块,假设每块32M,文件大小/32M > 1.1 就需要切片,1.1倍

\

CombineTextInputFormat:
专门解决小文件切片问题
设置虚拟切片大小,对文件小于虚拟切片大小的单独一块,大于虚拟切片大小的除以2,最后按顺序合并。

\

Partition分区

  • 默认reduceTask是1所以分区数是1,源码回进入匿名内部类,return partitions-1;
  • 自定义设置分区数后,源码进行计算分区,return (key.hashCode() & Integer.MAX_VALUE) %

\

numReduceTask:

(key.hashCode() & Integer.MAX_VALUE) 是为了防止数据越界,Integer.MAX_VALUE的二进制是0111 1111 1111 1111 1111 1111 1111 1111

\

假设自定义分区数为5,则

  • job.setNumReduceTask(1); 会正常运行,但只产生一个输出文件
  • job.setNumReduceTask(2); 报错
  • job.setNumReduceTask(6); 大于5,程序正常运行,但会产生空文件,浪费资源

\

排序

  • Map阶段两次排序,先快排再归并排序。 MapTask会将结果暂存环形缓冲区,到达到阈值后,先对缓冲区上的数据快排,再将数据溢写到磁盘,最后进行一次归并排序。
  • Reduce阶段一次排序,归并排序。 统一对磁盘和内存数据进行一次归并排序。
    排序的目的是为了Reduce时可以提高效率。

\

Combiner

  • Combiner是MR程序中Mapper和Reducer之外的组件
  • Combiner组件的父类就是Reducer
  • Combiner和Reducer的区别在于运行位置
  • Combiner是在每一个MapTask所在结点运行
  • Reducer是接收全局所有的Mapper的输出结果
  • Combiner的意义是对每个MapTask的输出进行局部汇总,减少网络传输量
  • Combiner应用的前提是不影响最终的业务逻辑,如求平均数就不能开启Combiner

\

如果设置job.setNumReduceTask(0),也就是取消reduce阶段,那么整个shuffle阶段包括combiner都不起作用
在实际工作中,可以用reducer类替代combiner类\

数据倾斜
如果大量数据在reduce段进行合并会造成数据倾斜

\

MapReduce总结:

\

1.InputFormat
默认是TextInputFormat   k:偏移量,v:内容
处理小文件CombinerTextImputFormat

2.Mapper
setup() 初始化
map() 用户业务逻辑
clearup() 关闭资源

3.分区
默认是HashPartitioner,默认按照 key的hash值%numreducetask 进行分区
自定义分区 继承 Partitioner

4.排序
部分排序:每个输出的文件内部有序
全排序:一个reduce,对所有数据进行大排序(慎用)、
二次排序:自定义排序 实现 WritableComparable接口 重写compareTo方法

5.Combiner
不影响最终业务逻辑
提前聚合map==>可解决数据倾斜问题

6.Reducer
setup()初始化
reduce()业务逻辑
clearup关闭资源

7.OutputFormat
默认TextOutFormat按行输出到文件
自定义

\

3. YARN

\

1.yarn的工作机制

\

2.yarn的调度器

  • FIFO/容量
  • apache 默认容量调度器;CDH默认公平调度器
  • 公平/容量默认一个default队列,但实际使用场景中需要创建多个队列
  • 中小企业:hive spark flink mr 按组件进行分
  • 中大企业:登录/注册/购物车/营销 按业务模块分

\

好处:解耦合 降低风险
每个调度器的特点
相同点:支持多队列,可以借调资源,支持多用户
不同点:容量调度器优先满足队列中先进来的任务执行;公平调度器对队列中的任务公平享有资源
生产环境中
中小企业,对并发度要求不高,选择容量
中大企业,对并发度要求较高,选择公平

\

3.开发需要重点掌握的

队列运行原理
yarn常用命令
核心参数配置
配置容量调度器和公平调度器
tool接口

\

4. 生产参数调优

namenode 和 datanode 默认获取机器上的自动分配内存不合理
CDH给出的建议:
namenode最小给1G,每增加100万个block,增加1G内存
datanode最小给4G(副本数小于400万时),每增加100万个副本数,增加1G内存
namenode心跳池,用来处理不同datanode并发心跳和客户端并发元数据
int(20*math.log(3))

\

HDFS压力测试

网络带宽
磁盘读写速率

\

hadoop jar /opt/module/hadoop-3.3.1/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-3.3.1-tests.jar TestDFSIO -write -nrFiles 10 -fileSize 128MB

hadoop jar /opt/module/hadoop-3.3.1/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-3.3.1-tests.jar TestDFSIO -read -nrFiles 10 -fileSize 128MB


HDFS纠删码

HDFS默认情况下,一个文件有3个副本,这样提高了数据的可靠性,但也带来了2倍的冗余开销。
Hadoop3.x引入了纠删码,采用计算的方式,可以节省约50%左右的存储空间。
只存储一个副本,hdfs会根据校验单元进行恢复数据。

\

HDFS异构存储

内存+固态+机械+归档,不同的服务器共同组建集群
按数据类型(热、温、冷...)可以配置hdfs上的路径执行什么存储模式

\

HDFS异常处理

namenode挂掉,可以用secondarynamenode中的文件帮助恢复,前提是期间namenode没有新操作,否则会丢数据
一般企业不用2NN在恢复,而使用namenode HA(配置两个namenode)

\

Hadoop调优
小文件问题:

\

将小文件合并后上传hdfs
将小文件打包HAR文件上传,减少namenode内存占用
combineTextInputFormat
开启Uber模式,多个Task共用一个JVM(JVM重用)

\

5. Hadoop源码解析

\

NameNode启动源码:

  • 启动9870端口服务+servlet
  • 加载镜像文件和编辑日志
  • 初始化NNRPC服务
  • NN启动资源检查,默认是100M
  • NN对心跳超时的判断(判断DN是否超过10分钟+30秒)
  • 安全模式(block启动阈值要达到0.999)

\

DataNode启动源码:

  • 初始化DataXceiverServer
  • 初始化HTTP服务
  • 初始化DNRPC服务端
  • DNNN注册
  • DNNN发送心跳

\

HDFS上传源码