HDFS
一个分布式文件系统,适合一次写入,多次读出的场景
namenode 管理节点
管理文件系统的命名控件管理整个系统内所有文件和目录
datanode 工作节点
存储并检索数据块 ,受namenode调度
hdfs 文件大小
hdfs 默认分块存储,默认大小128M
hdfs读写流程
写入
1.客户端向namenode 请求上传文件
2.响应可以上传文件
3.客户端请求上传第一个文件
4.namenode 返回三个节点 dn1,dn2,dn3
5.建立传输管道
6.dn1,dn2,dn3逐级应答
7.传输数据
Q : 如何nameNode 如何选择距离最近的datanode 上传数据?
按照网络拓扑的距离进行计算
读数据
1.客户端通过Distributed FileSystem 向namenode 请求下载文件,namenode 通过查询元数据信息,找到文件所在的datanode地址
2.就近挑选一台datanode,请求数据
3.datanode开始传输数据给客户端,以packet 作为单位
4.客户端以packet作为单位接受,先写本地缓存,然后写入目标文件。
NN和2NN的工作机制
Q: nameNode 中的元数据是存储在哪里的? 内存
一旦断电整个集群无法工作。为了解决这个问题产生在磁盘中备份元数据的 fsImage。但这又产生新的问题,如果元数据更新时同时更新 fsimage,就会导致效率过低,如果不更新,就会产生一致性问题,一旦断电,数据丢失,因此,引入 edits文件。每当有数据更新时,修改内存中的元数据追加到edits中。当edits数据量过大时,恢复的时间就会过长,因此,需要定期合并fsimage和edits,如果这一操作由namenode完成,效率又过低,为了实现这一功能,引入2NN。
流程:
1. 2NN询问是否需要checkPoint (更新检查点)
2.请求执行checkpoint
3.滚动正在写的edits
4.将fsImage写入2NN
5.将fsimage和edits加载到内存并合并
6.生成新的fsimage.chkpoint
7.拷贝到nn
8.将fsimage.chkpoint 重命名为fsimage
fsimage文件:hdfs文件系统元数据的一个永久检查点,其中包含文件系统的所有目录信息。
Fsimage中没有记录块所对应DataNode。
在集群启动后,要求DataNode上报数据块信息,并间隔一段时间后再次上报。
Edits : 记录追加操作
DN:
工作流程
1.dataNode启动后向nn注册
2.注册成功
3.DN每周期向NN上报所有信息,默认6小时
4.每隔几秒返回一次信息,超过10分钟没有说到DataNode的心跳,则认为该节点不可用。
MapReduce
一个分布式运算程序的编程框架,核心功能是将用户代码和默认组件整合成一个完整的分布式运算程序。
优点: 易于编程和扩展,高容错性,适合pb以上海量数据的离线处理
缺点:不擅长实时计算,不擅长流式计算(输入数据不能是动态变化的),不擅长有向图计算 (慢)
核心思想
- mapreduce 运行程序一般分成2个阶段,map阶段和reduce阶段
- map阶段的并发maptask,完全并行运行,互不相干
- reduce阶段的并发reducetask,完全互不相关,但是他们依赖的数据是上一个阶段所有maptask并发实例的输出
- mapreduce编程只能有一个map阶段和一个reduce阶段
mapreduce进程
- MrappMaster 负责整个程序的调度协调
- maptask
- reducetask
序列化
将结构化的对象转化为字节流以便在网络上传输,或写到磁盘中进行永久存储的过程。
序列化主要用于进行进程间通讯和永久存储,在hadoop中,多个节点之间的通讯使用rpc调用,rpc 调用的过程中需要进行序列化。
hadoop采用wirteable 进行序列化
writeable 封装器:writable 类对每一种Java基本类型(char类型除外),进行了封装,所有的封装都提供了get()和set()方法。
Text,针对utf8 的序列化类,可以认为是String 的writable等价
Nullwriteable
ObjectWritable
Writable集合类
- Arraywritable 数组
- TwoDArrayWriteable 2维数组
- MapWritable
- SortedMapWritable 排序 map
数据切片与并行
1.一个job的map阶段并行度由客户端端在提交job时的切片数决定
2.每切一片都将分配一个maptask并行处理
3.默认切片大小= blocksize
4.切片时不考虑数据集整体,而是针对每一个文件单独切片
job提交流程
1.建立连接
2.提交job
- 创建提交路径
- 拷贝jar包到集群
- 计算切片
- 写xml文件
切片流程
1.程序找到数据的存储目录
2.遍历目录下的每一个文件
- 获取文件大小
- 计算切片大小
compute(Math.max(minSize,Math.max(maxSize,blockSize)))
1 Long的最大值 128M
- 默认情况下切片大小为128M
- 每次切片时都要判断 输入文件字节大小 /128 >1.1 ? 作为1个split : size/128
- 将切片信息存储在切片规划文件中
shuffle
从map方法之后,reduce方法之前的数据处理过程。
- map方法之后,数据先写入环形缓冲区中,当环形缓冲区使用率达到一定的阈值后,再对缓冲区中的数据进行一次快速排序
- 数据溢写到文件中,当数据处理完毕后,会对磁盘上所有文件进行一次归并排序
- reduce从磁盘中拷贝数据到内存,内存不够溢出到磁盘,对map中的数据进行归并排序,进入reduce方法
Partition
按照条件输出到不同文件
- 默认分区 hash分区
根据key 的hashCode 对reduceTask 取模得到的,每有一个reduceTask便会产生一个文件。
- 自定义分区 继承 Partitioner类 重写getPartition方法
如果reduceTask > partitionSize 会产生空文件
如果reduceTask < partitionSize 会报错
分区号必须从0开始,逐一增加
Combiner
- combiner是在maptask所在的节点进行运行
- reducer是接受全局所有的mapper的输出结果
- 它的意义为对每一个maptask的输出继续局部汇总,以减少网络传输
小文件存储
每个小文件占用一个块,都需要在目录中占用内存存储信息,但是内存是不能无线大的,为了存储小文件,使用 sequenceFile 和mapFile
- sequenceFile 将所有文件以键值对的形式存储在一起,文件名作为key,内容作为value
- mapFile 由index 和data组成, index为文件的数据索引,记录偏移位置,通过index即可找到文件位置,相对于 sequenceFile 要快,但占用一部分存储空间,但是效率高
数据倾斜
解决办法: 1. 增加reduce任务个数 2.将倾斜的数据打散
一般采用生成随机值的方法来提高效率
mr 的缺点
1.从存储介质中采集数据,计算,再存储到存储介质中,不适合用于数据挖掘和机器学习这样的迭代计算和图形计算
2.mr 基于文件存储介质的操作,性能非常慢
3。mr 和hadoop 紧密结合在一起 ,无法动态替换
yarn
hadoop 的集群资源管理系统,yarn 与 hdfs 和 mapReduce 的关系如下:
yarn 通过2类进程提供自己的服务
resource manager: 管理集群上的资源的资源管理器
node manager: 运行在节点上能够启动和监控容器的节点管理器
yarn的工作机制
- 提交mr程序到客户端节点
- 申请一个应用
- 提交资源路径,应用id
- 提交资源,切片 xml jar包
- 初始化ta's'k
- 在容器中创建master
yarn 中的调度
yarn 调度器的工作就是为资源调度指定策略
yarn 中有三种调度器
fifo调度器: 按照任务提交的顺序运行应用。 优点是简单易懂,不需要任何配置,但是不适合大型集群。大的应用会占用集群中的所有资源,导致其他应用无法运行
Capacity Scheduler 容量调度器: 有一个独立的专门队列保证小作业的执行,但是大作业的执行时间要长
Fair Scheduler 公平调度器:结合以上两者的优点,当第一个大作业启动时,获取集群中所有的资源,当小作业启动时,它被分配到集群的一部分资源,保证执行。需要注意的是,第二个小作业的时间会有滞后,必须要等待第一个作业使用的容器用完释放资源。公平调度器支持抢占功能