Hadoop
- Hadoop是一个由Apache基金会所开发的分布式系统基础架构
- 主要解决海量数据的存储和海量数据的分析计算问题
- 广义上来说,hadoop指代大数据的一个生态圈,包括很多其他的软件
Hadoop优势
(1)高可靠性:Hadoop底层维护多个数据副本,所以即使Hadoop某个计算元素或存储出现故障,也不会导致数据的丢失。
(2)高扩展性:在集群间分配任务数据,可方便的扩展数以千计的节点。
(3)高效性:在MapReduce的思想下,Hadoop是并行工作的,以加快任务处理速度。
(4)高容错性:能够自动将失败的任务重新分配。
分布式文件系统架构
- FS File System
- 文件系统是基于硬盘之上的一个文件管理的工具
- 我们用户操作文件系统可以和硬盘进行解耦
- DFS Distributed File System:
- 分布式文件系统
- 将我们的数据存放在多台电脑上存储
- 分布式文件系统有很多,
- HDFS是mapreduce计算的基础
文件切分思想
-
文件存放在一个磁盘上效率肯定是低的,如果文件特别大会超出单机的存储范围
-
文件在计算机都是以二进制存储的,我们可以理解为存放的都是字节数组,而数组可以拆分为多个更小的数据,所以文件也可以进行拆分,而我们使用的时候只需要将他们根据文件的偏移量将他们合并到一起就可以了
-
偏移量: 可以理解为 下标数组都有对应的索引(下标),可以快速的定位数据
-
Block拆分标准
-
数据块的个数 =Ceil( 文件大小 / 每个块的大小)
-
在HDFS中, 数据块等大是很多计算的前提,我们不能破坏
-
文件应该拆分成同样大小的块, 首先选定一个块的大小,然后将文件从头到尾开始切分. 从第一个快到倒数第二个块都是大小相同的,除了最后一个块
-
-
如果切分块的时候大小不一致,会引来什么问题?
-
每个磁盘存储的数据量大小不同,存储的时间不一致,拼接文件的时候, 我们必须等所有的块都找齐之后才能开始拼接
-
如果数据块大小不一致在设计算法的时候, 需要为单独的块设计算法读取时间和程序计算时间
-
-
是否能修改HDFS上的数据?
-
迁移数据量不可控
-
破坏了等大的特性
总结: 在HDFS上一但数据被上传,就不能修改,但是可以追加,追加功能默认是关闭的
-
Block数据安全
- 首先肯定要对数据做备份
- 备份的数据肯定不能存放在一个节点上
- 备份的数目不能超过集群的节点总数
- 默认情况下,每个数据都会有三个副本, 副本的数量是可以动态修改的,可以根据存储和效率取一个合适的值
Block的管理效率
- 需要专门给节点进行分工
- 存储 DataNode
- 数据存储节点, 要求有一定的容量
- 记录 NameNode
- 记录文件的数据信息,所有的操作都在内存中,文件存储的IO是不经过NameNode的
- 日志 secondaryNameNode
- 记录集群运行过程中的日志变化
- 存储 DataNode
HDFS的特点
-
优点
- a)高容错性
- i.保存多个副本,且提供容错机制。
- ii.副本丢失或宕机自动恢复。默认存3份。
- b)运行在廉价的机器上(商用机)
- i.通过副本提高可靠性
- ii.提供了容错和恢复机制
- c)适合批处理
- i.移动计算而非数据
- ii.数据位置暴露给计算框架。NameNode上有位置
- d)适合大数据的处理
- i.TB,甚至PB级数据
- ii.百万规模以上的文件数量
- iii.10K+节点规模
- e)流式数据访问
- i.一次写入,多次读取,高吞吐量,所以可以同时处理大量数据
- a)高容错性
-
缺点
- a)不擅长低延迟数据访问
- 比如毫秒级
- b)不擅长小文件的分区
- i.占用NameNode大量内存
- ii.磁盘寻道时间超过读取时间
- c)不擅长并发写入,文件随机修改
- i.一个文件只能有一个写入者
- ii.仅支持append,也就是添加(有组件实现删等)
- a)不擅长低延迟数据访问
Hadoop3完全分布式搭建
-
开启集群
- [root@node01 yjx]# start-dfs.sh
-
关闭集群
- [root@node01 ~]# stop-dfs.sh
Hadoop集群命令
命令分类
-
hadoop fs:
- 该命令可以用于其他文件系统,不止是hdfs文件系统内,也就是说该命令的使用范围更广
-
hadoop dfs
- 专门针对hdfs分布式文件系统
-
hdfs dfs(推荐)
- 和上面的命令作用相同,相比于上面的命令更为推荐,并且当使用hadoop dfs时内部会被转为hdfs dfs命令
Hadoop FS命令
-
调用文件系统(FS)Shell命令应使用 bin/hadoop fs 的形式。 所有的的FS shell命令使用URI路径作为参数
-
1 hadoop fs -ls <path> 列出指定目录下的内容,支持pattern匹配。输出格式如filename(full path)<r n>size.n代表备份数。2 hadoop fs -lsr <path> 递归列出该路径下所有子目录信息3 hadoop fs -du<path>显示目录中所有文件大小,或者指定一个文件时,显示此文件大小4 hadoop fs - dus<path>显示文件大小 相当于 linux的du -sb s代表显示只显示总计,列出最后的和 b代表显示文件大 小时以byte为单位5 hadoop fs -mv <src> <dst> 将目标文件移动到指定路径下,当src为多个文件, dst必须为目录6 hadoop fs -cp <src> <dst>拷贝文件到目标位置,src为多个文件时,dst必须是个目 录7 hadoop fs -rm [skipTrash] <src>删除匹配pattern的指定文件8 hadoop fs -rmr [skipTrash] <src>递归删除文件目录及文件9 hadoop fs -rmi [skipTrash] <src>为了避免误删数 据,加了一个确认10 hadoop fs -put <> ... <dst>从本地系统拷贝到dfs中11 hadoop fs - copyFromLocal<localsrc>...<dst>从本地系统拷贝到dfs中,与-put一样12 hadoop fs - moveFromLocal <localsrc>...<dst>从本地系统拷贝文件到dfs中,拷贝完删除源文件13 hadoop fs -get [-ignoreCrc] [-crc] <src> <localdst> 从dfs中拷贝文件到本地系统,文件匹配 pattern,若是多个文件,dst必须是个目录14 hadoop fs -getmerge <src> <localdst>从dfs中 拷贝多个文件合并排序为一个文件到本地文件系统15 hadoop fs -cat <src>输出文件内容16 hadoop fs -copyTolocal [-ignoreCre] [-crc] <src> <localdst>与 -get一致17 hadoop fs -mkdir <path>在指定位置创建目录18 hadoop fs -setrep [-R] [-w] <rep> <path/file>设置文件的备份 级别,-R标志控制是否递归设置子目录及文件19 hadoop fs -chmod [-R] <MODE[,MODE]...|OCTALMODE>PATH修改文件权限, -R递归修改 mode为a+r,g-w,+rwx ,octalmode 为75520 hadoop fs -chown [-R] [OWNER][:[GROUP]] PATH递归修改文件所有者和组21 hadoop fs -count[q] <path>统计文件个数及占空间情况,输出表格列的含义分别为: DIR_COUNT.FILE_COUNT.CONTENT_SIZE.FILE_NAME,如果加-q 的话,还会列出 QUOTA,REMAINING_QUOTA,REMAINING_SPACE_QUOTA
hdfs dfs命令
-
-mkdir 创建目录 hdfs dfs -mkdir [-p] < paths> -ls 查看目录下内容,包括文件名,权限,所有者,大小和修改时间 hdfs dfs -ls [-R] < args> -put 将本地文件或目录上传到HDFS中的路径 hdfs dfs -put < localsrc> … < dst> -get 将文件或目录从HDFS中的路径拷贝到本地文件路径 hdfs dfs -get [-ignoreCrc] [-crc] < src> < localdst> 选项:-ignorecrc选项复制CRC校验失败的文件。-crc选项复制文件和CRC。 -du 显示给定目录中包含的文件和目录的大小或文件的长度,用字节大小表示。 hdfs dfs -du [- s] [-h] URI [URI …] 选项:-s选项将显示文件长度的汇总摘要,而不是单个文件。-h选项将以“人可 读”的方式格式化文件大小(例如64.0m而不是67108864);第一列标示该目录下总文件大小,第二列标示该 目录下所有文件在集群上的总存储大小和你的副本数相关(第二列内容=文件大小*副本数),第三列标示你查 询的目录 -dus 显示文件长度的摘要。 hdfs dfs -dus < args> 注意:不推荐使用此命令。而是使用 hdfs dfs -du -s。 -mv 在HDFS文件系统中,将文件或目录从HDFS的源路径移动到目标路径。不允许跨文件系统移动文件。 -cp 在HDFS文件系统中,将文件或目录复制到目标路径下 hdfs dfs -cp [-f] [-p | -p [topax] ] URI [ URI …] < dest> 选项:-f选项覆盖已经存在的目标。-p选项将保留文件属性 [topx](时间戳,所有权,权限,ACL,XAttr)。如果指定了-p且没有arg,则保留时间戳,所有权和权 限。如果指定了-pa,则还保留权限,因为ACL是一组超级权限。确定是否保留原始命名空间扩展属性与-p标 志无关。 -copyFromLocal 从本地复制文件到hdfs文件系统(与-put命令相似)hdfs dfs -copyFromLocal < localsrc> URI 选项:如果目标已存在,则-f选项将覆盖目标。 -copyToLocal 复制hdfs文件系统中的文件到本地 (与-get命令相似) hdfs dfs - copyToLocal [-ignorecrc] [-crc] URI < localdst> -rm 删除一个文件或目录 hdfs dfs -rm [-f] [-r|-R] [-skipTrash] URI [URI …] 选 项:如果文件不存在,-f选项将不显示诊断消息或修改退出状态以反映错误。-R选项以递归方式删除目录及其 下的任何内容。-r选项等效于-R。-skipTrash选项将绕过垃圾桶(如果已启用),并立即删除指定的文件。 当需要从超配额目录中删除文件时,这非常有用。 -cat 显示文件内容到标准输出上。 hdfs dfs -cat URI [URI …] -text 获取源文件并以文本格式输出文件。允许的格式为zip和TextRecordInputStream。 hdfs dfs -text -touchz 创建一个零长度的文件。 hdfs dfs -touchz URI [URI …] -stat 显示文件所占块数(%b),文件名(%n),块大小(%n),复制数(%r),修改时间(%y%Y) hdfs dfs -stat URI [URI …] -tail 显示文件的最后1kb内容到标准输出 hdfs dfs -tail [-f] URI 选项: -f选项将 在文件增长时输出附加数据,如在Unix中一样。 -count 统计与指定文件模式匹配的路径下的目录,文件和字节数 hdfs dfs -count [-q] [-h] < paths> -getmerge 将源目录和目标文件作为输入,并将src中的文件连接到目标本地文件(把两个文件的内容合 并起来) hdfs dfs -getmerge < src> < localdst> [addnl] 注:合并后的文件位于当前目 录,不在hdfs中,是本地文件 -grep 从hdfs上过滤包含某个字符的行内容 hdfs dfs -cat < srcpath> | grep 过滤字段 -chown hdfs上文件权限修改 hadoop fs -chown [-R] [OWNER][:[GROUP]] URI [URI ]#修 改文件的所有者 例如:hdfs dfs -chown -R Administrator:Administrator /user/ -distcp 最常用在集群之间的拷贝:hadoop distcp hdfs://master1:8020/foo/bar hdfs://master2:8020/bar/foo
文件的数据类型
-
文件有一个stat命令
- 元数据信息–>描述文件的属性
-
文件有一个vim命令
- 查看文件的数据信息
-
分类
-
元数据
-
描述文件信息的数据
-
File 文件名 Size 文件大小(字节) Blocks 文件使用的数据块总数 IO Block 数据块的大小 regular file:文件类型(常规文件) Device 设备编号 Inode 文件所在的Inode Links 硬链接次数 Access 权限 Uid 属主id/用户 Gid 属组id/组名 Access Time:简写为atime,表示文件的访问时间。当文件内容被访问时,更新这个时间 Modify Time:简写为mtime,表示文件内容的修改时间,当文件的数据内容被修改时,更新这个 时间。 Change Time:简写为ctime,表示文件的状态时间,当文件的状态被修改时,更新这个时间,例 如文件的链接数,大小,权限,Blocks数。
-
-
真实数据
- 真实存在于文件中的数据
- 文件真正存放的内容,这个数据就是存储在硬盘上的二进制数据
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CrrpFs77-1656229012818)(C:\Users\胡MS\AppData\Roaming\Typora\typora-user-images\image-20220618082104567.png)]
-
NameNode(NN)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M0EqAgkN-1656229012820)(C:\Users\胡MS\AppData\Roaming\Typora\typora-user-images\image-20220617162658926.png)]
- 总结[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KZBXS5Mt-1656229012821)(C:\Users\胡MS\AppData\Roaming\Typora\typora-user-images\image-20220618082215813.png)]
功能
- 接受客户端的读写服务
NameNode存放文件与Block的映射关系
NameNode会记录Block与DataNode的映射关系,但是不会持久化
- 保存文件的元数据信息
文件的归属
文件的权限
文件的大小时间
Block信息,但是block的位置信息不会持久化,需要每次开启集群的时候DN上报
-
收集Block的信息
- 系统启动时
NN关机的时候是不会存储任意的Block与DN的映射信息 ,DN启动的时候,会将自己节点上存储的Block信息汇报给NN ,NN接受请求之后重新生成映射关系 Block–DN3 ,如果某个数据块的副本数小于设置数,那么NN会将这个副本拷贝到其他节点
- 集群运行中
NN与DN保持心跳机制,三秒钟发送一次,如果客户端需要读取或者上传数据的时候,NN可以知道DN的健康情况 ,可以让客户端读取存活的DN节点
-
如果DN超过三秒没有心跳,就认为DN出现异常
不会让新的数据读写到DataNode 客户访问的时候不提供异常结点的地址
如果DN超过10分钟+30秒没有心跳,那么NN会将当前DN存储的数据转存到其他节点
超时时长的计算公式为: timeout = 2 * heartbeat.recheck.interval + 10 * dfs.heartbeat.interval。 而默认的heartbeat.recheck.interval 大小为5分钟, dfs.heartbeat.interval默认为3秒。
性能
-
NameNode为了效率,将所有的操作都在内存中完成
NameNode不会和磁盘进行任何的数据交换
问题:
数据的持久化
数据保存在内存中,掉电易失
DataNode(DN)
- 总结
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tk7PZcIN-1656229012821)(C:\Users\胡MS\AppData\Roaming\Typora\typora-user-images\image-20220618082628523.png)]
功能
-
存放的是文件的数据信息和验证文件完整性的校验信息
数据会存放在硬盘上
1m=1条元数据 1G=1条元数据
NameNode非常排斥存储小文件,一般小文件在存储之前需要进行压缩
-
汇报
启动时
汇报之前先验证Block文件是否被损坏
向NN汇报当前DN上block的信息
运行中
向NN保持心跳机制
客户可以向DN读写数据,
-
当客户端读写数据的时候,首先去NN查询file与block与dn的映射
然后客户端直接与dn建立连接,然后读写数据
SecondaryNameNode
理解
效率:内存
安全:硬盘
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QZLApYgx-1656229012822)(E:\program\安装资料\笔记工具\Markdown\Big_Data\Linux\04.Hadoop\07.Secondary NameNode1.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZiotM438-1656229012822)(D:\应用软件\微信\WeChat Files\wxid_8da4dpgm117m22\FileStorage\MsgAttach\b8a278761eef1b34b8ccc096f5c25f0e\File\2022-06\Linux\04.Hadoop\07.Secondary NameNode2.png)]
传统解决方案
日志机制
-
做任何操作之前先记录日志 ,当NN下次启动的时候,只需要重新按照以前的日志“重做”一遍即可
-
缺点
edits文件大小不可控,随着时间的发展,集群启动的时间会越来越长
有可能日志中存在大量的无效日志
-
优点
绝对不会丢失数据
拍摄快照
-
关机时我们可以将内存中的数据写出到硬盘上
序列化
-
启动时还可以将硬盘上的数据写回到内存中
反序列化
-
缺点
关机时间过长
如果是异常关机,数据还在内存中,没法写入到硬盘
如果写出频率过高,导致内存使用效率低(stop the world) JVM
-
优点
启动时间较短
SNN解决方案
-
解决思路(日志edits+快照fsimage)
让日志大小可控 ,定时快照保存
-
NameNode文件目录
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x41NeW0V-1656229012823)(C:\Users\胡MS\AppData\Roaming\Typora\typora-user-images\image-20220618155730488.png)]
-
解决方案
-
当我们启动一个集群的时候,会产生四个文件
- edits_0000000000000000001
- fsimage_00000000000000000
- seen_txid
- VERSION
-
我们每次操作都会记录日志 -->edits_inprogress-000000001
-
随和时间的推移,日志文件会越来越大,当达到阈值的时候(64M 或 3600秒)
-
dfs.namenode.checkpoint.period 每隔多久做一次checkpoint ,默认3600s dfs.namenode.checkpoint.txns 每隔多少操作次数做一次checkpoint,默 认1000000次 dfs.namenode.checkpoint.check.period 每个多久检查一次操作次数,默认60s
-
-
会合并成新的日志文件
-
因为合并数据的时候需要占用和NameNode当前数据相等量的内存
-
然后将当前镜像与后续的日志进行叠加
-
如果放在NN中,NN压力太大,于是合并的操作就交给了SecondaryNameNode
-
但不可能NN每次执行都合并一次并写出,于是设置了一个阀值:
3600s与64M
-
SecondaryNameNode 工作流程
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eD1mArfo-1656229012823)(C:\Users\胡MS\AppData\Roaming\Typora\typora-user-images\image-20220618160510832.png)]
SNN数据恢复
-
强行杀死NameNode节点
- kill -9 7388
-
清空namenode下name中的fsimage和edtis文件
-
[root@node01 ~]# rm -rf /var/yjx/hadoop/full/dfs/name/current/*
-
-
secondary namenode下的name中的fsimage和edits复制到namenode对应文件夹中
-
[root@node01 ~]# scp -r root@node02:/var/yjx/hadoop/full/dfs/namesecondary/current/* /var/yjx/hadoop/full/dfs/name/current
-
启动namenode
- hadoop-daemon.sh start namenode
-
访问namenode节点页面,成功
-
[root@node01 ~]# rm -rf /var/yjx/hadoop/full/dfs/name/current/*
-
安全模式
-
集群启动时的一个状态
-
安全模式是HDFS的一种工作状态,处于安全模式的状态下,只向客户端提供文件的只读视图,不接受对命名空间的修改;同时NameNode节点也不会进行数据块的复制或者删除,
-
集群启动时 主节点先载入镜像文件(快照) 执行最新日志里的各项操作 创建新的日志
-
然后进入安全模式 数据节点向主节点汇报当前节点所拥有的有效节点
-
如果节点启动失败,块的副本数达不到最小要求,主节点会将块复制到其他数据节点上
-
-
NameNode启动时,
- 首先将镜像文件(fsimage)载入内存,并执行编辑日志(edits)中的各项操作。
- 一旦在内存中成功建立文件系统元数据的映像,则创建一个新的fsimage文件和一个空的编辑日志。
- NameNode开始监听RPC和Http请求。
- 此时NameNode处于安全模式,只接受客户端的读请求。
-
系统中的数据块的位置并不是由NameNode维护的,而是以块列表的形式存储在DataNode中。
-
安全模式下
- 安全模式下,各个DataNode会向NameNode发送自身的数据块列表
- 当NameNode有足够的数据块信息后,便在30秒后退出安全模式
- NameNode发现数据节点过少会启动数据块复制过程
-
如果NN收集的Block信息没有达到最少副本数,就会将缺失的副本,从有的DN上拷贝到其他DN
- dfs.replication.min=2
- 但是默认最低副本数为1
- 在拷贝的过程中系统还是处于安全模式
-
安全模式相关命令
-
hadoop dfsadmin -safemode leave 强制NameNode退出安全模式 hadoop dfsadmin -safemode enter 进入安全模式 hadoop dfsadmin -safemode get 查看安全模式状态 hadoop dfsadmin -safemode wait 等待一直到安全模式结束
-
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q19SCONS-1656229012823)(C:\Users\胡MS\AppData\Roaming\Typora\typora-user-images\image-20220618162400621.png)]
HDFS的权限
- HDFS对权限的控制
- 只能防止好人做错事
- 不能防止坏人做坏事
- 你告诉他你是谁,他就认为你是谁!
机架感知策略
就是块选择DateNode 的一种策略, 为了保证副本在集群的安全性
- 我们需要将副本放在不同的DN节点上,节点也需要一定的考量
- 可靠性、可用性、带宽消耗
- 第一个节点
- 集群内部(优先考虑和客户端相同节点作为第一个节点)
- 集群外部(选择资源丰富且不繁忙的节点为第一个节点)
- 第二个节点
- 选择和第一个节点不同机架的其他节点
- 第三个节点
- 与第二个节点相同机架的其他节点
- 第N个节点
- 与前面节点不重复的其他节点
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-maS5dv1u-1656229012824)(C:\Users\胡MS\AppData\Roaming\Typora\typora-user-images\image-20220618164633000.png)]
HDFS写数据流程
写数据就是将客户端的数据上传到HDFS
宏观流程
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yFZiYP0m-1656229012824)(C:\Users\胡MS\AppData\Roaming\Typora\typora-user-images\image-20220618165608147.png)]
- 客户端向HDFS发送写数据请求
- hdfs dfs -put tomcat.tar.gz /yjx/
- file system通过rpc调用namenode的create方法
- nn首先检查是否有足够的空间权限等条件创建这个文件,或者这个路径是否已经存在,权限
- 有:NN会针对这个文件创建一个空的Entry对象,并返回成功状态给DFS
- 没有:直接抛出对应的异常,给予客户端错误提示信息
- nn首先检查是否有足够的空间权限等条件创建这个文件,或者这个路径是否已经存在,权限
- DFS如果接收到成功状态,会创建一个FSDataOutputStream的对象给客户端使用
- 客户端需要向NN询问第一个Block存放的位置
- NN通过机架感知策略 (node1 node 2 node8)
- 需要将客户端和DN节点创建连接
- pipeline(管道)
- 客户端和node1创建连接 socket
- node1和node2创建连接 socket
- node2 和Node8创建连接 socket
- pipeline(管道)
- 客户端将文件按照块block切分数据, 并按照packet发送数据
- 默认一个packet大小为64K,Block128M为2048个packet
- 客户端通过pipeline管道开始使用FSDataOutputStream对象将数据输出
- 客户端首先将一个packet发送给node1,同时给予node1一个ack状态
- node1接受数据后会将数据继续传递给node2,同时给予node2一个ack状态
- node2接受数据后会将数据继续传递给node8,同时给予node8一个ack状态
- node8将这个packet接受完成后,会响应这个ack给node2为true
- node2会响应给node1 ,同理node1响应给客户端
- 客户端接收到成功的状态,就认为某个packet发送成功了,直到当前块所有的packet都发送完成
- 如果客户端接收到最后一个pakcet的成功状态,说明当前block传输完成,管道就会被撤销
- 客户端会将这个消息传递给NN,NN确认传输完成
- NN会将block的信息记录到Entry,客户端会继续向NN询问第二个块的存储位置,依次类推
- block1 (node1 node2 node8)
- block2 (node1 node8 node9)
- …
- blockn(node1 node7 node9)
- 当所有的block传输完成后,NN在Entry中存储所有的File与Block与DN的映射关系,关闭
FsDataOutPutStream
微观流程
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lUMBQ7Il-1656229012824)(C:\Users\胡MS\AppData\Roaming\Typora\typora-user-images\image-20220618165959733.png)]
- 首先客户端从自己的硬盘以流的方式读取数据文件到自己的缓存中
- 然后将缓存中的数据以chunk(512B)和checksum(4B)的方式放入到packet(64K)
- chunk:checksum=128:1
- checksum:在数据处理和数据通信领域中,用于校验目的的一组数据项的和
- Packet中的数据分为两类,一类是实际数据包,另一类是header包。
- 一个Packet数据包的组成结构
- 当packet满的时候 添加到 dataqueue ,
- data streamer开始从dataqueue队列上取出一个packet,通过FSDataOPS发送到Pipeline
- 在取出的时候,也会将packet加入到ackQueue,典型的生产者消费者模式
- 客户端发送一个Packet数据包以后开始接收ack,会有一个用来接收ack的Response Processor进程,如果收到成功的ack
- 如果某一个packet的ack为true,那么就从ackqueue删除掉这个packet
- 如果某一个packet的ack为false,将ackqueue中所有的packet重新挂载到 发送队列,重新发送
- 最终DFS保存的数据格式为
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1TkZ9LmQ-1656229012825)(C:\Users\胡MS\AppData\Roaming\Typora\typora-user-images\image-20220618170815140.png)]
HDFS读数据流程
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-udyUaZGF-1656229012825)(C:\Users\胡MS\AppData\Roaming\Typora\typora-user-images\image-20220618171357074.png)]
- 首先客户端发送请求到HDFS,申请读取某一个文件
- /yjx/tomcat.tar.gz
- HDFS去NN查找这个文件的信息(权限,文件是否存在)
- 如果文件不存在,抛出指定的错误
- 如果文件存在,返回成功状态
- HDFS创建FSDataInputStream对象,客户端通过这个对象读取数据
- 客户端获取文件第一个Block信息,返回DN1 DN2 DN8
- 客户端直接就近原则选择DN1对应的数据即可
- 依次类推读取其他块的信息,直到最后一个块,将Block合并成一个文件
- 关闭FSDataInputStream
- 首先客户端发送请求到HDFS,申请读取某一个文件
Hadoop1的困境
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NyVWYpNC-1656229012825)(C:\Users\胡MS\AppData\Roaming\Typora\typora-user-images\image-20220618171616621.png)]
- 单点故障
- 每个群集只有一个NameNode,NameNode存在单点故障(SPOF)。
- 如果该计算机或进程不可用,则整个群集在整个NameNode重新启动或在另一台计算机上启动之前将不可用
- 如果发生意外事件(例如机器崩溃),则在操作员重新启动NameNode之前,群集将不可用。
- 计划内的维护事件,例如NameNode计算机上的软件或硬件升级,将导致群集停机时间的延长。
- 水平扩展
- 将来服务器启动的时候,启动速度慢
- NameNode随着业务增多.内存占用也会越来越多
- 如果namenode内存占满,将无法继续提供服务
- 业务隔离性差
- 存储 : 有可能我们需要存储不同部门的数据
- 计算:有可能存在不同业务的计算流程
- 项目后期NanmeNode的吞吐量会是集群的瓶颈
- 客户端的所有请求都会先访问NameNode
- Hadoop2.x
- NameNode节点的高可用
- HA–high availability (解决Name Node的高可用问题)
- NameNode业余的水平扩展
- Federation (联邦机制)
- NameNode节点的高可用
Hadoop-HA
- 所谓HA(High Availablity),即高可用(7*24小时不中断服务)。
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tIQe7zxU-1656229012826)(C:\Users\胡MS\AppData\Roaming\Typora\typora-user-images\image-20220618175230215.png)]
设计思想
- hadoop2.x启用了主备节点切换模式(1主1备)
- 当主节点出现异常的时候,集群直接将备用节点切换成主节点
- 要求备用节点马上就要工作
- 主备节点内存几乎同步
- 有独立的线程对主备节点进行监控健康状态
- 需要有一定的选举机制,帮助我们确定主从关系
- 我们需要实时存储日志的中间件
ANN (主 NameNode )
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v5yIg5iO-1656229012826)(C:\Users\胡MS\AppData\Roaming\Typora\typora-user-images\image-20220618175312378.png)]
-
Active NameNode 的功能和原理的NN的功能是一样的
-
接受客户端请求,查询数据块DN信息
-
存储数据的元数据信息
- 数据文件:Block:DN的映射关系
-
工作
- 启动时:接受DN的block汇报
- 运行时:和DN保持心跳(3s,10m30s)
-
存储介质
- 完全基于内存
- 优点:数据处理效率高
- 缺点:数据的持久化(日志edits+快照fsimage
SNN (备用 NameNode)
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7fxCQBAv-1656229012827)(C:\Users\胡MS\AppData\Roaming\Typora\typora-user-images\image-20220618175955430.png)]
-
Standby NameNode:NN的备用节点
-
他和主节点做同样的工作,但是它不会发出任何指令
-
存储:数据的元数据信息
- 数据文件:Block:DN的映射关系
它的内存数据和主节点内存数据几乎是一致的
- 数据文件:Block:DN的映射关系
-
工作
- 启动时
- 接受DateNode的block汇报
- 运行时
- 和DateNode保持心跳(3s, 10m30s)
- 启动时
-
存储介质
- 完全基于内存
优点:数据处理效率高
缺点:数据的持久化
- 完全基于内存
-
合并日志和镜像
-
当搭建好集群的时候,格式化主备节点的时候,ANN和SNN都会会默认创建
-
当我们操作HDFS的时候ANN会产生日志信息
-
主节点会将日志文件中新增的数据同步到JournalNode集群上
-
所以只需要snn有操作的日志信息,就可以合并fsImage与edits信息,理论上是一直在合并数据
-
SNN将合并好的Fsimage发送给ANN,ANN验证无误后,存放到自己的目录中
-
DataNode (数据节点)
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wEMOBG2q-1656229012827)(C:\Users\胡MS\AppData\Roaming\Typora\typora-user-images\image-20220619160507423.png)]
-
存储
- 文件的Block文件
-
介质
- 硬盘
-
启动时
- 同时向两个NN汇报Block信息
-
运行中
- 同时和两个NN节点保持心跳机制
QJM (日志节点)
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8YJJOvbv-1656229012827)(C:\Users\胡MS\AppData\Roaming\Typora\typora-user-images\image-20220619160849482.png)]
-
Quorum JournalNode Manager 共享存储系统,NameNode通过共享存储系统实现日志数据同步。
-
JournalNode是一个独立的小集群,它的实现原理和Zookeeper的一致( Paxos)
-
ANN产生日志文件的时候,就会同时发送到 JournalNode的集群中每个节点上
-
JournalNode不要求所有的jn节点都接收到日志,只要有半数以上的(n/2+1)节点接受收到日志,那么本条日志就生效
-
SNN每间隔一段时间就去QJM上面取回最新的日志
- SNN上的日志有可能不是最新的
-
HA集群的状态正确至关重要,一次只能有一个NameNode处于活动状态。
-
JournalNode只允许单个NameNode成为作者。在故障转移期间,将变为活动状态的NameNode将承担写入JournalNodes的角色,这将有效地防止另一个NameNode继续处于活动状态,从而使新的Active节点可以安全地进行故障转移
ZKFC (主节点故障转移控制器)
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Mc63ynOt-1656229012828)(C:\Users\胡MS\AppData\Roaming\Typora\typora-user-images\image-20220619162006808.png)]
-
Failover Controller(故障转移控制器)
-
对 NameNode 的主备切换进行总体控制,能及时检测到 NameNode 的健康状况
- 在主 NameNode 故障时借助 Zookeeper 实现自动的主备选举和切换
- 为了防止因为NN的GC失败导致心跳受影响,ZKFC作为一个deamon进程从NN分离出来
-
启动时:
- 当集群启动时,主备节点的概念是很模糊的
- 当ZKFC只检查到一个节点是健康状态,直接将其设置为主节点
- 当zkfc检查到两个NN节点是的健康状态,发起投票机制
- 选出一个主节点,一个备用节点,并修改主备节点的状态
-
运行时:
- 由 ZKFailoverController、HealthMonitor 和 ActiveStandbyElector 这 3 个组件来协同实现主备切换
- ZKFailoverController启动的时候会创建 HealthMonitor 和
- ActiveStandbyElector 这两个主要的内部组件
- HealthMonitor 主要负责检测 NameNode 的健康状态
- ActiveStandbyElector 主要负责完成自动的主备选举,内部封装了 Zookeeper 的处理逻辑
- 由 ZKFailoverController、HealthMonitor 和 ActiveStandbyElector 这 3 个组件来协同实现主备切换
-
主备节点正常切换
- NameNode 在选举成功后,ActiveStandbyElector会在 zk 上创建一个
ActiveStandbyElectorLock 临时节点,而没有选举成功的备 NameNode 中的
ActiveStandbyElector会监控这个节点 - 如果 Active NameNode 对应的 HealthMonitor 检测到 NameNode 的状态异常时,
ZKFailoverController 会主动删除当前在 Zookeeper 上建立的临时节点
ActiveStandbyElectorLock - 如果是 Active NameNode 的机器整个宕掉的话,那么跟zookeeper连接的客户端线程也挂了,会话结束,那么根据 Zookeepe的临时节点特性,ActiveStandbyElectorLock 节点会自动被删除,从而也会自动进行一次主备切换
- 处于 Standby 状态的 NameNode 的 ActiveStandbyElector 注册的监听器就会收到这个节点的 NodeDeleted 事件,并创建 ActiveStandbyElectorLock 临时节点,本来处于 Standby 状态的 NameNode 就选举为Active NameNode 并随后开始切换为 Active 状态。
- NameNode 在选举成功后,ActiveStandbyElector会在 zk 上创建一个
Zookeeper (集群)
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D6o5eJ6O-1656229012828)(C:\Users\胡MS\AppData\Roaming\Typora\typora-user-images\image-20220619162534906.png)]
-
为主备切换控制器提供主备选举支持。
-
辅助投票
-
和ZKFC保持心跳机制,确定ZKFC的存活
脑裂brain-split
定义:
脑裂是Hadoop2.X版本后出现的全新问题,实际运行过程中很有可能出现两个namenode同时服务于整个集群的情况,这种情况称之为脑裂。
原因:
脑裂通常发生在主从namenode切换时,由于ActiveNameNode的网络延迟、设备故障等问题,另一个NameNode会认为活跃的NameNode成为失效状态,此时StandbyNameNode会转换成活跃状态,此时集群中将会出现两个活跃的namenode。因此,可能出现的因素有网络延迟、心跳故障、设备故障等。
脑裂场景:
NameNode 可能会出现这种情况,NameNode 在垃圾回收(GC)时,可能会在长时间内整个系统无响应
zkfc客户端也就无法向 zk 写入心跳信息,这样的话可能会导致临时节点掉线,备 NameNode
会切换到 Active 状态
这种情况可能会导致整个集群会有同时有两个Active NameNode
解决方案:
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PDJ0DAcN-1656229012828)(C:\Users\胡MS\AppData\Roaming\Typora\typora-user-images\image-20220619164145747.png)]
方案一:
- 每当ANN成功竞选之后, 会创建一个临时节点和一个正常节点
- 当ANN主动下线后临时节点和正常节点都会儿被删除
- 如果ANN发现, 临时节点与正常节点都不存在, 自己就可以放心的切换成为主节点
- 首先和原来ANN进行联系,RPC调用ANN的ActiveBreadCrumb方法, 尝试将主切换为备用
- sshfence: 通过SSH登录到目标机器上, 执行fuser将对应的进程杀死
- 当原来的ANN被处理后, 现在SNN开始调用becomeActive成为主节点,开始对外提供服务
- 新ANN的ZFKFC也会在ZK赏面创建自己的临时节点和正常节点
方案二:
- 每当ANN成功竞选之后, 会创建一个临时节点和一个正常节点
- 当ANN被动下线后临时节点会被删除,正常节点会被保留
- 如果ANN发现, 临时节点被删除, 正常节点存在 , 集群有可能发生脑裂
- 然后如果RPC转换失败,会执行预定义的隔离措施
- shellfence: 执行用户自定义的shell脚本来将对应的进程隔离
- 当原来的ANN被处理后, 现在SNN开始调用becomeActive成为主节点,开始对外提供服务
- 新ANN的ZFKFC也会在ZK赏面创建自己的临时节点和正常节点
如果集群发生脑裂,我们要保证只有一个NN的命令是有效的, 即使有多个NN发送指令, 倒是只有一个命令会被认可
- 每次NN发送指令的时候,都会带一个序列号
- 每次选举之后, ANN会将新的序列号发送给DN
- 如果出现脑裂, 多个NN发送指令, DN会以最新的指令为准
Hadoop-Federation
- 联邦机制
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bcuxyIyx-1656229012829)(C:\Users\胡MS\AppData\Roaming\Typora\typora-user-images\image-20220619172255401.png)]
单NN局限性
- Namespace(命名空间)的限制
- NameNode所能存储的对象(文件+块)数目受到NameNode所在JVM的heap size的限制。
- 50G的heap能够存储20亿(200million)个对象,这20亿个对象支持4000个DataNode,12PB的存储
- DataNode从4T增长到36T,集群的尺寸增长到8000个DataNode。存储的需求从12PB增长到大于100PB。
- 性能的瓶颈
- 整个HDFS文件系统的吞吐量受限于单个Namenode的吞吐量
- 隔离问题
- HDFS上的一个实验程序就很有可能影响整个HDFS上运行的程序
- 集群的可用性
- Namenode的宕机无疑会导致整个集群不可用。
- Namespace和Block Management的紧密耦合
- 纵向扩展目前的Namenode不可行
- 将Namenode的Heap空间扩大到512GB启动花费的时间太长
- Namenode在Full GC时,如果发生错误将会导致整个集群宕机
Hadoop3.x新特性
Erasure Encoding
-
简介
- HDFS默认情况下,Block的备份系数是3,一个原始数据块和其他2个副本。
- 其中2个副本所需要的存储开销各站100%,这样使得200%的存储开销
- 正常操作中很少访问具有低IO活动的冷数据集的副本,但是仍然消耗与原始数据集相同的资源量。
-
EC技术
- EC(擦除编码)和HDFS的整合可以保持与提供存储效率相同的容错。
- HDFS:一个副本系数为3,要复制文件的6个块,需要消耗6*3=18个块的磁盘空间
- EC:6个数据块,3个奇偶校验块
- 擦除编码需要在执行远程读取时,对数据重建带来额外的开销,因此他通常用于存储不太频繁访问的数据
- EC(擦除编码)和HDFS的整合可以保持与提供存储效率相同的容错。
NameNode
- 在Hadoop3中允许用户运行多个备用的NameNode。
- 例如,通过配置三个NameNode(1个Active NameNode和2个StandbyNameNode)和5个JournalNodes节点
- 集群可以容忍2个NameNode节点故障。
服务器端口
- 早些时候,多个Hadoop服务的默认端口位于Linux端口范围以内。
因此,具有临时范围冲突端口已经被移除该范围 - [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rJf2Awkt-1656229012829)(C:\Users\胡MS\AppData\Roaming\Typora\typora-user-images\image-20220620161059618.png)]
DataNode
- 单个数据节点配置多个数据磁盘,在正常写入操作期间,数据被均匀的划分,因此,磁盘被均匀填充。
- 在维护磁盘时,添加或者替换磁盘会导致DataNode节点存储出现偏移
- 这种情况在早期的HDFS文件系统中,是没有被处理的。
- Hadoop3通过新的内部DataNode平衡功能来处理这种情况,这是通过hdfs diskbalancer CLI来进行调用的。执行之后,DataNode会进行均衡处理
蚊子腿
-
Yarn:
提供YARN的时间轴服务V.2,以便用户和开发人员可以对其进行测试,并提供反馈意见 -
优化Hadoop Shell脚本
-
重构Hadoop Client Jar包
-
支持随机Container
-
MapReduce任务级本地优化
-
支持文件系统连接器
Hadoop-MapReduce
MapReduce计算框架必须基于HSDFS之上, 他是一个离线的计算框架, 所以有很高的延迟性,
MapReduce设计理念
- map–>映射(key value)
- reduce–>归纳
- mapreduce必须构建在hdfs之上一种大数据离线计算框架
- 在线:随时对数据进行计算, 马上得到结果
- 离线:处理的是历史数据不要求马上得到结果
- mapreduce不会马上得到结果,他会有一定的延时
- 如果数据量小,使用mapreduce反而不合适
- 杀鸡用牛刀
- 原始数据–>map(Key,Value)–>Reduce
- 分布式计算
- 将大的数据切分成多个小数据,交给更多的节点参与运算
- 计算向数据靠拢
- 一切都是计算向数据靠拢
MapReduce 优缺点
优点
1 )MapReduce 易于编程
它简单的实现一些接口, 就可以完成一个分布式程序, 这个分布式程序可以分布到大量廉价的 PC 机器上运行。也就是说你写一个分布式程序,跟写一个简单的串行程序是一模一样的。就是因为这个特点使得 MapReduce 编程变得非常流行。
2 ) 良好的扩展性
当你的计算资源不能得到满足的时候, 你可以通过简单的增加机器来扩展它的计算能力。
3 ) 高容错性
MapReduce 设计的初衷就是使程序能够部署在廉价的 PC 机器上, 这就要求它具有很高的容错性。比如其中一台机器挂了,它可以把上面的计算任务转移到另外一个节点上运行,不至于这个任务运行失败, 而且这个过程不需要人工参与, 而完全是由Hadoop内部完成的。
4 ) 适合 PB 级以上海量数据的离线处理
可以实现上千台服务器集群并发工作,提供数据处理能力。
缺点
1 ) 不擅长实时计算
MapReduce 无法像 MySQL 一样,在毫秒或者秒级内返回结果。
2 ) 不擅长流式计算
流式计算的输入数据是动态的, 而 MapReduce 的输入数据集是静态的, 不能动态变化。
这是因为 MapReduce 自身的设计特点决定了数据源必须是静态的。
3 ) 不擅长 DAG (有向无环图)计算
多个应用程序存在依赖关系,后一个应用程序的输入为前一个的输出。在这种情况下,MapReduce 并不是不能做, 而是使用后, 每个 MapReduce 作业的输出结果都会写入到磁盘,会造成大量的磁盘 IO,导致性能非常的低下。
MR的计算流程
原始数据 File
将1T数据切分成块 存放在HDFS上 每一块128M
数据块Block
块的大小一样且不可改变 可能出现块的数量和集群计算能力不匹配 需要一个单位进行动态调节
切片Split
切片是一个逻辑概念,在不改变数据存储情况下,控制参与计算的节点数目
一个切片对应一个MapTask映射任务,一般切片大小为Block的整数倍(2 1/2)
计算节点 MapTask
map默认每次从切片中读取一行到内存中进行计算,这会产生大量临时数据 内存空间大小有限
存硬盘效率太低 此时提出了 环形数据缓冲区 的方案用来解决
环形数据缓冲区
在内存中构建了一个100M的环形数据缓存区,设阈值为80%,当数据达到80M时开始向硬盘中溢写数据
同时还剩20M的空间可以使用效率不会被减缓,数据写到硬盘后腾出空间可以继续运算
存储到硬盘的过程中
**分区Partation:**根据Key直接计算出对应的Reduce Key指我需要的结果
**排序Sort:**将溢写的数据按照先 Partation(分区)后以Key的顺序进行排序
**溢写Spill:**将内存计算后的数据存储到硬盘上,避免OOM 每次产生一个80M的文件
从硬盘中取每个节点数据结果时
**合并Merge:**溢写会产生很多有序的小文件,将这些有序的文件合并成一个有序的大文件, 就是把每个计算节点生成的好几个80m的小文件合成一个大的结果 ,合并小文件的时候同时进行排序(归并排序),最终产生一个有序的大文件 计算节点数量=文件数量
组合器combiner
对每一个maptask的输出进行局部汇总,以减小网络传输量
最后汇总数据
**拉取Fetch:**将Map的临时结果拉取到对应Reduce节点 相同的Key必须拉取到同一个Reduce节点 Reduce节点可以有多个Key, 就是说从每个结算节点的计算结果中拉取需要的数据,因为有多个计算节点所以会拉取到好几份数据
**合并Merge:**拉取的时候会从多个Map中拉取数据, 将这些有序的小文件再归并成大文件
写出Output:最后将结果写出:每个reduce将自己计算的最终结果都会存放到HDFS上
原始数据File
- 1T数据被切分成块存放在HDFS上,每一个块有128M大小
数据块Block
- hdfs上数据存储的一个单元,同一个文件中块的大小都是相同的
因为数据存储到HDFS上不可变,所以有可能块的数量和集群的计算能力不匹配
我们需要一个动态调整本次参与计算节点数量的一个单位
我们可以动态的改变这个单位–》参与的节点
切片Split
- 切片是一个逻辑概念
- 在不改变现在数据存储的情况下,可以控制参与计算的节点数目
- 通过切片大小可以达到控制计算节点数量的目的
- 有多少个切片就会执行多少个Map任务
- 一般切片大小为Block的整数倍(2 1/2)
- 防止多余创建和很多的数据连接
- 如果Split>Block ,计算节点少了
- 如果Split<Block ,计算节点多了
- 默认情况下,Split切片的大小等于Block的大小 ,默认128M
- 一个切片对应一个MapTask
MapTask
- map默认从所属切片读取数据,每次读取一行(默认读取器)到内存中
- 我们可以根据自己书写的分词逻辑(空格分隔).计算每个单词出现的次数
- 这是就会产生 (Map<String,Integer>)临时数据,存放在内存中
- 但是内存大小是有限的,如果多个任务同时执行有可能内存溢出(OOM)
- 如果把数据都直接存放到硬盘,效率太低
- 我们需要在OOM和效率低之间提供一个有效方案
- 可以现在内存中写入一部分,然后写出到硬盘
环形数据缓冲区
可以循环利用这块内存区域,减少数据溢写时map的停止时间
-
每一个Map可以独享的一个内存区域
在内存中构建一个环形数据缓冲区(kvBuffer),默认大小为100M
设置缓冲区的阈值为80%,当缓冲区的数据达到80M开始向外溢写到硬盘
溢写的时候还有20M的空间可以被使用效率并不会被减缓
而且将数据循环写到硬盘,不用担心OOM问题 -
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TOBr2rYj-1656229012829)(C:\Users\胡MS\AppData\Roaming\Typora\typora-user-images\image-20220620171951211.png)]
分区Partation
- 根据Key直接计算出对应的Reduce
分区的数量和Reduce的数量是相等的
hash(key) % partation = num
默认分区的算法是Hash然后取余
Object的hashCode()—equals()
如果两个对象equals,那么两个对象的hashcode一定相等
如果两个对象的hashcode相等,但是对象不一定equlas
排序Sort
- 对要溢写的数据进行排序(QuickSort)
按照先Partation后Key的顺序排序–>相同分区在一起,相同Key的在一起
我们将来溢写出的小文件也都是有序的
溢写Spill
- 将内存中的数据循环写到硬盘,不用担心OOM问题
每次会产生一个80M的文件
如果本次Map产生的数据较多,可能会溢写多个文件
合并Merge
- 因为溢写会产生很多有序(分区 key)的小文件,而且小文件的数目不确定
后面向reduce传递数据带来很大的问题
所以将小文件合并成一个大文件,将来拉取的数据直接从大文件拉取即可
合并小文件的时候同样进行排序(归并排序),最终产生一个有序的大文件
组合器combiner
combiner的意义就是对每一个maptask的输出进行局部汇总,以减小网络传输量。
拉取Fetch
- 我们需要将Map的临时结果拉取到Reduce节点
- 原则:
- 相同的Key必须拉取到同一个Reduce节点
- 但是一个Reduce节点可以有多个Key
- 未排序前拉取数据的时候必须对Map产生的最终的合并文件做全序遍历
- 而且每一个reduce都要做一个全序遍历
- 如果map产生的大文件是有序的,每一个reduce只需要从文件中读取自己所需的即可
合并Merge
- 因为reduce拉取的时候,会从多个map拉取数据
那么每个map都会产生一个小文件,这些小文件(文件与文件之间无序,文件内部有序)
为了方便计算(没必要读取N个小文件),需要合并文件
归并算法合并成2个(qishishilia)
相同的key都在一起
归并Reduce
- 将文件中的数据读取到内存中
一次性将相同的key全部读取到内存中
直接将相同的key得到结果–>最终结果
写出Output
- 每个reduce将自己计算的最终结果都会存放到HDFS上
yarn 架构
yarn是Hadoop集群的资源管理者
-
client
- 客户端发送mr任务到集群
- 客户端的种类有很多种
-
ResourceManager
- 资源协调框架的管理者
- 分为主节点和备用节点(防止单点故障)
- 主备的切换基于Zookeeper进行管理
- 时刻与NodeManager保持心跳,接受NodeManager的汇报
- NodeManager汇报当前节点的资源情况
- 当有外部框架要使用资源的时候直接访问ResourceManager即可
- 如果有MR任务,先去ResourceManager申请资源,ResourceManager根据汇报相对灵活分配资源
- 资源在NodeManager1,NodeManager1要负责开辟资源
-
NodeManager
- 资源协调框架的执行者
- 每一个DataNode上默认有一个NodeManager
NodeManager汇报自己的信息到ResourceManager
-
Container
- 2.x资源的代名词
- Container动态分配的
-
ApplicationMaster
- 我们本次JOB任务的主导者
- 负责调度本次被分配的资源Container
- 当所有的节点任务全部完成,application告诉ResourceManager请求杀死当前
- ApplicationMaster线程
- 本次任务所有的资源都会被释放
-
Task(MapTask–ReduceTask)
- 开始按照MR的流程执行业务
- 当任务完成时,ApplicationMaster接收到当前节点的回馈
-
四大组件:(四个进程)
ResourceManager(Rm):主进程
Nodemanager(NM):各个机器节点管理器
ApplicationMaster(AM):申请资源
Container容器:处理各个节点分布式作业的
yarn工作流程
(1) MR程序提交到客户端所在的节点。
(2)Yarn Runner向ResourceManager申请一个Application。
(3)RM将该应用程序的资源路径返回给YarnRunner。
(4)该程序将运行所需资源提交到HDFS上。
(5)程序资源提交完毕后,申请运行mrAppMaster。
(6)RM将用户的请求初始化成一个Task。
(7)其中一个NodeManager领取到Task任务。
(8)该NodeManager创建容器Container,并产生MAppmaster。
(9)Container从HDFS上拷贝资源到本地。
(10)MRAppmaster向RM 申请运行MapTask资源。
(11)RM将运行MapTask任务分配给另外两个NodeManager,另两个NodeManager分别领取任务并创建容器。
(12)MR向两个接收到任务的NodeManager发送程序启动脚本,这两个NodeManager分别启动MapTask,MapTas对数据分区排序。
(13)MrAppMaster等待所有MapTask运行完毕后,向RM申请容器,运行ReduceTask。
(14)ReduceTask向MapTask获取相应分区的数据。
(15)程序运行完毕后,MR会向RM申请注销自己。
- 步骤1 用户向YARN中提交应用程序,其中包括ApplicationMaster程序、启动ApplicationMaster的命令、用户程序等。
- 步骤2 ResourceManager为该应用程序分配第一个Container,并与对应的Node-Manager通信,要求它在这个Container中启动应用程序和ApplicationMaster。
- 步骤3 ApplicationMaster首先向ResourceManager注册,这样用户可以直接通过ResourceManager查看应用程序的运行状态,然后它将为各个任务申请资源,并监控它的运行状态,直到运行结束,即重复步骤4~7。
- 步骤4 ApplicationMaster采用轮询的方式通过RPC协议向ResourceManager申请和领取资源。
- 步骤5 一旦ApplicationMaster申请到资源后,便与对应的NodeManager通信,要求它启动任务。
- 步骤6 NodeManager为任务设置好运行环境(包括环境变量、JAR包、二进制程序等)后,将任务启动命令写到一个脚本中,并通过运行该脚本启动任务。
- 步骤7 各个任务通过某个RPC协议向ApplicationMaster汇报自己的状态和进度,以让ApplicationMaster随时掌握各个任务的运行状态,从而可以在任务失败时重新启动任务。 在应用程序运行过程中,用户可随时通过RPC向ApplicationMaster查询应用程序的当前运行状态。
- 步骤8 应用程序运行完成后,ApplicationMaster向ResourceManager注销并关闭自己。