- 基于前面的学习与配置,相信对于HDFS有了一定的了解
HDFS概述
1.什么是HDFS
- Hadoop Distributed File System:分步式文件系统
- HDFS是Hadoop体系中数据存储管理的基础
- HDFS是基于流数据模式访问和处理超大文件的需求而开发的
1.流式数据:将数据序列化为字节流来存储,这样不会破坏文件的结构和内容,而且字节流直接存储在磁盘上,可以分片或分块
2.当超大规模的文件本身就已经超越了单台服务器的存储规模,需要多台服务器同时存储,
此时需要将数据序列化成字节数据,按照字节的顺序进行切分,然后分布式地(均匀的)存储在各个服务器上
3.若要将一个大的文件进行切分,该文件必须支持序列化,
若要存储在文件系统中,该文件系统必须是流式数据访问模式
- HDFS将大规模的数据以分布式的方式均匀存储在集群中的各个服务器上,然后分布式并行计算框架MR利用各个数据节点DN的本地计算资源在本地服务器上对大规模数据集的一个子集数据进行计算
- HDFS具有高容错、高可靠性、高可扩展性、高吞吐率等特征, 适合一次写入多次读取的场景
2.HDFS的优势
1.HDFS中存储的数据主要用于找规律,建模等,而不是用于存储订单数据等需要经常修改的数据
HDFS中存储的数据一次写入,多次读取(离线,统计分析),并且写入后不允许修改
->为什么不允许修改?
HDFS存储的数据通常都是超大规模的,而且这些数据都有副本,一旦发生修改其副本数也需要修改,
而且对大规模数据进行修改需要加锁,HDFS集群中允许多用户访问,一旦加锁,其性能大大降低
所以Hadoop适用于处理离线数据**,不适合处理实时数据
2.HDFS的数据处理规模比较大,应用一次需要大量的数据,同时这些应用一般都是批量处理,而不是用户交互式处理。
应用程序能以流的形式访问数据库,主要的是数据的吞吐量**,而不是访问速度。
3.应用场景:电商系统中的下订,用户注册,用户浏览等数据存到HDFS中,就可以进行用户画像,用户分群,用户购买行为习惯的分析。
这就要对这些数据进行多维度的分析和汇总,所以多次读取就是必须的。
结构化:关系型,sql关系表
半结构化:按一定的格式存储,word, ppt
非结构化:视频,音频, 图片
HDFS认为系统发生故障是常态,能检测和应对故障,自动故障迁移与自动故障恢复,
所以可以应用在低成本的机器上,保证高高容错性
1.原来HDFS集群中只有一个NameNode,当该NN故障导致整个集群不可用,
高可用(HA)则消除Hadoop 1中存在的单点故障,提供故障转移功能,当ActiveNN故障时,StandbyNN将接管工作
2.各个DataNode都会存储数据,且HDFS分布集群通过数据冗余的方式,将同一份数据的多个副本存储在多个节点上,
避免了某个DN宕机导致数据丢失的情况
3.HDFS的局限
1.低延迟数据访问:访问数据的时间尽可能短
2.与关系型数据库不同,DB有存储极限,而HDFS处理的数据都是PB级别,当存储的数据超过DB存储极限时,就不能再对数据进行简单的CRUD操作,而是对海量的数据进行分析,挖掘其商业价值
而且HDFS保证高吞吐量,这必定会牺牲低延迟性
所以对于低延迟的数据访问Hadoop不适合,HBase更适合
->HBase:分步式基于列的非关系性数据库
1.小文件可以存成一个块,块大小固定且存于NN中,NN存于内存中,内存大小受限导致HDFS所能存储的文件有限,同时大量内存占用降低NN性能
当然可以将小文件通过SequenceFile, MapFile方式归档,压缩成大文件再存到块中
2.小文件和大文件的元数据信息上的差别很小
3.配置归档文件:hadoop archive -archiveName input.har[归档文件的文件名] -p /input[需要归档的目录] /output[归档文件输出目录]
查看归档文件:hadoop fs -ls har:/
解归档文件:hadoop fs -cp har:/
1.HDFS中只能进行追加操作,不支持多用户对同一文件的写操作及在文件任意位置进行修改
多用户对同一个文件的操作,尤其是超大文件,涉及线程安全,即需要加锁,造成性能上的损失
2.HDFS的数据冗余设计,当对文件任意一个位置进行修改,那么备份的数据也要一起修改,如此HDFS的开销会很大
从业务角度来说,一个PB级别的文件如果只修改了几行数据,对最后分析的结果影响很小
4.HDFS的特性
- 可扩展性及可配置性:集群在不重启的情况下,能够自动识别配置进来的新服务器
- 跨平台性
- Shell命令行:既有Shell接口(与linux命令形式相似) ,也提供Java编程接口
- WEB界面:内置两个Web系统(HDFS, MapReduce)
HDFS设计核心
1.数据块
1.文件系统:存储设备上组织文件的方法
2.分步式文件系统:允许文件透过网络在多台主机上分享的文件系统
1.修改hdfs-site.xml配置文件
<property>
<name>dfs.block.size</name>
<value>134217728</value>
</property>
2.通过API指定,原来块不受影响,只改变新块
conf.set("dfs.block.size", args[0]);
3.查看某文件块大小:hadoop fs -stat "%o" /j2ee.txt
-------------------------------------------------
4.HDFS中找到目标文件块所需要的时间与文件块大小有关,块不能设置太大也不能太小
文件块越大,寻址时间越短,但磁盘传输时间越长,导致程序处理该块时变得非常慢,
MR中的Map每次只对一个块操作,如果块过大运行速度也会很慢;
文件块越小,寻址时间越长,但磁盘传输时间越短,
大量小文件会占用NN空间内存,不可取
5.HDFS中块大小为什么设置为128M?
HDFS中平均寻址时间大概为10ms,经过前人的大量测试发现,寻址时间为传输时间的1%时为最佳状态,所以最佳传输时间为10ms/0.01=1000ms=1s
目前磁盘的传输速率普遍为100MB/s,计算出最佳块大小为100MB/s*1s=100MB,所以设定块大小为128MB
在工业生产中磁盘传输速率为200MB/s时,一般设定块大小为256MB
磁盘传输速率为400MB/s时,一般设定block大小为512MB
- 小文件不会占据整个数据块的空间
- 通过命令可查文件所占块数及相关数据信息
hdfs fsck /j2ee.txt[需要检查的文件] -files[文件] -locations[显示文件位置] -includeSnapshots -blocks[块] -racks -storagepolicies
1.文件大小可以大于集群中任意磁盘大小,因为最终大文件会被切分存储于不同DN
2.文件被切分后,只需要考虑文件被切分后固定128M大小的数据块如何存储,简化存储子系统,使存储更加方便
下载文件时可以提前划分好空间,然后通过多线程的方式下载,这样做更快且防止了下载90%时文件超过磁盘空间导致整个下载失败
3.数据块非常适合用于数据的备份,从而提高数据的容错能力;当数据丢失时,可以以块为单位找回,而不涉及文件整体;当要使用一个文件时,只需要将这个文件对应的块进行临时的拼接即可
2.机架感知
- 数据块副本存放的实现过程称为机架感知,默认是关闭的
- 如果集群中的机器都跑在一个机架上,那么集群下的节点默认都在/default-rack下,可以启动hadoop集群的时候查看logs/namenode.log
- 查看机架感知:hdfs dfsadmin -printTopology

- 机架感知配置(此处只是感受机架感知,未来公司会不同)
1.进入目录 cd /usr/local/hadoop-2.7.1/etc/hadoop
2.创建文件 mkdir rackaware
3.进入目录 cd rackaware
4.编写配置文件 vim topology.data
192.168.10.100 node1 /dc1/rack1
192.168.10.101 node2 /dc1/rack2
192.168.10.102 node3 /dc1/rack2
192.168.10.103 node4 /dc1/rack3
5.编写脚本 vim rackaware.sh (将脚本中的中文删除)
#!/bin/bash
HADOOP_CONF=/usr/local/hadoop-2.7.1/etc/hadoop/rackaware
while [ $# -gt 0 ] ; do
nodeArg=$1
exec<${HADOOP_CONF}/topology.data
result=""
while read line ; do
ar=( $line )
if [ "${ar[0]}" = "$nodeArg" ]||[ "${ar[1]}" = "$nodeArg" ]; then
result="${ar[2]}"
fi
done
shift
if [ -z "$result" ] ; then
echo -n "/default-rack"
else
echo -n "$result"
fi
done
6.修改脚本权限 chmod a+x rackaware.sh
a表示所有用户,g表示组用户,o表示其它用户,x表示执行权限
7.测试 sh rackaware.sh 192.168.10.100 node2
8.启用机架感知 vim core-site.xml
<property>
<name>net.topology.script.file.name</name>
<value>/usr/local/hadoop-2.7.1/etc/hadoop/rackaware/rackaware.sh</value>
</property>
9.将rackaware.sh与core-site.xml发送到node2,3,4节点
scp -r ./rackaware root@node2:`pwd`
scp -r core-site.xml root@node2:`pwd`
10.重启hdfs
stop-all.sh
start-dfs.sh
11.查看机架感知 hdfs dfsadmin -printTopology
3.数据块副本存放策略
- 存放策略的好坏涉及系统的健壮性,若副本都堆积统一节点,该节点崩溃系统还是不可用
- 第一个副本放在上传文件的DN,若是集群外提交则随机挑选一台磁盘不太满的,CPU不太忙的节点
- 第二个副本放在不同于第一个副本的机架节点
- 第三个副本放在与第二个副本相同机架节点
- 更多副本则随机节点
4.数据块的备份数配置
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
- 通过命令更改已上传的文件副本数:hadoop fs -setrep -R 3 /
- 上传文件的同时指定创建的副本数:hdfs dfs -Ddfs.replication=1 -put core-site.xml /
- 查看当前hdfs的副本数:hdfs fsck -locations
5.安全模式
- 安全模式指在不加载第三方设备驱动情况下启动机器,便于检测与修复,即在安全模式下对于客户端是只读的
- 常应用于启动或者重新启动hdfs时,收集DN信息或HDFS维护升级
- 操作命令
1.退出安全模式:hdfs dfsadmin -safemode leave
2.进入安全模式:hdfs dfsadmin -safemode enter
3.查看安全模式状态:hdfs dfsadmin -safemode get
4.等到安全模式结束:hdfs dfsadmin -safemode wait
- 对hdfs文件系统进行检查:hdfs fsck /
-move: 移动损坏的文件到/lost+found目录下
-delete: 删除损坏的文件
-files: 输出正在被检测的文件
-openforwrite: 输出检测中的正在被写的文件
-includeSnapshots: 检测的文件包括系统snapShot快照目录下的
-list-corruptfileblocks: 输出损坏的块及其所属的文件
-blocks: 输出block的详细报告
-locations: 输出block的位置信息
-racks: 输出block的网络拓扑结构信息
-storagepolicies: 输出block的存储策略信息
-blockId: 输出指定blockId所属块的状况,位置等信息
源码分析:https://blog.csdn.net/Androidlushangderen/article/details/50996821?utm_source=blogxgwz9
6.负载均衡
- HDFS集群非常容易出现机器与机器之间磁盘利用率不平衡的情况,且集群的性能由集群的最慢节点决定。当数据不平衡时,Map任务可能会分配到没有存储数据的机器,这将导致网络带宽的消耗,也无法很好的进行本地计算
- 当HDFS负载不均衡时,需要对各节点机器上数据的存储分布进行调整,从而让数据均匀的分布在各个DataNode上,均衡IO性能,防止热点的发生
- 进行数据的负载均衡调整,必须要满足如下原则
数据平衡不能导致数据块减少,数据块备份丢失
管理员可以中止数据平衡进程
每次移动的数据量以及占用的网络资源,必须是可控的
数据均衡过程,不能影响namenode的正常工作
- 负载均衡的核心是数据均衡算法,该数据均衡算法将不断迭代数据均衡逻辑,直至集群内数据均衡为止,该数据均衡算法每次迭代的逻辑如下

- DN在何时才需要负载均衡?将DataNode分组

Over组超过阈值,Above组超过平均值,Below组低于平均值,Under组低于阈值
Over组、Above组中的块向Below组、Under组移动
1.设置阈值:start-balancer.sh –threshold [参数]
参数表示阈值,默认设置10,范围0-100,理论上该参数设置的越小,整个集群就越平衡
2.配置带宽命令:dfs.balance.bandwidthPerSec
默认1048576(1M/S)
3.配置带宽全局:vim hdfs-site.xml
<property>
<name>dfs.balance.bandwidthPerSec</name>
<value>1048576</value>
</property>
4.关闭负载均衡:stop-balancer.sh
5.设置定时任务实现定时负载均衡:00 22 * * 5 hdfs balancer -Threshold 5 >>/home/logs/balancer_`date +"\%Y\%m\%d"`.log 2>&1
7.心跳机制
- 主节点和从节点之间的通信是通过心跳机制(RPC函数)实现
- 心跳机制
1.master启动时开启RPC server
2.slave启动时连接master并每隔3秒钟主动向master发送心跳,将自己的状态信息告诉master,然后master通过这个心跳的返回值向slave节点传达指令
DataNode每隔3s向NameNode发送心跳,发送的内容主要是本地磁盘上块的使用情况,1h做一次整体块汇报
当长时间没有发送心跳时,NameNode就判断DataNode的连接已经中断,把该DN定性为dead node,NameNode会检查dead node中的副本数据,并复制到其他的data node中
NodeManager每隔3s向ResourceManager发送心跳,发送的内容主要是本节点COU,内存等
ApplicationMaster向ResourceManager申请资源,返还资源
TaskTracker向JobTracker汇报节点和任务运行状态信息
为Tasktracker分配任务,判断Tasktracker是否活着,及时让Jobtracker获取各个节点上的资源使用情况和任务运行状态
8.数据块损坏处理
- DN有自检功能,当数据块创建3周后自动触发校验和运算以保证集群中数据块的安全
- 如何自检?校验和是啥?
Hadoop创建文件时,同时在同一个文件夹下创建隐藏文件a.crc,该隐藏文件记录了文件的校验和
(校验和:争对文件大小每512字节生成32位校验和)
写入文件时,hdfs为每个数据块都生成一个crc文件
客户端读取文件时,按同样的算法生成crc文件,对比生成的crc文件与存储的crc文件,
不匹配则损坏,损坏则读副本
HDFS体系结构
1.主从架构
2.NameNode
3.DataNode
4.SecondaryNameNode
- 备份NN,合并fsimage与edit logs,节省启动时间