这是我参与「第四届青训营 」笔记创作活动的第5天
1. HDFS
配置文件优先级
hdfs-default.xml < hdfs-site.xml < 项目资源下的配置 < 代码中的配置
节点距离 结点距离计算=到共同祖先的距离总和
机架感知
- 第一个副存放在
client local - 第二个副本存放在
remote - 第三个副本存放在和第二个副本同一机架上
HDFS读取数据
多个block是串行读的,不是并行读取
NameNode
FsImage镜像文件记录hdfs中的文件关系,树形结构Edits记录的是编辑日志,用户具体对hdfs做了哪些操作,只能追加。2NN没有NN中的edits_inprogress文件
DataNode
每次通电,datanode向namenode汇报block信息
2. MapReduce
\
提交流程:
切片个数决定了未来MapTask的个数
\
作业提交重点:
MapReduce会在本地创建临时文件夹进行任务提交,三个东西:
-
- 切片信息
- jar包(集群模式)
- xml文件(记录环境的配置)
- 当
MR job提交成功后,临时文件夹会清空。P88 MapReduce job提交源码
\
切片重点:
- 切片原则是按照文件单独切片
- 切片大小由
块大小、minsize、maxsize决定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 - 加载镜像文件和编辑日志
- 初始化
NN的RPC服务 NN启动资源检查,默认是100MNN对心跳超时的判断(判断DN是否超过10分钟+30秒)- 安全模式(block启动阈值要达到0.999)
\
DataNode启动源码:
- 初始化
DataXceiverServer - 初始化
HTTP服务 - 初始化
DN的RPC服务端 DN向NN注册DN向NN发送心跳
\
HDFS上传源码