Hadoop原理(总)–HDFS+MapReduce+Yarn

内容大纲介绍
  • Hadoop原理–HDFS相关
  • Hadoop原理–MapReduce相关
  • Hadoop原理–Yarn相关

1.HDFS原理–分布式介绍
问: 为什么要用分布式存储?  也可能会问: 分布式存储解决了什么问题?
答案: 分布式存储解决了单机存储容量有限的问题, 且带来了比较高的性能提升. 例如: 3台服务器, 就是3倍的传输效率, 读写效率...
    细节: 横向扩展 = 加机器,  纵向扩展 = 加配置(硬件)
2.HDFS原理–架构图

Hadoop的架构图链接

问: 简述HDFS的架构及各节点的角色?
答案:
    namenode: 主节点.
        1. 管理整个HDFS集群.
        2. 维护和管理元数据.
    SecondaryNameNode: 辅助节点.
        辅助namenode维护和管理元数据的.
    datanode: 从节点.
        1. 存储具体的数据.
        2. 负责源文件的读写操作.
        3. 定时和namenode发送心跳包.

在这里插入图片描述

3.HDFS原理–分块存储
问: 简述你对HDFS的分块存储机制的理解.
答案:
    1. 分块存储是为了方便统一管理的, 默认的块大小为: 128MB.    
    细节: Hadoop2.X开始才是128MB, Hadoop1.X是: 64MB.
    2. 副本机制是为了提高容错率, 副本数越多, 容错率越高.    
    带来的弊端是: 磁盘利用率下降了.
    3. 实际开发中, 建议副本数为: 2 ~ 5
    4. 如果要修改block块的大小 和 默认的副本数, 可以去: Hadoop的配置文件中修改.
        路径为:
            /export/server/hadoop/etc/hadoop/hdfs-site.xml
        官方配置文档路径为:
            https://hadoop.apache.org/docs/r3.3.0
            https://hadoop.apache.org/docs/r3.3.0/hadoop-project-dist/hadoop-hdfs/hdfs-default.xml
        参考配置信息如下:
            <!---->
            <!--设置: 副本数-->
            <property>
                <name>dfs.replication</name>
                <value>3</value>
            </property>

            <!--设置: 每个块的默认大小-->
            <property>
                <name>dfs.blocksize</name>
                <value>134217728</value>
                <description>设置HDFS块大小,单位是b</description>
            </property>
4.HDFS原理–namenode如何管理元数据
问: namenode是如何维护和管理元数据的?
答案:
    1. namenode是通过一批Edits(小) 和 1个FSImage(大)两类文件来维护和管理元数据的.
    2. Edits文件相对较小, 操作起来速度相对较快, 它只记录HDFS最近一段状态的元数据信息.
       阈值: 1个小时 或者 100W次
    3. FSImage文件相对较大, 操作起来速度相对较慢, 它记录的是HDFS集群除最近状态外, 其它所有的元数据信息.
    4. HDFS集群启动的时候, 会自动加载FSImage文件 和 最新的Edits文件进内存, 用于记录元数据.
       整个过程称为HDFS的自检动作, 此状态下, HDFS集群会强制进入到安全模式, 只能读, 不能写.
    5. 我们HDFS集群的Edits文件和FSImage文件存储在: /export/data/hadoop/dfs/name/current

在这里插入图片描述

5.HDFS原理–SecondaryNameNode如何辅助namenode管理元数据
问: SecondaryNameNode是如何辅助namenode管理元数据的?
    1. SecondaryNameNode会间隔60s(秒), 询问一次namenode, edits文件是否满足了阈值(1个小时, 或者100W次)
    2. 如果满足条件, 就通知namenode创建新的Edits文件, 继续往里写入元数据信息.
    3. 根据http协议, 从namenode上把要合并的edits文件 和 fsimage文件拉取到本地进行合并.
    4. 将合并后的新的FSImage文件推送给namenode, 用来替换之前旧的FsImage文件.
       细节: 旧的FSImage文件并不会被立即删除, 而是达到一定的阈值后, 才会被删除.
    5. 对于Edits文件和FSImage文件的合并操作, 是由SecondaryNameNode独立完成的, 全程namenode不参与.
    6. 实际开发中, namenode 和 SecondaryNameNode会被部署到不同的服务器上, 配置几乎一致, 只不过SecondaryNameNode的内存要稍大一些.
    7. 在紧急情况下, SecondaryNameNode可以用来恢复namenode的元数据.

在这里插入图片描述

6.HDFS原理–三大机制详解
  • 三大机制指的是: 副本机制, 负载均衡, 心跳机制
    在这里插入图片描述
问: HDFS的三大机制及副本存储?
心跳机制:
	1.datanode会定时(3秒)向namenode发送心跳包,告诉namenode,我还活着.
	2.如果超过一定时间(630秒),namenode没收到datanode的心跳包,就认为它宕机了此时就会将该datanode的块信息,交由其它活跃的datanode来存储.
	3.所有的datanode会定时(6个小时),向namenode汇报一次自己完整的块信息,namenode校验更新
负载均衡:
	namenode会保证所有的datanode的资源使用率,尽量保持一致
副本机制:
	可以提高容错率,默认的副本数是: 3
	如果当前副本总数 > 默认的副本数(3),namenode会自动删除某个副本
	如果当前副本总数 < 默认的副本数(3),namenode会自动增加该副本。
	如果当前活跃的机器总数< 默认的副本数(3),例如: 默认3副本,但是现在只有2台机器活跌了就会强制进入到 安全模式(safemode), 安全模式下: 只能读,不能写.
更多配置,详见Hadoop官方文档:
https://hadoop. apache. org/docs/r3.3. 0/hadoop-project-dist/hadoop-hdfs/hdfs-default.xml

在这里插入图片描述

7.HDFS原理–HDFS写数据流程
问: 请简述你对HDFS的写数据流程的理解?
答案:
    1. Client(客户端)请求namenode, 上传文件.
    2. namenode接收到客户端请求后, 会校验权限, 并告知客户端是否可以上传.
       校验: 客户端是否有写的权限, 及文件是否存在.
    3. 如果可以上传, 客户端会按照128MB(默认)对文件进行切块.
    4. Client(客户端)再次请求namenode, 第1个Block块的上传位置.
    5. namenode会根据副本机制, 负载均衡, 机架感知原理及网络拓扑图, 返回给客户端存储该Block块的DataNode列表.
        例如: node1, node2, node3
    6. Client(客户端)会先连接就近的datanode机器, 然后依次和其他的datanode进行连接, 形成: 传输管道(Pipeline)
    7. 采用数据报包(DataPacket)的形式传输数据, 每个包的大小不超过: 64KB, 并建立: 反向应答机制(ACK机制)
    8. 具体的上传动作: node1 -> node2 -> node3,  ACK反向应答机制: node3 => node2 => node1
    9. 重复上述的步骤, 直至第1个Block块上传完毕.
    10. 返回第4步, 客户端(Client)重新请求第2个Block的上传位置, 重复上述动作, 直至所有的Block块传输完毕.
        至此, HDFS写数据流程结束.
    核心词: 请求, 校验权限, 切块, Pipeline(传输管道), ACK反向应答机制(ACK确认机制), 数据报包(64KB), 重复至完成.

在这里插入图片描述

8.HDFS原理–HDFS读数据流程
问: 请简述你对HDFS的读数据流程的理解?
答案:
    1. Client(客户端)请求namenode, 读取文件.
    2. namenode校验该客户端是否有读权限, 及该文件是否存在, 校验成功后, 会返回给客户端该文件的块信息.
        例如:
            block1: node1, node2, node5
            block2: node3, node6, node8
            block3: node2, node5, node6     这些地址都是鲜活的.
            ......
    3. Client(客户端)会连接上述的机器(节点), 并行的从中读取块的数据.
    4. Client(客户端)读取完毕后, 会循环namenode获取剩下所有的(或者部分的块信息), 并行读取, 直至所有数据读取完毕.
    5. Client(客户端)根据Block块编号, 把多个Block块数据合并成最终文件即可. 

在这里插入图片描述

9.HDFS原理–安全模式介绍
问题9: HDFS的安全模式解释:
    概述:
        安全模式是HDFS自带的有一种保护机制, 在安全模式下, 只能读, 不能写.
    进入安全模式的方式:
        1. 启动Hadoop集群的时候, 会自动进入到安全模式, 进行自检. 自检没问题后, 会自动关闭安全模式.
        2. 当活跃的节点数 < 默认的副本数时, 会强制进入到安全模式.
        3. 手动进入.
            格式:
                hdfs dfsadmin -safemode get | enter | leave     获取 | 进入 | 离开
10.HDFS原理–归档操作
背景:
	HDFS适用于操作海量的大文件, 如果小文件过多, 就会占用多个Block块, 且也有多份元数据, 资源消耗比较大.
	针对于这种该情况, 我们可以用 归档包 来解决它.
概述:
	归档包类似于压缩包, 但是只有压, 没有缩, 相当于把多个文件合并成1个文件, 这样元数据就只有1份儿了.
格式:
	hadoop archive -archiveName 归档包的名字 -p 要被归档的文件名 存储归档包的路径
演示步骤:
	1. 在Linux中创建 1.txt, 2.txt, 3.txt三个文件.
		echo 'hello world   1' >> 1.txt
		echo 'hello world   2' >> 2.txt
		echo 'hello world   3' >> 3.txt
	2. 在HDFS中创建data目录, 然后将上述的3个文件分别上传过来.
		hadoop fs -put *.txt /data
	3. 通过上述的命令, 把上述的3个txt文件 压成 归档包.
	   需求: 把/data/所有的txt文件 这三个记事本, 创建归档包, 并将归档包存储到:  /output目录下.
	   格式如下:
		 hadoop archive -archiveName myTest.har -p /data/ /output
	4. 查看归档包的内容.
		[root@node1 ~]# hadoop fs -ls /output/myTest.har         -- HDFS路径默认前缀是:  hdfs://node1:8020/
		Found 4 items
		-rw-r--r--   3 root supergroup          0 2024-01-17 15:09 /output/myTest.har/_SUCCESS
		-rw-r--r--   3 root supergroup        250 2024-01-17 15:09 /output/myTest.har/_index
		-rw-r--r--   3 root supergroup         23 2024-01-17 15:09 /output/myTest.har/_masterindex
		-rw-r--r--   3 root supergroup         43 2024-01-17 15:09 /output/myTest.har/part-0

		遇到的问题: 发现, 上述的代码不能直接看到归档包 具体 归档了哪些文件, 那如何查看呢?
		解决方案: 把前缀换成归档包的前缀即可, 用什么前缀, 说明用什么规则来解析按 归档包.
			hadoop fs -ls har:///output/myTest.har

			[root@node1 ~]# hadoop fs -ls har:///output/myTest.har
			Found 3 items
			-rw-r--r--   3 root supergroup         15 2024-01-17 15:05 har:///output/myTest.har/1.txt
			-rw-r--r--   3 root supergroup         14 2024-01-17 15:05 har:///output/myTest.har/2.txt
			-rw-r--r--   3 root supergroup         14 2024-01-17 15:05 har:///output/myTest.har/3.txt
			[root@node1 ~]#
			[root@node1 ~]# hadoop fs -ls har://hdfs-node1:8020/output/myTest.har
			Found 3 items
			-rw-r--r--   3 root supergroup         15 2024-01-17 15:05 har://hdfs-node1:8020/output/myTest.har/1.txt
			-rw-r--r--   3 root supergroup         14 2024-01-17 15:05 har://hdfs-node1:8020/output/myTest.har/2.txt
			-rw-r--r--   3 root supergroup         14 2024-01-17 15:05 har://hdfs-node1:8020/output/myTest.har/3.txt

	5. 从 /data目录中, 删除 1.txt, 2.txt, 3.txt这三个文件. 然后解压归档包, 获取到源文件.
	   hadoop fs -cp /output/myTest.har/ /data              实现不了想要的效果, 只是把 归档包下所有的内容拷贝过去了.
	   hadoop fs -cp har:///output/myTest.har/* /data       这个才是我们要的语句.

细节:
	1. 归档包名的后缀必须是: *.har
	2. 存储归档包的路径必须是: hdfs文件的路径
	3. 归档包路径的前缀要写成:   har://hdfs-node1:8020/
11.HDFS原理–垃圾桶机制
概述:
	目前我们搭建的Hadoop集群, 默认没有开启垃圾桶机制, 每次删除文件, 都是永久删除的, 找不回来了.
	这样做比较危险, 我们可以开启垃圾桶机制, 这样删除数据的时候, 就会自动放到垃圾桶中, 保存一定的时间, 超出时间后, 才会自动删除.
配置垃圾桶的步骤:
	1. 去 /export/server/hadoop/etc/hadoop 的core-site.xml文件中, 加入如下的内容:
		<!-- 如下的时间单位是: 分钟, 即: 1440分钟 = 24小时 -->
		<property>
			<name>fs.trash.interval</name>
			<value>1440</value>
		</property>
	2. 注意: 三台虚拟机都要去修改上述的 core-site.xml文件.
		方式1: 逐个修改.
		方式2: 远程分发, 即: 把node1中修改后的文件, 直接拷贝给node2, node3即可.
			格式:
				scp 数据源文件路径 目的地主机名或者ip:要存储该文件的目录路径
			示例:
				scp core-site.xml node2:/export/server/hadoop/etc/hadoop
				scp core-site.xml node3:$PWD        如果数据源文件所在目录 和 另一台机器的存储目录一致, 可以写成: $PWD
	3. 三台虚拟机都修改完毕后, 记得重启: Hadoop集群.
		stop-all.sh
		start-all.sh
开启垃圾桶机制之后, 代码写法如下:
	1. 删除某个文件, 例如:
		[root@node1 hadoop]# hadoop fs -rm /data/2.txt
		2024-01-17 16:03:29,657 INFO fs.TrashPolicyDefault: Moved: 'hdfs://node1.itcast.cn:8020/data/2.txt' to trash
		at: hdfs://node1.itcast.cn:8020/user/root/.Trash/Current/data/2.txt
	2. 现在就可以从垃圾桶中恢复数据了.
		[root@node1 hadoop]# hadoop fs -mv /user/root/.Trash/Current/data/2.txt /data
	3. 如果明确要删除某个文件, 且不走垃圾桶, 删除方式如下.
		[root@node1 hadoop]# hadoop fs -rm -skipTrash /data/1.txt       -- skipTrash意思是: 跳过垃圾桶
12.Hadoop原理–MR相关
问题1: 什么是计算? 什么是分布式计算?
答案:
    计算: 狭义上指的是数学运算, 广义上指的是: 分析数据, 获取结果.
    分布式计算:
        即: 分而治之的思想, 把大问题拆解成若干个小问题, 小问题解决了, 大问题也就解决了.

问题2: 分布式计算的两种思路?
答案:
    思路1: 分散 => 汇总, 去中心化.
        MapReduce就是这种思路, 先MapTask负责分, 再ReduceTask负责合.
    思路2: 步骤执行 => 中心化调度     Spark, Flink用的是这种方式.
        Spark, Flink: Master(主节点), Worker(从节点)

问题3: 请简述你对MR核心8步的理解?        
答案:1. 封装数据源组件, 负责切片, (逐行)读取源文件.
   1个切片 = 1个MapTask任务 = 1个分好区, 排好序, 规好约的文件.
   默认切片大小 = 128MB
   2. MapTask任务, 负责: 分.
      3. 分区.   给数据打标记的, 标记着该条数据将来被哪个ReduceTask任务来处理.
         4. 排序.   按照键, 对数据进行升序排列.
         5. 规约.   对数据做局部合并, 默认: 不规约.
         6. 分组.   按照键, 进行分组.
         7. ReduceTask任务, 负责: 合.
            1个分区 = 1个ReduceTask任务 = 1个结果文件.
         8. 封装输出组件, 负责把ReduceTask处理的结果, 写到目的地文件.

问题4: 请简述MR的执行流程.
答案:
    1. MR任务分为MapTask任务 和 ReduceTask任务两部分, 其中: MapTask任务负责: 分, ReduceTask任务负责: 合.
        1个切片(默认128MB) = 1个MapTask任务 = 1个分好区, 排好序, 规好约的磁盘文件.
        1个分区 = 1个ReduceTask任务 = 1个结果文件.
    2. 先切片, 每个切片对应1个MapTask任务, 任务内部会逐行读取数据, 交由MapTask任务来处理.
    3. MapTask对数据进行分区,排序,规约处理后, 会将数据放到1个 环形缓冲区中(默认大小: 100MB, 溢写比: 0.8), 达到80MB就会触发溢写线程.
    4. 溢写线程会将环形缓冲区中的结果写到磁盘的小文件中, 当MapTask任务结束的时候, 会对所有的小文件(10个/次)合并, 形成1个大的磁盘文件.
        1个切片(默认128MB) = 1个MapTask任务 = 1个分好区, 排好序, 规好约的磁盘文件.
    5. ReduceTask任务会开启拷贝线程, 从上述的各个结果文件中, 拉取属于自己分区的数据, 进行: 分组, 统计, 聚合.
    6. ReduceTask将处理后的结果, 写到 结果文件中.
         1个分区 = 1个ReduceTask任务 = 1个结果文件.
    核心词: 切片, MapTask(分), 环形缓冲区(100MB, 0.8), ReduceTask(合), 结果文件.

13.hadoop原理–Yarn相关
问题1: 什么是资源?
答案:
    指的是计算机资源, 例如: CPU, 内存, 磁盘等.

问题2: 什么是资源调度?
答案:
    在服务器比较繁忙, 程序(计算任务)较多的时候, 如何合理的调度和分配, 管理资源, 就叫: 资源调度.
    资源调度最重要的市: 调度策略(调度算法)

问题3: Yarn调度job流程?       RM: ResourceManager(主节点), NM: nodemanager(从节点)
答案:
    1. 客户端提交 计算任务给Yarn(ResourceManager: 主节点).
    2. RM接收到客户端请求后, 会根据负载均衡等找一台相对空闲的机器(NM), 创建APPMaster进程, 负责该计算任务的监控和执行.
        1个计算任务 = 1个AppMaster进程.
    3. AppMaster创建成功后, 要和RM建立心跳机制, 并通过心跳包的方式, 从RM中获取该计算任务的相关信息.
    4. APPMaster找RM申请执行该计算任务所需的资源, RM会找一些NM创建Container资源容器, 来"占用"该计算任务所需的资源.
    5. APPMaster找到Container资源容器所在的NM(从节点).
    6. 通过NM, APPMaster建立了和Container资源容器的连接.
    7. 具体的计算过程, APPMaster会实时监控计算任务的执行情况, 并及时调度(如资源不够, 立马像RM申请).
    8. 计算任务执行结束后, APPMaster将执行结果发送给RM, 并启动自毁, 告知Yarn(RM), 可以回收该任务所占用的资源了(Container资源容器).

问题4: Yarn是1个统一的任务接收 `和 资源调度器, 资源就是: CPU, 内存等, 调度就是: 如何分配资源(调度算法, 策略), 那如何理解: 统一呢?
答案:
    Yarn是负责任务接收 和 资源调度的, 至于是什么计算任务, Yarn根本不关心, 只要符合Yarn的规范即可.
    即: Yarn不仅能调度MR计算任务, 还能调度Spark计算任务, Flink计算任务等...

在这里插入图片描述
在这里插入图片描述