HDFS
分布式存储介绍
分布式存储是一种将数据分散存储在多个地理位置的存储系统。解决了单机存储容量有限的问题,且带来了比较高的性能提升.例如:n台服务器,就是n倍的传输速率,读写速率等.
组成
NameNode:主节点
1.管理整个HDFS集群
2.维护和管理元数据
SecondaryNameNode:辅助节点
1.辅助NameNode维护和管理元数据
datanode:从节点
1.存储具体的数据
2.负责源文件的读写操作
3.定时向NameNode发送心跳包
架构图
Hadoop2.x架构
分块存储
1.分块存储是为了方便同意管理,默认的块大小为128MB
2.副本机制是为了提高容错率,副本数越多,容错率越高
3.实际开发中,建议副本数为2~5
4.如果要修改block块的大小和默认副本数,可以去: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>
NameNode管理元数据
1.namenode通过一批Edits和FSImage两类文件来维护和管理元数据
2.Edit文件相对较小,操作起来速度较快,它只记录HDFS最近一段状态的元数据信息.阈值为一个小时或者100万次
3.FSImage文件相对较大,操作起来速度相对较慢,它记录的是HDFS集群最近状态外,其它的元数据信息
4.HDFS集群启动时,会自动加载FSImage文件和最新的Edits文件进入内存,用于记录元数据.整个过程称为HDFS的自检动作,此状态下,HDFS集群会强制进入安全模式,只能读不能写
SecondaryNameNode辅助管理元数据
1.SecondaryNameNode会间隔60秒询问一次namenode Edits是否满足阙值
2.满足条件,则通知namenode创建新的Edits文件,继续写入元数据
3.根据http协议,从namenode上把要合并的edits文件和FSImage文件拉取本地进行合并
4.将合并的新FSImage文件推送给namenode,用来替换旧的FSImage文件,旧的文件不会立即删除,只有达到阙值才会删除
5.对于Edits文件和FSImage文件的合并操作,由SecondaryNameNode独立完成的,全程namenode不参与
6.实际开发中,namenode和SecondaryNameNode会部署在不同的服务器上,配置几乎一致,SecondaryNameNode内存稍大
7.在紧急情况下,SecondaryNameNode可以用来会恢复元数据
三大机制
1.副本机制:默认3个副本
当前副本总数>默认副本数,namenode会自动删除某个副本
当前副本总数<默认副本数,namenode会自动增加某个副本数
当前活跃机器总数<默认副本数,会强制进入安全模式,只能读不能写
2.负载均衡
namenode会保证所有的datanode资源使用率,尽量保持一致
3.心跳机制
datanode会定时(3秒)向namenode发送心跳包,告诉namenode还活跃着
如果超过一定时间(630秒),namenode没收到datanode心跳包,则认为它宕机了,此块信息交由其它活跃的datanode存储
所有datanode会定时(6小时)向namenode汇报一次自己完整的块信息,让namenode校验更新
![](https://img-blog.csdnimg.cn/direct/74694d32c27c444180662e0acf71b8a1.png)
读写数据流程
读数据流程
1.client请求namenode读取文件
2.namenode校验该client是否有读权限,以及文件是否存在,校验成功会返回客户端该文件的block块信息
3.client会连接上述的节点,并行读取块中的数据
4.client读取完毕后,会找namenode获取剩下的块信息,直至数据读取完毕
5.client根据block的编号把block块合并成最终的文件
写数据流程
1.client请求namenode,上传文件
2.namenode收到请求后,校验权限
3.如果可以上传,客户端会按照默认块大小(128)进行切块
4.client再次请求namenode,第一个block上传的位置
5.namenode根据负载均衡,副本机制,机架感知原理以及网络拓扑图,返回给client存储该块的datanode节点
6.client会先连接就近的datanode机器,然后一次和其他datanode进行连接,形成传输管道(Pipeline)
7.采用数据报包(DataPacket)的形式形成传输数据,每个包的大小不超过64kb,并建立反应答机制(ACK)
8.传输动作:node1 =>node2 =>node3 ,ACK:node3=>node2=>node1
9.重复上述动作,直至第一个block块完成
10.客户端请求第二块block块的上传位置,直至所有的block块传输完毕
安全模式
安全模式是HDFS自带的一种保护机制,在安全模式下,只能读不能写.
进入安全模式的方式:
1.启动Hadoop集群的时候,会自动进入安全模式,进行自检,自检没问题,会关闭安全模式
2.当活跃的节点数<默认副本数,会强制进入安全模式
3.手动进入
hdfs dfsadmin -safemode get | enter | leave
归档操作
HDFS适用于操作海量的大文件,如果小文件过多,就会占用多个block块,并且也有多份的元数据,资源消耗较大,我们可以采用归档包来解决这个问题,归档包类似于压缩包,只有压没有缩,相当于把多个文件合成一个文件,元数据也变成一份.
格式:
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/
4. 实际开发中, 大多数公司可以每年, 每季度, 每月, 甚至是每周归档一次, 既可以降低元数据, 也可以提高磁盘利用率(否则1个小文件就要占1个Block块)
当我们需要使用源文件的时候, 可以很方便的从归档包中提取出我们要的内容.
垃圾桶机制
目前我们搭建的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意思是: 跳过垃圾桶
MapReduce
分布式计算
将大文件拆成若干个小问题,小问题解决了,大问题就解决了,采用分而治之的思想.
思路:
思路一:
分散 =>汇总,去中心化 (MR先让MapTask分则分,再让ReduceTask负责合)
思路二:
步骤执行=>中心化调度(Spark,Flink使用这种方式)
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个结果文件
Yarn
资源调度
在服务器比较繁忙,程序(计算任务)较多的时候,如何合理的调度和分配,管理资源叫做资源调度
资源调度最重要的市:调度策略.
Yarn三大调度策略
FIFO Scheduler(先进先出调度器): 按照任务到达时间排序,先到先服务.
优点:每个计算任务能独享集群100%的资源
缺点:不能并行执行,如果大任务过多,会导致小任务纸执行时间过长
Capacity Scheduler(容器调度器):将集群的资源混氛围多个队列,每个队列有独立的资源配额.
优点:1.可以当多任务并行执行,提高计算效率
2.以借调资源
缺点:1.计算任务不能独享集群100%的资源,存在资源浪费的情况.
2.如果出现资源借调的情况,可能会出现无法及时归还资源的情况
Fair Scheduler(公平调度器):会为所运行的任务动态的调整系统资源.
优点:1.多任务可以并行执行,提高计算效率
2.如果只有一个任务,则它可以共享集群100%的资源
缺点:每个任务获取集群资源,都是公平的,均分的,例如:一个任务,就占用100%的资源,
2个任务,各占50%的资源
三个任务,各占33.33%的资源
...
小任务如果过多,会导致大任务迟迟无法执行结束的问题.
Yarn调度job流程
1.客户端提交任务给Yarn(ResourceManager:主节点)
2.RM接受到客户端请求后,会根据负载均衡扥刚找到一台相对空闲的机器(Nodemanager),创建APPMaster进程,负责该计算任务的监控和执行.
1个计算任务=1个APPMaster进程
3.APPMaster创建成功后,要和ResourceManager建立心跳机制,并通过心跳包的方式,从ResourceManager中获取该计算任务的相关信息.
4.APPMaster找到ResourceManager申请执行该计算任务所需的资源,ResourceManager会找到一些Nodemanager创建一些Container资源容器,来占用该计算任务所需的资源.
5.APPMaster找到Container资源容器所在的Nodemanager.
6.通过Nodemanager,APPMaster建立和Container资源容器的连接.
7.通过具体的计算过程,APPMaster会实时监控该计算任务的执行情况,并及时调度(如资源不够,立马向ResourceManager申请).
8.计算任务执行结束后,APPMaster将执行将执行结果发送给ResourceManager,并启动自毁,告知
ResourceManager,可以收回该任务所占用的资源(Container资源容器)
版权归原作者 听海z 所有, 如有侵权,请联系我们删除。