HDFS入门
1.HDFS基本概念:
HDFS是Hadoop Distribute File System 的简称,意为:Hadoop分布式文件系统。是Hadoop核心组件之一,作为最底层的分布式存储服务而存在。
分布式文件系统解决的问题就是大数据存储。
2. HDFS重要特性
A:是一个文件系统 用于存储文件的 提供统一命名空间的目录树结构 便于用户操作文件系统
B:是一个分布式文件系统 分布式意味着多台机器 当中有不同的角色 各司其职 共同配合。
2.1. master/slave主从架构
HDFS采用master/slave架构。一般一个HDFS集群是有一个Namenode和一定数目的Datanode组成。Namenode是HDFS集群主节点,Datanode是HDFS集群从节点,两种角色各司其职,共同协调完成分布式的文件存储服务。
- 主角色:namenode 管理文件系统元数据(目录树结构 文件和块的对应信息)
- 从角色:datanode 负责具体数据块存储 定时向nn进行块的汇报
2.2. 分块存储
HDFS中的文件在物理上是分块存储(block)的,块的大小可以通过配置参数来规定,默认大小在hadoop2.x版本中是128M。
hadoop 2.x block size = 128M
hadoop 1.x block size = 64M
2.3. Namenode元数据管理
目录结构及文件分块位置信息叫做元数据。Namenode负责维护整个hdfs文件系统的目录树结构,以及每一个文件所对应的block块信息(block的id,及所在的datanode服务器)。
2.4. Datanode数据存储
文件的各个block的具体存储管理由datanode节点承担。每一个block都可以在多个datanode上。Datanode需要定时向Namenode汇报自己持有的block信息。
存储多个副本(副本数量也可以通过参数设置dfs.replication,默认是3)。
2.5. 副本机制
hadoop默认的副本数是3(1 + 2 = 3)
为了容错,文件的所有block都会有副本。每个文件的block大小和副本系数都是可配置的。应用程序可以指定某个文件的副本数目。副本系数可以在文件创建的时候指定,也可以在之后改变。
2.6. 一次写入,多次读出
hdfs没有数据修改操作 主要是支持大数据查询分析需求
3.HDFS 基本操作
3.1. Shell 命令选项
选项名称 | 使用格式 | 含义 |
---|---|---|
-ls | -ls <路径> | 查看指定路径的当前目录结构 |
-lsr | -lsr <路径> | 递归查看指定路径的目录结构 |
-du | -du <路径> | 统计目录下个文件大小 |
-dus | -dus <路径> | 汇总统计目录下文件(夹)大小 |
-count | -count [-q] <路径> | 统计文件(夹)数量 |
-mv | -mv <源路径> <目的路径> | 移动 |
-cp | -cp <源路径> <目的路径> | 复制 |
-rm | -rm [-skipTrash] <路径> | 删除文件/空白文件夹 |
-rmr | -rmr [-skipTrash] <路径> | 递归删除 |
-put | -put <多个linux上的文件> <hdfs路径> | 上传文件 |
-copyFromLocal | -copyFromLocal <多个linux上的文件> <hdfs路径> | 从本地复制 |
-moveFromLocal | -moveFromLocal <多个linux上的文件> <hdfs路径> | 从本地移动 |
-getmerge | -getmerge <源路径> <linux路径> | 合并到本地 |
-cat | -cat <hdfs路径> | 查看文件内容 |
-text | -text <hdfs路径> | 查看文件内容 |
-copyToLocal | -copyToLocal [-ignoreCrc] [-crc] [hdfs源路径] [linux目的路径] | 从本地复制 |
-moveToLocal | -moveToLocal [-crc] <hdfs源路径> <linux目的路径> | 从本地移动 |
-mkdir | -mkdir <hdfs路径> | 创建空白文件夹 |
-setrep | -setrep [-R] [-w] <副本数> <路径> | 修改副本数量 |
-touchz | -touchz <文件路径> | 创建空白文件 |
-stat | -stat [format] <路径> | 显示文件统计信息 |
-tail | -tail [-f] <文件> | 查看文件尾部信息 |
-chmod | -chmod [-R] <权限模式> [路径] | 修改权限 |
-chown | -chown [-R] 属主] 路径 | 修改属主 |
-chgrp | -chgrp [-R] 属组名称 路径 | 修改属组 |
-help | -help [命令选项] | 帮助 |
3.2. Shell常用命令介绍
格式:
hadoop fs <agrs> 文件系统的协议: //主机名: host/文件路径
A:-ls
使用方法:hadoop fs -ls [-h] [-R] <args>
功能:显示文件、目录信息。
hadoop fs -ls file:/// ##访问的是本地文件系统
hadoop fs -ls hadf://主机名:8020/ ##访问的是hdfs文件系统
hadoop fs -ls gfs://主机名:9999/ ##访问谷歌文件系统
hadoop fs -ls / ##不指定默认访问文件系统 fs.defaultFS
B:-mkdir
使用方法:hadoop fs -mkdir [-p] <paths>
功能:在hdfs上创建目录,-p表示会创建路径中的各级父目录。
示例:hadoop fs -mkdir –p /user/hadoop/dir1
C:-put
put 上传操作 从本地文件系统复制到目标文件系统
本地文件系统(执行命令所在的客户端的文件系统)
目标文件系统(hdfs)
使用方法及举例:
使用方法:hadoop fs -put [-f] [-p] [ -|<localsrc1> .. ]. <dst>
功能:将单个src或多个srcs从本地文件系统复制到目标文件系统。
-p:保留访问和修改时间,所有权和权限。
-f:覆盖目的地(如果已经存在)
完整格式:
hadoop fs -put file:///root/example-mr-1.2.jar hdfs://node-1:8020/a/b/c
省略格式:
hadoop fs -put example-mr-1.2.jar /a/b/
<1>上传新文件
hdfs fs -put file:/root/test.txt hdfs:/ #上传本地test.txt文件到HDFS根目录,HDFS根目录须无同名文件,否则“File exists”
hdfs fs -put test.txt /test2.txt #上传并重命名文件。
hdfs fs -put test1.txt test2.txt hdfs:/ #一次上传多个文件到HDFS路径。
<2>上传文件夹
hdfs fs -put mypkg /newpkg #上传并重命名了文件夹。
<3>覆盖上传
hdfs fs -put -f /root/test.txt / #如果HDFS目录中有同名文件会被覆盖
copyFromLocal(上传)
<1>上传文件并重命名
hadoop fs -copyFromLocal file:/test.txt hdfs:/test2.txt
<2>覆盖上传
hadoop fs -copyFromLocal -f test.txt /test.txt
D:-get
get 下载操作 将文件下载到本地文件系统
本地文件系统[执行命令所在的客户端的文件系统]
使用方法及举例:
使用方法:hadoop fs -get [-ignorecrc] [-crc] [-p] [-f] <src> <localdst>
-ignorecrc:跳过对下载文件的CRC检查。
-crc:为下载的文件写CRC校验和。
功能:将文件复制到本地文件系统。
<1>拷贝文件到本地目录
hadoop fs -get hdfs:/test.txt file:/root/
<2>拷贝文件并重命名。可以简写
hadoop fs -get /test.txt /root/test.txt
copyToLocal(下载)
<1>拷贝文件到本地目录
hadoop fs -copyToLocal hdfs:/test.txt file:/root/
<2>拷贝文件并重命名。可以简写
hadoop fs -copyToLocal /test.txt /root/test.txt
E:appendToFile
使用方法:hadoop fs -appendToFile <localsrc> ... <dst>
功能:追加一个文件到已经存在的文件末尾
举例:
<1>读取本地文件内容追加到HDFS文件
hadoop fs - appendToFile file:/test.txt hdfs:/newfile.txt
用到最多:hdfs上小文件的合并
<2>合并小文件
hadoop fs -appendToFile 2.txt 3.txt /a/1.txt
F:getmerge
功能:合并下载多个文件
示例:比如hdfs的目录 /aaa/下有多个文件:log.1, log.2,log.3,...
代码:
hadoop fs -getmerge /aaa/log.* ./log.sum
3.3其他:
setrep:
- 注意事项: 可以通过该命令修改hdfs中文件副本个数 在企业中避免使用该操作
- 进行副本设置修改的操作 需要hdfs集群配合文件进行数据复制 降低对外提供正常服务能力
- 通常一批文件设置为几个副本 在上传前就需要决定好
-cat
使用方法:hadoop fs -cat [-ignoreCrc] URI [URI ...]
功能:显示文件内容到stdout
示例:hadoop fs -cat /hadoop/hadoopfile
-tail
使用方法:hadoop fs -tail [-f] URI
功能:将文件的最后一千字节内容显示到stdout。
-f选项将在文件增长时输出附加数据。
示例:hadoop fs -tail /hadoop/hadoopfile
-chgrp
使用方法:hadoop fs -chgrp [-R] GROUP URI [URI ...]
功能:更改文件组的关联。用户必须是文件的所有者,否则是超级用户。
-R将使改变在目录结构下递归进行。
示例:hadoop fs -chgrp othergroup /hadoop/hadoopfile
-chmod
功能:改变文件的权限。使用-R将使改变在目录结构下递归进行。
示例:hadoop fs -chmod 666 /hadoop/hadoopfile
-chown
功能:改变文件的拥有者。使用-R将使改变在目录结构下递归进行。
示例:hadoop fs -chown someuser:somegrp /hadoop/hadoopfile
-copyFromLocal
使用方法:hadoop fs -copyFromLocal <localsrc> URI
功能:从本地文件系统中拷贝文件到hdfs路径去
示例:hadoop fs -copyFromLocal /root/1.txt /
-copyToLocal
功能:从hdfs拷贝到本地
示例:hadoop fs -copyToLocal /aaa/jdk.tar.gz
-cp
功能:从hdfs的一个路径拷贝hdfs的另一个路径
示例: hadoop fs -cp /aaa/jdk.tar.gz /bbb/jdk.tar.gz.2
-mv
功能:在hdfs目录中移动文件
示例: hadoop fs -mv /aaa/jdk.tar.gz /
-getmerge
功能:合并下载多个文件
示例:比如hdfs的目录 /aaa/下有多个文件:log.1, log.2,log.3,...
hadoop fs -getmerge /aaa/log.* ./log.sum
-rm
功能:删除指定的文件。只删除非空目录和文件。-r 递归删除。
示例:hadoop fs -rm -r /aaa/bbb/
-df
功能:统计文件系统的可用空间信息
示例:hadoop fs -df -h /
-du
功能:显示目录中所有文件大小,当只指定一个文件时,显示此文件的大小。
示例:hadoop fs -du /user/hadoop/dir1
-setrep
功能:改变一个文件的副本系数。-R选项用于递归改变目录下所有文件的副本系数。
示例:hadoop fs -setrep -w 3 -R /user/hadoop/dir1
4. HDFS文件限额操作
- 可以设置某个文件夹可以用于多少个子文件 或者文件的大小限制
- 强制限制 超过即禁止
4.1数量限额;
hadoop fs -mkdir -p /user/root/文件夹名 #创建hdfs文件夹
hdfs dfsadmin -setQuota 2 文件夹名 # 给该文件夹下面设置最多上传两个文件,上传文件,发现只能上传一个文件
hdfs dfsadmin -clrQuota /user/root/文件夹名 # 清除文件数量限制
4.2空间大小限额:
hdfs dfsadmin -setSpaceQuota 4k /user/root/文件夹名 # 限制空间大小4KB
hdfs dfs -put /export/softwares/zookeeper-3.4.5-cdh5.14.0.tar.gz /user/root/文件夹名
上传超过4Kb的文件大小上去提示文件超过限额
hdfs dfsadmin -clrSpaceQuota /user/root/文件夹名 #清除空间限额
hdfs dfs -put /export/softwares/zookeeper-3.4.5-cdh5.14.0.tar.gz /user/root/文件夹名
4.3查看hdfs文件限额数量
hdfs dfs -count -q -h /user/root/文件夹名
5.HDFS基本原理:
5.1. NameNode概述
a、 NameNode是HDFS的核心。
b、 NameNode也称为Master。
c、 NameNode仅存储HDFS的元数据:文件系统中所有文件的目录树,并跟踪整个集群中的文件。
d、 NameNode不存储实际数据或数据集。数据本身实际存储在DataNodes中。
e、 NameNode知道HDFS中任何给定文件的块列表及其位置。使用此信息NameNode知道如何从块中构建文件。
f、 NameNode并不持久化存储每个文件中各个块所在的DataNode的位置信息,这些信息会在系统启动时从数据节点重建。
g、 NameNode对于HDFS至关重要,当NameNode关闭时,HDFS / Hadoop集群无法访问。
h、 NameNode是Hadoop集群中的单点故障。
i、 NameNode所在机器通常会配置有大量内存(RAM)。
5.2. DataNode概述
a、 DataNode负责将实际数据存储在HDFS中。
b、 DataNode也称为Slave。
c、 NameNode和DataNode会保持不断通信。
d、 DataNode启动时,它将自己发布到NameNode并汇报自己负责持有的块列表。
e、 当某个DataNode关闭时,它不会影响数据或群集的可用性。NameNode将安排由其他DataNode管理的块进行副本复制。
f、 DataNode所在机器通常配置有大量的硬盘空间。因为实际数据存储在DataNode中。
g、 DataNode会定期(dfs.heartbeat.interval配置项配置,默认是3秒)向NameNode发送心跳,如果NameNode长时间没有接受到DataNode发送的心跳, NameNode就会认为该DataNode失效。
h、 block汇报时间间隔取参数dfs.blockreport.intervalMsec,参数未配置的话默认为6小时.
5.3. HDFS的工作机制
NameNode负责管理整个文件系统元数据;DataNode负责管理具体文件数据块存储;Secondary NameNode协助NameNode进行元数据的备份。
HDFS的内部工作机制对客户端保持透明,客户端请求访问HDFS都是通过向NameNode申请来进行。
5.4. NN和DN之间的汇报机制
- 启动集群的时候 首先启动namenode 然后启动datanode
- datanode启动的时候需要进行两件事
- 去namenode进行注册汇报 报告自己启动成功 --->我活了
- 去namenode汇报自己本机持有哪些数据块
- 集群启动之后 正常工作期间 还需要间隔指定的时间进行汇报
- datanode每隔3秒进行心跳 目的:报活
dfs.heartbeat.interval(命令如下)
- datanode每间隔6小时 汇报自己持有块信息(命令如下)
dfs.blockreport.intervalMsec
- 在启动的过程中 hdfs会进入所谓**安全模式** 数据只可以读不可以写 内部进行数据完整性校验
6.HDFS文件上传流程:
图一:
详细文字解释:
1. 客户端拿到一个文件,跟namenode说,我要上传这个文件,上传到哪个目录下。我们假设这个文件名为 cjk.avi,目录为 /hadoop/hdfs/
2. namenode拿到这个文件后,获取文件名,然后去元数据中查找/hadoop/hdfs/中是否已经存在相同文件名的文件,如果没有,那么告诉客户端说你可以上传这个文件
3. 客户端接到可以上传文件的命令后,会将文件进行切分(hadoop2.X是128M),切分成N(N>=1)块,如果切成n块,那么除去最后一个,其它块的大小都是一样的。
4. 客户端拿到第一个块block01后,跟namenode说,我要上传block01,然后namenode去自身的datanode信息池中查找应该上传到哪几个datanode(备份数)中,然后将查询到的datanode的信息告诉客户端
5. 客户端拿到datanode的信息后,开辟一个socket流将block01上传到namenode返回的datanode中最近的一个datanode节点,然后这个datanode节点会对block01进行水平备份,也就是将数据从datanode本地复制到其他指定的机器上。
6. datanode将数据水平备份完成之后,会通知客户端,说block01上传成功
7. 然后客户端会通知namenode说block01上传成功,此时namenode会将元数据(可以简单地理解为记录了block块存放到哪个datanode中)同步到内存中
8. 其他的block块循环上面的过程
9. 至此一个大文件就上传到hdfs中了
7.HDFS文件下载流程:
详细文字解释:
1. Client向namenode发起RPC请求 , 确定请求文件block所在的位置
2. nn的元数据会对请求进行判断 , 根据情况返回文件的部分或者全部blk列表 , 且每个blk , nn都会返回含有该blk副本的datanode地址
3. 返回的dn地址 , 会按照集群拓扑结构得出dn与客户端的距离并进行排序 , **排序两个规则**:网络拓扑结构中距离 Client 近的排靠前;心跳机制中超时汇报的 DN 状态为 STALE,这样的排靠后
4. Client选取排序靠前的dn来读取blk , 若客户端本身就是dn , 那么直接从本地直接获取数据
5. 底层上本质是建立Socket Stream(FSDataInputStream) , 重复的调用父类DataInputStream的read方法 , 知道这个块上的数据读取完毕
6. 当读取完列表的blk之后 , 若文件读取还没有结束 , 客户端会继续向nn获取下一批的blk列表
7. 读取完一个blk都会进行checksum验证 , 如果读取dn时出现错误 , 客户端会通知nn , 然后再从下一个拥有blk副本的dn继续读
8. read方法是并行的读取blk信息 , 不是一块一块的读取 , nn只返回Client请求包含块的dn地址 , 并不返回数据
9. 最终读取来所有的blk合并成一个完整的文件.
8.HDFS的应用操作:
-
开发的版本的选择
-
因为服务器环境搭建使用的cdh 版本 ,本地开发jar版本理应也是cdh
-
cdh和apache 相同版本中 api 代码 逻辑是没有区别的
-
如果使用cdh 需要手动添加cloudera maven仓库 因为它是商业公司
-
-
问题1:客户端身份的权限问题
Permission denied: user=AllenWoon, access=WRITE, inode="/":root:supergroup:drwxr-xr-x
-
解决: 在客户端设置访问文件系统身份
-
-
问题2: hadoop本地环境的问题
-
报错现象
ERROR - Failed to locate the winutils binary in the hadoop binary path java.io.IOException: Could not locate executable null\bin\winutils.exe in the Hadoop binaries. WARN - Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
-
原因:hadoop往windows平台进行数据写操作的时候 需要winutils.exe 配合才能交互。winutils.exe来自hadoop源码中C++本地库的支持。
-
解决:把hadoop源码在windows进行编译 得到winutils.exe 达到和本地操作交互的能力
-
安装: 把windows编译的hadoop解压到一个路径(没有中文 没有空格)
-
配置hadoop环境变量
HADOOP_HOME=C:\Work\soft\hadoop-2.6.0-cdh5.14.0 PATH=;%HADOOP_HOME%\bin
-
首先cmd 验证hadoop环境变量是否正确
-
确保之前安装的jdk路径也是没有中文 没有空格的
-
重启idea开发工具
-
-
-
跨hdfs集群数据复制
-
命令 distcp
hadoop distcp hdfs://node-1:8020/1.txt hdfs://itcast:8020/test/
-
使用场合
业务中涉及生成环境和开发环境之间某些数据进行交流的时候使用
-
-
hadoop archive的使用
-
产生背景:hdfs架构设计不利于小文件存储 文件不管多小 都需要元数据描述记录 如果集群小文件过多
可能磁盘使用情况很低 但是内存使用确很高 俗称 小文件吃内存
-
档案的功能:通过mr程序 把多个小文件 合并成一个档案文件
-
archive的使用
-
档案的创建
hadoop archive -archiveName test.har -p /input /outputdir 档案建立成功 为了优化小文件吃内存的情况 可以把小文件删除 hadoop fs -rm -r /input
-
档案的查看
查看建立档案之后的样子 hadoop fs -ls hdfs://node-1:8020/outputdir/test.har 查看建立档案之前的样子 hadoop fs -ls har://hdfs-node-1:8020/outputdir/test.har 可以查询出该档案是由哪些小文件合并而来
-
档案的提取
串行提取 hadoop fs -cp har:///outputdir/test.har hdfs://node-1:8020/input hadoop distcp har:///outputdir/test.har hdfs://node-1:8020/input
-
档案的注意事项
-
-
-
hdfs 快照功能
-
创建快照相当于给hdfs系统设置备份
-
创建快照的前提是文件夹已经存在
-
创建快照需要两步
-
首先允许其设置快照
hdfs dfsadmin -allowSnapshot /small
-
然后再是设置创建快照
hdfs dfs -createSnapshot /small
-
浏览快照
http://node-1:50070/explorer.html#/small/.snapshot
-
-