Hadoop HDFS
一:HDFS架构图
HDFS:分布式文件系统 Hadoop Distributed File System
Block数据块
- 基本存储单位,一般大小为64M,配置大的块主要是因为:
- 减少搜寻时间,一般硬盘传输速率比寻道时间要快,大的块可以减少寻道时间;
- 减少管理块的数据开销,每个块都需要在NameNode上有对应的记录;
- 对数据块进行读写,减少建立网络的连接成本
- 一个大文件会被拆分成一个个的块,然后存储于不同的机器。如果一个文件少于Block大小,那么实际占用的空间为其文件的大小
- 基本的读写单位,类似于磁盘的页,每次都是读写一个块
- 每个块都会被复制到多台机器,默认复制3份
NameNode
-
存储文件的metadata,运行时所有数据都保存到内存,整个HDFS可存储的文件数受限于NameNode的内存大小
-
一个Block在NameNode中对应一条记录(一般一个block占用150字节),如果是大量的小文件,会消耗大量内存。同时map task的数量是由splits来决定的,所以用MapReduce处理大量的小文件时,就会产生过多的map task,线程管理开销将会增加作业时间。处理大量小文件的速度远远小于处理同等大小的大文件的速度。因此Hadoop建议存储大文件
-
数据会定时保存到本地磁盘,但不保存block的位置信息,而是由DataNode注册时上报和运行时维护(NameNode中与DataNode相关的信息并不保存到NameNode的文件系统中,而是NameNode每次重启后,动态重建)
-
NameNode失效则整个HDFS都失效了,所以要保证NameNode的可用性
Secondary NameNode
定时与NameNode进行同步(定期合并文件系统镜像和编辑日志,然后把合并后的传给NameNode,替换其镜像,并清空编辑日志,类似于CheckPoint机制),但NameNode失效后仍需要手工将其设置成主机。
DataNode
-
保存具体的block数据
-
负责数据的读写操作和复制操作
-
DataNode启动时会向NameNode报告当前存储的数据块信息,后续也会定时报告修改信息
-
DataNode之间会进行通信,复制数据块,保证数据的冗余性
二:Hadoop 写文件
-
客户端将文件写入本地磁盘的HDFS Client文件中
-
当临时文件大小达到一个block大小时,HDFS client通知NameNode,申请写入文件
-
NameNode在HDFS的文件系统中创建一个文件,并把该block id和要写入的DataNode的列表返回给客户端
-
客户端收到这些信息后,将临时文件写入DataNodes
4.1 客户端将文件内容写入第一个DataNode(一般以4kb为单位进行传输)4.2 第一个DataNode接收后,将数据写入本地磁盘,同时也传输给第二个DataNode
4.3 依此类推到最后一个DataNode,数据在DataNode之间是通过pipeline的方式进行复制的
4.4 后面的DataNode接收完数据后,都会发送一个确认给前一个DataNode,最终第一个DataNode返回确认给客户端
4.5 当客户端接收到整个block的确认后,会向NameNode发送一个最终的确认信息
4.6 如果写入某个DataNode失败,数据会继续写入其他的DataNode。然后NameNode会找另外一个好的DataNode继续复制,以保证冗余性
4.7 每个block都会有一个校验码,并存放到独立的文件中,以便读的时候来验证其完整性
-
文件写完后(客户端关闭),NameNode提交文件(这时文件才可见,如果提交前,NameNode垮掉,那文件也就丢失了。fsync:只保证数据的信息写到NameNode上,但并不保证数据已经被写到DataNode中)
三:Hadoop 读文件
- 客户端向NameNode发送读取请求
- NameNode返回文件的所有block和这些block所在的DataNodes(包括复制节点)
- 客户端直接从DataNode中读取数据,如果该DataNode读取失败(DataNode失效或校验码不对),则从复制节点中读取(如果读取的数据就在本机,则直接读取,否则通过网络读取)
四:HDFS 可靠性
-
DataNode可以失效,DataNode会定时发送心跳到NameNode。如果一段时间内NameNode没有收到DataNode的心跳消息,则认为其失效。此时NameNode就会将该节点的数据(从该节点的复制节点中获取)复制到另外的DataNode中
-
数据可以毁坏,无论是写入时还是硬盘本身的问题,只要数据有问题(读取时通过校验码来检测),都可以通过其他的复制节点读取,同时还会再复制一份到健康的节点中
-
NameNode不可靠
五:hadoop fs
- hdfs dfs: 只能操作HDFS上的文件
- hadoop fs:除了能操作HDFS上的文件还可以操作本地文件
在使用HDFS Shell时为了减少不必要的日志,建议把日志调试正INFO级别,如果是DEBUG级别每执行一个命令就会打印很多内容。
hadoop-env.sh
export HADOOP_ROOT_LOGGER=INFO,console
1. hadoop fs -help
帮助命令, 用于查看某个命令如何使用
# 查看fs所有的命令
hadoop fs -help
# 查看ls命令的用法
hadoop fs -help ls
2. hadoop fs -mkdir
# 创建多级目录
hadoop fs -mkdir -p /helloworld/input
3. hadoop fs -moveFromLocal 、hadoop fs -put、hadoop fs -copyFromLocal
上传本地文件:将本地文件上传到hdfs中。
# 上传成功后会删除本地文件
hadoop fs -moveFromLocal <本地文件路径> <HDFS目录路径>
# 上传成功后不会删除本地文件
hadoop fs -put <本地目录> <HDFS目录>
# 复制本地目录到HDFS目录, 不会删除本地文件
hadoop fs -copyFromLocal <本地目录> <HDFS目录>
# 创建两个文件
echo "hello hadoop hdfs test" > /tmp/test.txt
echo "Hadoop Distributed File System foo" > /tmp/foo.txt
cho "hdfs foobar" > /tmp/foobar.txt
# 会删除/tmp/test.txt文件
hadoop fs -moveFromLocal /tmp/test.txt /helloworld/input
# 不会删除/tmp/foo.txt文件
hadoop fs -put /tmp/foo.txt /helloworld/input
# 和put类似,不会删除本地文件
hadoop fs -copyFromLocal /tmp/foobar.txt /helloworld/input
4.列举目录内容
# 查看根目录下的内容
hadoop fs -ls <HDFS文件目录>
# -R:递归显示
hadoop fs -ls -R <HDFS文件目录>
# 列举根目录文件
hadoop fs -lsr /
# 递归列举根目录文件
hadoop fs -ls -R /
# 列举指定目录文件
hadoop fs -ls /helloworld/input
5. 查看文件内容
hadoop fs -cat <文件路径>
hadoop fs -text <文件路径>
# 显示HDFS上某文件最后1kb内容
hadoop fs -tail <HDFS文件路径>
# 显示HDFS上某文件最后1kb内容, 如果有心数据进来会实时显示
hadoop fs -tail -f <HDFS文件路径>
hadoop fs -cat /helloworld/input/foo.txt
hadoop fs -text /helloworld/input/foo.txt
hadoop fs -tail /helloworld/input/foo.txt
6. hadoop fs -cp
# 将HDFS某个文件复制到HDFS其它路径下
hadoop fs -cp <HDFS文件源路径> <HDFS文件目标路径>
hadoop fs -cp /helloworld/input/foobar.txt /helloworld/input/foobar.backup.txt
7. hadoop fs -mv
# 移动HDFS上的文件
hadoop fs -mv <HDFS文件源路径> <HDFS文件目标路径>
hadoop fs -mv /helloworld/input/foobar.backup.txt /helloworld/backup
8. hadoop fs -appendToFile
# 将本地文件的内容追加到HDFS某文件内容的末尾
hadoop fs -appendToFile <本地文件路径> <HDFS文件路径>
echo "append content" > /tmp/a.txt
hadoop fs -appendToFile /tmp/a.txt /helloworld/input/foobar.txt
hadoop fs -cat /helloworld/input/foobar.txt
9. hadoop fs -find
根据名称查找文件
# name 不区分大小写
# iname 区分大小写
# print 打印(默认)
# print0 打印在一行
hadoop fs -find <路径> -name <文件名> -print
hadoop fs -find /helloworld/input/ -name foo.txt
10. hadoop fs -count
# 统计目录文件大小
hadoop fs -count <HDFS路径>
hadoop fs -count /helloworld/input
11. hadoop fs -copyToLocal、hadoop fs -get、hadoop fs -getmerge
# 将HDFS目录下载到本地文件
hadoop fs -copyToLocal <HDFS文件路径> <本地目录>
hadoop fs -get <HDFS文件路径> <本地目录>
# 合并下载多个文件
hadoop fs -getmerge <HDFS目录路径> <本地文件路径>
hadoop fs -copyToLocal /helloworld/input /Users/mengday/Desktop/
hadoop fs -get /helloworld/input /Users/mengday/Desktop/download
hadoop fs -getmerge /helloworld/input /Users/mengday/Desktop/merge.txt
12. hadoop fs -rmdir、hadoop fs -rm
# 删除空文件夹
hadoop fs -rmdir <HDFS空文件夹>
# 递归(-r)删除文件或者文件夹
hadoop fs -rm -r <HDFS目录>
hadoop fs -rmr <HDFS目录>
hadoop fs -rm -r /helloworld/backup
13. hadoop fs -chgrp、hadoop fs -chmod、hadoop fs -chown
# 修改某目录的所有组为root用户
hadoop fs -chgrp -R root <hdfs目录>
# 修改文件权限
hadoop fs -chmod -R 777 <hdfs目录>
# 修改所有者为root用户
hadoop fs -chown -R root <hdfs目录>
六:hadoop fsck
- move: 移动损坏的文件到/lost+found目录下
- delete: 删除损坏的文件
- openforwrite: 输出检测中的正在被写的文件
- list-corruptfileblocks: 输出损坏的块及其所属的文件
- files: 输出正在被检测的文件
- blocks: 输出block的详细报告 (需要和-files参数一起使用)
- locations: 输出block的位置信息 (需要和-files参数一起使用)
- racks: 输出文件块位置所在的机架信息(需要和-files参数一起使用
# 查看HDFS中某个文件的块block分布
hadoop fsck / -files -blocks -locations -racks
# 检测存在那些坏块
hdfs fsck /
# 删除坏块
hdfs fsck / -delete
七:参考文章:
下一篇: hdfs操作