HDFS的存储原理

HDFS存储架构

  1. 块block的大小默认是128M,hdfs-site.xml
    <property>
    	<name>dfs.blocksize</name>
    	<value>134217728</value>
    </property>
    
  2. 副本数默认是3,hdfs-site.xml
    <property>
    	<name>dfs.replication</name>
    	<value>3</value>
    </property>
    

说明:当存储一个超过128M的文件,比如260M,会切分为3块:128M+128M+4M,每份存储3个副本即存储了780M的数据,如果当前节点含有DataNode进程,第一个副本会优先存在当前节点,否则就随机挑选一台磁盘不太慢的CPU不太繁忙的节点;第二个副本会存储在第一个副本不同的机架的节点上;第三个副本放置于第二个副本相同机架的不同节点上。
在这里插入图片描述
其中两份存在Rack2下的dn4和dn5两个节点,另一个存在Rack1下的dn1节点
3. HDFS是不适合做小文件存储的,因为小文件过多,会导致块block也就过多,而块的元数据信息存在namenode中,这样很容易导致namenode存储占满
4. 假如hdfs上已经存在小文件,需要尽量合并成大文件并且<=128M,比如控制在110M

HDFS进程介绍

  1. NameNode:主节点存储;1、文件系统的命名空间;2、文件的目录结构;3、文件的属性,权限,创建时间,副本数;4、文件对应被切割为哪些数据块,副本数,数据分布在哪些datanode节点上通过blockmap进行维护的,namenode不会持久化存储这些映射关系
  2. namenode是通过启动和运行时,datanode会定期发送blockreport给namenode,依次namenode在内存中动态维护这种映射关系
  3. namenode的作用:管理文件系统的命名空间,维护文件系统树的所有文件和文件夹,这些信息以两个文件形式永久保存在本地磁盘:镜像文件fsimage和编辑日志文件editlog
  4. datanode:存储数据库和数据库校验和,与namenode进行通信:1、每隔3s发送心跳包给namenode,去证明我还活着配置参数hdfs-site.xml:dfs.heartbeat.interval,默认大小3秒,2、每隔一定的时间发送一次blockreport,配置参数hdfs-site.xml:dfs.blockreport.intervalMsec,默认间隔时间21600000ms=6h,dfs.datanode.directoryscan.interval,默认间隔时间21600s=6h
  5. SecondaryNamenode,是为了解决单点故障的,存储fsimage和editlog;作用:定期合并fsimage 和editlog文件作为新的fsimage,推送给namenode,简称为检查点:checkpoint;
    考虑到合并过程很耗费磁盘IO,网络IO,CPU,合并过程都放在secondarynamenode【SN】上进行
    checkpoint的触发条件:
    –满足dfs.namenode.checkpoint.preiod【默认1小时】时间点
    –或者满足dfs.namenode.checkpoint.txns【默认100万次txns id】
    可以配置两个参数做checkpoint:hdfs-site.xml:
    dfs.namenode.checkpoint.period 3600s,设置为一小时,如果没有HA,也可以设置为1800s
    dfs.namenode.checkpoint.txns 1000000,如果操作达到100万次,没有达到一小时也会做checkpoint
    

但是没有满一小时比如40分钟,如果出现故障,这40分钟数据就会丢失

HDFS文件的写流程

  1. hdfs dfs -put xxx.log /,无感知的
  2. Client调用FileSystem.create(filePath)方法,与NN进行【RPC】通信,check是否存在及是否有权限创建;false,返回错误信息;true,就创建一个新文件,不关联任何的block块,返回一个FSDataOutputStream对象
  3. Client调用FSDataOutputStream对象的write()方法,现将第一块的第一个副本写到第一个DN,第一个副本写完;就传输给第二个DN,第二个副本写完;就传输给第三个DN,第三个副本写完。步骤如下
    在这里插入图片描述
    当第三个副本写完,就会返回ack packet确认包给第二个DN,第二个DN收到第三个DN的ack packet确认包加上自身的成功写入的信息,返回一个ack packet确认包给第一个DN,第一个DN收到第二个DN的ack packet确认包加上自身的成功写入的信息,就返回一个ack packet确认包给FSDataOutputStream对象,标志第一个块的三个副本写完。其他的块也是如此写入
  4. 当文件写入数据完成后,Client调用FSDataOutputStream.close()方法,关闭输出流。
  5. 再调用FileSystem.complete()方法,告诉NN该文件写入成功

HDFS文件读取流程

  1. Client调用FileSystem.open(filePath)方法,与NN进行【RPC】通信,返回该文件的部分或者全部的block列表,也就是FSDataInputStream对象
  2. Client调用FSDataInputStream对象read()方法;
    a:与第一个块最近的DN进行read,读取完成后,会check;true,就关闭与当前DN的通信;false,会记录失败的块和DN的信息,下次不会在读取,那么下次就会去该块的第二个DN地址读取
    b:然后去第二个块的最近的DN上通信读取,check后,关闭通信
    c:假如block列表读取完成后,文件还未结束,FileSystem会再次从NN获取该文件的下一批次的block列表。(感觉就是连续的数据流,对于客户端操作是透明无感知的)
  3. Client调用FSDataInputStream.close()方法,关闭输入流
    在这里插入图片描述

SN的checkpoint步骤

  1. NameNode滚动editLog:roll edits
  2. NameNode传输fsimage+edits到SN
  3. SN合并fsimage+edits=>fsimage.ckpt
  4. SN传输fsimage.ckpt到NameNode
  5. NameNode将fsimage.ckpt文件重命名fsimage,此完成了fsimage和editlog的同步,如图
    在这里插入图片描述

hdfs debug

[hadoop@hadoop01 ~]$ hdfs debug
Usage: hdfs debug [arguments]

These commands are for advanced users only.

Incorrect usages may result in data loss. Use at your own risk.

verifyMeta -meta [-block ]
computeMeta -block -out
recoverLease -path [-retries ]
[hadoop@hadoop01 ~]$
手动修复: 多副本
[hadoop@hadoop01 current]$ hdfs debug recoverLease -path xxx -retries 10

自动修复:

参考:
https://ruozedata.github.io/2019/06/06/%E7%94%9F%E4%BA%A7HDFS%20Block%E6%8D%9F%E5%9D%8F%E6%81%A2%E5%A4%8D%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5(%E5%90%AB%E6%80%9D%E8%80%83%E9%A2%98)/
文件fei.md

上传
-bash-4.2$ hdfs dfs -mkdir /blockrecover
-bash-4.2$ echo “www.baidu.com” > fei.md
-bash-4.2$ hdfs dfs -put fei.md /blockrecover
-bash-4.2$ hdfs dfs -ls /blockrecover
Found 1 items
-rw-r–r-- 3 hdfs supergroup 18 2019-03-03 14:42 /blockrecover/fei.md
-bash-4.2$
校验: 健康状态
-bash-4.2$ hdfs fsck /
Connecting to namenode via http://yws76:50070/fsck?ugi=hdfs&path=%2F
FSCK started by hdfs (auth:SIMPLE) from /192.168.0.76 for path / at Sun Mar 03 14:44:44 CST 2019
…Status: HEALTHY
Total size: 50194618424 B
Total dirs: 354
Total files: 1079
Total symlinks: 0
Total blocks (validated): 992 (avg. block size 50599413 B)
Minimally replicated blocks: 992 (100.0 %)
Over-replicated blocks: 0 (0.0 %)
Under-replicated blocks: 0 (0.0 %)
Mis-replicated blocks: 0 (0.0 %)
Default replication factor: 3
Average block replication: 3.0
Corrupt blocks: 0
Missing replicas: 0 (0.0 %)
Number of data-nodes: 3
Number of racks: 1
FSCK ended at Sun Mar 03 14:44:45 CST 2019 in 76 milliseconds
The filesystem under path ‘/’ is HEALTHY
-bash-4.2$

直接DN节点上删除文件一个block的一个副本(3副本)

删除块和meta文件:
[root@yws87 subdir135]# rm -rf blk_1075808214 blk_1075808214_2068515.meta
直接重启HDFS,直接模拟损坏效果,然后fsck检查:
-bash-4.2$ hdfs fsck /
Connecting to namenode via http://yws77:50070/fsck?ugi=hdfs&path=%2F
FSCK started by hdfs (auth:SIMPLE) from /192.168.0.76 for path / at Sun Mar 03 16:02:04 CST 2019
.
/blockrecover/fei.md: Under replicated BP-1513979236-192.168.0.76-1514982530341:blk_1075808214_2068515. Target Replicas is 3 but found 2 live replica(s), 0 decommissioned replica(s), 0 decommissioning replica(s).
…Status: HEALTHY
Total size: 50194618424 B
Total dirs: 354
Total files: 1079
Total symlinks: 0
Total blocks (validated): 992 (avg. block size 50599413 B)
Minimally replicated blocks: 992 (100.0 %)
Over-replicated blocks: 0 (0.0 %)
Under-replicated blocks: 1 (0.10080645 %)
Mis-replicated blocks: 0 (0.0 %)
Default replication factor: 3
Average block replication: 2.998992
Corrupt blocks: 0
Missing replicas: 1 (0.033602152 %)
Number of data-nodes: 3
Number of racks: 1
FSCK ended at Sun Mar 03 16:02:04 CST 2019 in 148 milliseconds
The filesystem under path ‘/’ is HEALTHY
-bash-4.2$

手动修复hdfs debug

-bash-4.2$ hdfs |grep debug
没有输出debug参数的任何信息结果!
故hdfs命令帮助是没有debug的,但是确实有hdfs debug这个组合命令,切记。
修复命令:
-bash-4.2$ hdfs debug recoverLease -path /blockrecover/fei.md -retries 10
recoverLease SUCCEEDED on /blockrecover/fei.md
-bash-4.2$
直接DN节点查看,block文件和meta文件恢复:
[root@yws87 subdir135]# ll
total 8
-rw-r–r-- 1 hdfs hdfs 56 Mar 3 14:28 blk_1075808202
-rw-r–r-- 1 hdfs hdfs 11 Mar 3 14:28 blk_1075808202_2068503.meta
[root@yws87 subdir135]# ll
total 24
-rw-r–r-- 1 hdfs hdfs 56 Mar 3 14:28 blk_1075808202
-rw-r–r-- 1 hdfs hdfs 11 Mar 3 14:28 blk_1075808202_2068503.meta
-rw-r–r-- 1 hdfs hdfs 18 Mar 3 15:23 blk_1075808214
-rw-r–r-- 1 hdfs hdfs 11 Mar 3 15:23 blk_1075808214_2068515.meta

自动修复

当数据块损坏后,DN节点执行directoryscan操作之前,都不会发现损坏;
也就是directoryscan操作是间隔6h
dfs.datanode.directoryscan.interval : 21600
在DN向NN进行blockreport前,都不会恢复数据块;
也就是blockreport操作是间隔6h
dfs.blockreport.intervalMsec : 21600000
当NN收到blockreport才会进行恢复操作。

但是有可能: 手动修复 加上自动修复都是失败的
所以数据仓库要注意数据质量和数据重刷机制

DataNode Memory

datanode一般要落地磁盘,所以内存不用太大,2G足够,默认是4G
https://issues.apache.org/jira/secure/Dashboard.jspa
设置为8G只用了600M,下面的error的原因

java.lang.OutOfMemoryError: unable to create new native thread

实际是下面的配置导致的
1.echo “kernel.threads-max=196605” >> /etc/sysctl.conf
echo “kernel.pid_max=196605” >> /etc/sysctl.conf
echo “vm.max_map_count=393210” >> /etc/sysctl.conf
sysctl -p
2./etc/security/limits.conf

  • soft nofile 196605
  • hard nofile 196605
  • soft nproc 196605
  • hard nproc 196605

hdfs生产环境注意事项

  1. 检查生产环境是否开启回收站,CDH默认是开启的,在配置文件core-site.xml中配置fs.trash.interval 10080 (7天)
  2. 开启了回收站,慎用-skipTrash,比如 hdfs dfs -rm -skipTrash /fei.log,而是使用hdfs dfs -rm /fei.log,这样删除的文件就会放在回收站,7天后自动删除
  3. hdfs安全模式:只对写有影响,进入安全模式,hdfs dfsadmin -safemode enter;离开安全模式hdfs dfsadmin -safemode leave;安全模式尽量少做,如果hdfs集群故障,一般控制上游的数据同步
    在这里插入图片描述
    如果HDFS出现故障,一般控制FLUME采集数据这块,等集群恢复,才继续同步数据
  4. hdfs fsck :用于检查HDFS上文件和目录的健康状态、获取文件的block块信息和位置信息等
    [hadoop@hadoop01 hadoop]$ hdfs fsck /
    21/11/07 10:03:33 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
    Connecting to namenode via http://hadoop01:50070/fsck?ugi=hadoop&path=%2F
    FSCK started by hadoop (auth:SIMPLE) from /172.17.0.5 for path / at Sun Nov 07 10:03:34 CST 2021
    ......Status: HEALTHY
     Total size:	175049 B
     Total dirs:	12
     Total files:	6
     Total symlinks:		0
     Total blocks (validated):	5 (avg. block size 35009 B)
     Minimally replicated blocks:	5 (100.0 %)
     Over-replicated blocks:	0 (0.0 %)
     Under-replicated blocks:	0 (0.0 %)
     Mis-replicated blocks:		0 (0.0 %)
     Default replication factor:	1
     Average block replication:	1.0
     Corrupt blocks:		0
     Missing replicas:		0 (0.0 %)
     Number of data-nodes:		1
     Number of racks:		1
    FSCK ended at Sun Nov 07 10:03:34 CST 2021 in 5 milliseconds
    
    The filesystem under path '/' is HEALTHY
    
    具体命令介绍:
    -move: 移动损坏的文件到/lost+found目录下
    -delete: 删除损坏的文件
    -openforwrite: 输出检测中的正在被写的文件
    -list-corruptfileblocks: 输出损坏的块及其所属的文件
    -files: 输出正在被检测的文件
    -blocks: 输出block的详细报告 (需要和-files参数一起使用)
    -locations: 输出block的位置信息 (需要和-files参数一起使用)
    -racks: 输出文件块位置所在的机架信息(需要和-files参数一起使用)
    例如要查看HDFS中某个文件的block块的具体分布,可以这样写:
    hadoop fsck /your_file_path -files -blocks -locations -racks

各个DN节点的数据平衡

  1. start-balancer.sh -threshold 10,threadhold表示所有节点的磁盘使用的与集群平均使用之差要小于这个阈值
    在这里插入图片描述
    平均值(90%+60%+80%)/3=76%,所以需要把DN1数据均衡到DN2,保证每个节点已经使用的磁盘空间和平均值都相差在10%范围内
    其中hdfs-site.xml中dfs.datanode.balance.bandwidthPerSec 控制均衡数据的每秒的大小,正常设置为30m,即30m每秒
  2. stop-balancer.sh,如果各个节点数据平衡夯住,就可以使用该命令
  3. 数据平衡一般晚上做调度

单个DN节点的多磁盘数据平衡

需要现在hdfs-site.xml
配置dfs.disk.balancer.enabled,启用多磁盘数据平衡;dfs.datanode.data.dir:/data01,/data02,/data03,/data04,多个磁盘用逗号分隔
具体参考:https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HDFSDiskbalancer.html
操作命令步骤:
hdfs diskbalancer -plan hadoop01 生成hadoop01.plan.json
hdfs diskbalancer -execute hadoop01.plan.json 执行
hdfs diskbalancer -query hadoop01 查询状态
执行磁盘数据均衡的时机是:新盘加入;监控服务器的磁盘剩余空间,小于阈值比如10%,发送邮件预警,手动执行

为什么DN节点的生产上挂载多个物理的磁盘目录?
/data01 disk1
/data02 disk2
/data03 disk3
为了高效率写,高效率读,并行读写
在这里插入图片描述
提前规划好2-3年存储量 ,避免后期加磁盘维护的工作量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值