05-hadoop02之HDFS

一、HDFS中重要的理论

1、HDFS文件系统中,默认的需要将存储的数据进行切割存储的,每一个块是128M(hadoop2.x和3.x), 如果是hadoop1.x (64M)。

2、为什么每一个块都是128M呢(我们去磁盘上找东西,是需要先找到它,消耗时间,大文件和小文件寻址时间是一样的,大约是5ms~15ms毫秒之间,磁盘读取数据最优的话,寻址时间大约占传输时间的百分之1 是最好的)。 找到一个文件10ms,最好获取数据的时间 1000ms = 1s , 现在磁盘的读取速度是100M/s 。所以我们可以将块设置为128M。

比如硬盘上,找到一个文件,大约需要5ms~15ms之间,这个叫做寻址时间。假如你找到的数据,只花了1ms就读取完了,肯定觉得效率真低,最好就是寻址时间占比少一些。最好的效率是 寻址花费 10ms,读取数据的时间最好是100倍,大约就是1s钟。这个能读取多少数据跟硬盘的材质有关系,固态和机械硬盘是不一样的。一般大数据服务器的硬盘都是机械硬盘,一秒钟的理论值是100M。

总结:每一个块到底可以设置多大,取决于硬盘的读写速度,假如你们公司全部使用固态硬盘,就可以设置为256M一个块,也可以更大。

3、在HDFS中,每一个块默认都有三个数据(防止丢失,容灾)。

一般集群中的每一个数据都有三份,比如八角笼中,1G的电影,放在集群中占3G.

假如 1G = 1024M = 8个块 每一个块都有2个备份,总共是24个块。

4、机架感知

机房:

机架:

Hadoop为什么可以做到机架感知呢?算法

5、为什么块不设置的小一点?

最重要的原因是:消耗内存。比如不管一个块大或者小,都有元数据,这个元数据大约是150字节。

10T的数据 元数据 某某机房,某某机架,某个服务器的名字

1KB 元数据 某某机房,某某机架,某个服务器的名字

比如有一亿个块,一亿个块的元数据,大约占内存的数据是20G。

如果一个块是128M,一亿个块 128个亿的M.

如果一个块是1M, 一亿个块 一亿M .

结论:hdfs不适合存储小文件。耗费内存

6、块信息如何修改?

可以通过hdfs-site.xml 修改块大小。

每一个主要的配置文件都有两份,第一份是 hdfs-defalut.xml 里面存放的是这个功能的默认设置,还有一个是hdfs-site.xml 这个里面存放的是 自定义设置。hdfs-site.xml中的配置会替换hdfs-defalut.xml中的配置。

<property>
  <name>dfs.blocksize</name>
  <value>134217728</value>
  <description>默认块⼤⼩,以字节为单位。可以使⽤以下后缀(不区分⼤⼩写):k,m,g, t,p,e以重新指定⼤⼩(例如128k, 512m, 1g等)</description>
</property>
<property>
  <name>dfs.namenode.fs-limits.min-block-size</name>
  <value>1048576</value>
  <description>以字节为单位的最⼩块⼤⼩,由Namenode在创建时强制执⾏时间。这可以防 ⽌意外创建带有⼩块的⽂件降低性能。</description>
</property>
<property>
  <name>dfs.namenode.fs-limits.max-blocks-per-file</name>
  <value>1048576</value>
  <description>每个⽂件的最⼤块数,由写⼊时的Namenode执⾏。这可以防⽌创建降低性能 的超⼤⽂件 
   </description>
</property>

通过路径查看一台服务器的blk的数据:

 

7、hdfs的优缺点

缺点

1、对于低延迟(立即响应)的场景是不适合的。
2、不适合存储小文件
3、不适合修改(文件上传之后无法修改)

 优点:

适合大数据量的存储
一份变3份,很好的容错性。

8、hdfs的体系结构

1、NameNode
   有且仅有一个(HA【高可用】除外),负责我们整个hdfs集群的管理工作。
   管理其他的DataNode节点,并且记录各个块的信息。可以处理客户端的各种请求。
   NameNode所记录的数据,其实是在内存中存放的。机器宕机了,内存数据消失。
   为了防止数据丢失,namenode 有两个帮手:fsimage 以及 edit 两种文件。
2、SecondaryNameNode
   不是第二个nameNode ,其实是小秘。有且仅有一个。
   可以帮助namenode 完成 fsimage 和 edit 的合并工作。
3、DataNode
   数据节点,真正存储数据的地方,可以有1个,也可以有多个。
   不定时的向namenode 发送心跳数据,每隔3秒发送一次。

二、HDFS成员

元数据 --- 数据的数据,类似于字典的目录,比如hdfs以及mysql 等都有元数据。

每一个块都要有一个对应的元数据,元数据150个字节,这150个字节存在了namenode的内存中,假如namenode挂掉了,元数据也就消失了,整个集群报废了。

为了防止namenode挂掉又重启导致数据丢失的问题:可以使用两类文件帮助,fsimage 和 edits

1、fsimage 一种文件

namenode 中存储的是元数据,而且是存储在内存中。 突然电脑宕机了,数据没了。所以namenode的元数据非常的重要,每隔一个小时,会将namenode 中的内存数据数据备份一下,变成了fsimage的东西,而且只保留最近的两次。
   20230816 11:25:09 保存一次
   20230816 12:25:09 保存一次
   20230816 13:25:09 保存一次 (删除第一次保存的数据)
   防止namenode的服务器宕机了,数据丢失的问题。如果真宕机了,重启namenode ,它会自动的加载fsimage数据到内存中。

2、edits 文件(也是一种文件类型)

fsiamge 每隔一个小时保存一份,假如在这一个小时内,突然宕机了,也会丢失数据。
这期间的所有操作都会记录到edit的文件中。
edit中记录的是你的每一次操作(上传,删除等操作)。
如果宕机了,这里面的操作会自动的帮你执行一遍,从而达到跟宕机之前一模一样的效果。

edits 可以有多个:
生成的规则是如下:
1、默认一个小时生成一个
2、如果在一个小时内,疯狂的进行操作,次数超过了100万次
3、edits 文件不能太大,大小超过了64M 也会生成一个新的

将老的fsimage 文件和 从未合并的edits文件合并在一起,生成一个新的fsimage,这个操作是每隔一个小时操作一次。这个事情是SecondaryNameNode 来做。

三、HDFS集群的开机启动原理

一个命令: start-dfs.sh 启动后发生了什么?

1、如果是一个新的集群:

刚格式化了 namenode的,就是一个新的hdfs集群。
要想重新格式化,需要删除  tmp 下的所有文件及文件夹。

启动后就是创建一个新的edits文件,和一个空的fsimage文件,仅此而已。

2、如果是一个老的集群:

首先整个集群先进入安全模式:此时的安全模式,是只读模式,不允许上传,删除,重命名等
只有达到了一定的条件,才会离开安全模式。
1、在这种情况下,其实最耗时的操作就是加载最新的fsimage 到namenode节点的内存中,因为namenode 是整个集群的核心,处理大量的数据,速度必须很快。
2、执行尚未合并的edits文件,执行里面的每一次操作,达到跟关机之前一样的效果。
3、重新创建一个新的edits文件,用于继续记录操作
4、将老的fsimage和 edits文件合并,生成一个新fsimage供下一次使用。

edtis文件,也是可以通过命令强制让其重新生成一个的。

edits⽂件可以强制让其滚动,结束当前的edits⽂件,产⽣⼀个的edits⽂件
     hdfs dfadmin -rollEdits
什么叫做文件的回滚?
将一个正在使用的文件,结束,开启新的文件,这个操作就叫做滚动\回滚。

四、HDFS的安全模式

当hdfs集群启动的时候,由于要做很多的事情,这期间进群进入了安全模式
离开安全模式的条件:

NameNode启动后会进入一个称为安全模式的特殊状态。处于安全模式的NameNode对于客户端来说是只读的。NameNode从所有的DataNode接收心跳信号和块状态报告(blockreport)
每个数据块都有一个指定的最小副本数(dfs.replication.min),当NameNode检测确认某个数据块的副本数目达到这个最小值,那么该数据块就会被认为是副本安全(safely replicated)的
在一定百分比(这个参数配置于dfs.safemode.threshold.pct,默认值是99.9%)的数据块被NameNode检测确认是安全之后,再过若干时间后(这个参数配置于dfs.safemode.extension,默认值是30秒),NameNode将退出安全模式状态。接下来NameNode会确定还有哪些数据块的副本没有达到指定数目,并将这些数据块复制到其他DataNode上。


1、你的datanode上的最小副本数,应该是每个块都需要保证一个1。最小副本数是1
   比如  a.txt   有三个副本,有 1 个就可以用。 dfs.replication.min=1
2、所谓的最小副本条件指的是在整个文件系统中99.9%的块满足最小副本级别(默认值:dfs.replication.min=1)
  假如有一万个块,99.9%的块达到了一个副本数即可离开,等于9990个块需要达到这个条件,这9990个块只需要每个块都满足1个副本数即可。

也可以手动的进入安全模式,也可以手动的离开安全模式:
只有安全模式不起作用:
1、查看是否处于安全模式:
hdfs dfsadmin -safemode get     ON 说明是安全模式,OFF 说明不是安全模式 
2、通过命令⼿动进⼊或者离开
hdfs dfsadmin -safemode enter
    进入安全模式,上传不起作用,会提示的
hdfs dfsadmin -safemode leave
在公司中,集群全年的可靠性达到:99.99%       365*24*60*60,意味着全年的某个时刻,停止50多分钟。
大数据售前工程师(能呲):
你们公司比如是做大数据服务的。人家问:大数据服务的可靠性有多强?

可通过如下配置修改:hdfs-site.xml

1. dfs.namenode.replication.min:
   可用的block 的数量,必须都有一个副本数    1
这个地方设置的1 表示一个块什么情况下叫做可用。

2. dfs.namenode.safemode.threshold-pct:
   集群中,可用的块的数量占全部的数量的比如:99.9% 即可,没必要达到100%
	
3. dfs.namenode.safemode.min.datanodes:
   离开安全模式的最小可用(alive)datanode数量要求,默认为0.也就是即使所有datanode都不可用,仍然可以离开安全模式。

4. dfs.namenode.safemode.extension:
    当集群中所有的条件都满足后,需要保持多久才能真正的离开,默认为30000 即 30s

五、HDFS的读写流程

1、写入的流程

2、读取流程

六、NameNode 和 DataNode 之间的心跳机制

七、SecondayNamenode的工作机制(小秘的工作日常)

工作内容:将fsimage以及edits文件进行合并,形成一个新的fsimage。

SecondaryNameNode 每隔一个小时,去nameNode中拉去数据
拉取的时候,会终止当前的edits文件,生成一个新的edits_inprogress_XXX.
   接着将我们edits文件以及最新的fsiamge文件拉去到SecondaryNameNode的服务器上。
   进行合并,生成一个最新的fsimage.ckpt
 传递给nameNode ,NameNode 修改一下名字,变为新的fsimage ,删除掉之前的倒数第二个文件。因为fsimage只保留两个最新的文件。

八、介绍3个脚本文件

目前遇到的问题是什么?

1、你是否有这样的困惑?整个集群,每一个服务器上都需要输入 jps 查看服务。

能否实现,在bigdata01上输入一个命令,直接出三台服务器上的所有正在运行的jps。

它来了:

所有的自定义的脚本文件,存放在/usr/local/bin 下面

创建 vi jps-cluster.sh

编辑保存退出。

1、jps-cluster.sh

如果我们想在Bigdata01 这台电脑上,查看整个集群的服务启动情况,可以使用这个脚本文件。


#!/bin/bash
USAGE="使⽤⽅法:sh jps-cluster.sh'"
NODES=("bigdata01" "bigdata02" "bigdata03")
for NODE in ${NODES[*]};do
echo "--------$NODE--------"
ssh $NODE "/opt/installs/jdk/bin/jps"
done
echo "------------------------------------------"
echo "--------jps-cluster.sh脚本执⾏完成!--------"

记得赋权限

chmod u+x jps-cluster.sh

不管在哪个地方都可以执行该命令 jps-cluster.sh

2、集群文件分发脚本【xsync.sh】

我们经常进行文件的长拷贝,拷贝完第一台,拷贝第二台,如下所示:

scp -r 文件或者文件夹 root@主机名:/路径

可以一个命令下去,分发所有的Linux服务器,不用一个个的长拷贝了。

需要有一个服务,rsync

需要在所有的分发的电脑上安装 rsync。

脚本文件:

一定要注意:此脚本文件,不要在windows进行编辑,否则会报错,全程使用linux进行编辑,原因是windows中的字符集和linux中的不一样。

touch xsync.sh

chmod u+x xsync.sh

使用的案例: xsync.sh /etc/profile

#!/bin/bash
#1 获取输入参数个数,如果没有参数,直接退出
pcount=$#
if [ $pcount -lt 1 ]
then
echo No Enough Arguement!
exit;
fi

#2. 遍历集群所有机器
for host in bigdata02 bigdata03
do
echo ====================    $host    ====================
#3. 递归遍历所有目录
for file in $@
do
#4 判断文件是否存在
if [ -e $file ]
then
#5. 获取全路径
pdir=$(cd -P $(dirname $file); pwd)
echo pdir=$pdir

#6. 获取当前文件的名称
fname=$(basename $file)
echo fname=$fname

#7. 通过ssh执行命令:在$host主机上递归创建文件夹(如果存在该文件夹)
ssh $host "source /etc/profile;mkdir -p $pdir"

#8. 远程同步文件至$host主机的$USER用户的$pdir文件夹下
rsync -av $pdir/$fname $USER@$host:$pdir
else
echo $file Does Not Exists!
fi
done
done
rsync -av

最常用的选项,表示递归模式,保留软链接、文件权限、修改时间戳、属主、属组、设备文件、特殊文件,详细显示执行过程

测试一下: 

xsync.sh   跟上你想同步的文件或者文件夹都可以
xsync.sh  /etc/hosts   将hosts文件同步给其他两台电脑。

3、命令同步执行脚本[xcall.sh]

一个命令在一个电脑上运行,是否可以在多台电脑上同步执行呢?

比如 yum install -y rsync

vi xcall.sh

编辑

chmod u+x xcall.sh

#!/bin/bash

params=$@
i=1
for (( i=1 ; i <= 3 ; i = $i + 1 )) ; do
    echo ============= bigdata0$i $params =============
    ssh bigdata0$i "$params"
done

测试:

xcall.sh  hostname
xcall.sh  ifconfig
xcall.sh  yum install -y rsync
xcall.sh source /etc/profile

不能是xcall.sh jps
除非写全路径:xcall.sh /opt/installs/jdk/bin/jps
可以将 jps这个命令做一个软链接到/usr/local/bin 下
xcall.sh ln -s /opt/installs/jdk/bin/jps /usr/local/bin/jps
这样一修复,就可以 xcall.sh jps 
scp 进行远程拷贝,假如没有那个文件夹可以自行创建。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YuPangZa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值