HDFS概述
HDFS的功能与应用场景
功能
实现分布式文件存储,提供分布式文件读写。
过程
分:将一个大的文件拆分为多个小的部分(block块,默认为128M),将块储存在不同的节点上。
合:读取时将所有块进行合并,返回给用户。
HDFS存储的是块,而用户操作的是文件。NameNode存储了元数据(记录文件和块的映射关系)。
应用场景
不同的存储需求应该用不同的框架来实现。
HDFS要将数据储存到硬盘,速度不快,且块128M,显然:
HDFS适合:存储大数据量文件的场景;离线的场景、延迟性要求不高的场景;读写速度要求不高的场景;一次写入,多次读取的场景。
HDFS不适合:一条数据一条数据存储的场景(更适合使用数据库);读写速度要求较高的场景(更适合使用分布式硬盘、内存存储);频繁修改的场景(更适合使用内存存储)。
HDFS的分块与副本机制
分块机制
功能:用于实现分布式,将大文件拆分成为多个小的块。
块的大小是按照文件大小划分的,由属性决定。
在Hadoop官网:
查找配置文件,可以看到很多惊天大秘密。。。
HDFS默认配置有写:
换算出来Block块的大小就是128M。
或者去配置文件里也能找到类似的内容:
<property>
<name>dfs.blocksize</name>
<value>134217728</value>
</property>
默认就是128M为一块,如果不足128M就会按实际大小存储。
副本机制
HDFS的副本机制很像NAS机常用的raid1(raid0是类似双通道内存那样提速用的,raid1是2块硬盘记录完全相同的内容以确保数据的安全性)。
功能:为了保证数据块的安全,HDFS会为每个块构建副本,存储多份相同的内容。
HDFS的算法会自动将每个块复制多份,尽量存储在不同的机器上(也是由配置决定)。
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
可以看出默认配置是每个块存储3份。(银行的异地容灾一般也是备份3份)。
<property>
<name>dfs.datanode.data.dir</name>
<value>file:///export/server/hadoop-2.7.5/hadoopDatas/datanodeDatas</value>
</property>
HDFS中数据会储存在这个位置,由于笔者是3台虚拟机搭的集群,默认又是保存3份,故每个节点的该位置都会保存一套完整的数据。
在这个位置可以看到存储的文件被切成了2块128M和一块不足128M的内容。
主从架构
用户通过Client访问分布式服务HDFS的NameNode进程。NameNode进程会将需要存储的文件切分为128M的Block并将任务下发给DataNode进程,而用于记录分片映射关系(文件被切成几块、每块的位置)的元数据会由NameNode保存。
Client功能
Client是介于用户和Server之间的,用户操作客户端向服务端提交请求需要经过客户端,客户端供用户开发命令/代码,并将命令提交给服务端执行,还能将服务端运行的结果返回给用户。
NameNode功能
管理节点,同一时间只能有1个处于工作状态。
管理所有DataNode的状态(死活):通过心跳机制(所有的DataNode定期向NameNode发送心跳信号,如果NameNode长时间没有接收到心跳,就会判定为DataNode故障,网络状态不良时可能判作不健康)。
管理所有数据的安全(检查数据是否有丢失):通过汇报块机制(所有的DataNode会定期向NameNode汇报当前自己机器上所存储的数据块的情况,NameNode将每个DataNode汇报的信息与元数据进行比较,判断是否有数据丢失)。
管理元数据:NameNode管理的元数据都在内存中,所有数据的更新都是在内存中进行操作,为了掉电不丢失,也会在硬盘中存储快照(
由于在配置文件中写过:<property> <name>dfs.namenode.name.dir</name> <value>file:///export/server/hadoop-2.7.5/hadoopDatas/namenodeDatas</value> </property>
在该目录下的current里有个fsimage文件,这货就是存储在硬盘中的快照。每次NameNode启动会从fsimage文件中加载所有元数据到内存中,所有元数据更新都只更新内存元数据。快照的更新是借助SecondaryNameNode)。
接收客户端的读写请求:所有的HDFS客户端想要实现读写请求,必须指定NameNode的地址8020(配置文件中有写:fs.defaultFS = hdfs://node1:8020
)
DataNode功能
自身是存储节点(存储128M的Block数据块),接收NameNode的管理(分发的任务),接收客户端对块的读写请求(Client事实上是直接和DataNode传输64KB的Socket包的)。
数据写入流程
客户端会请求NameNode写入HDFS,NameNode会验证请求是否合法并返回结果(NameNode验证写入的文件是否存在、有没有权限写入等。如果不合法,直接拒绝请求)
NameNode返回对应的结果,构建这个文件的元数据,此时并没有跟块关联。
客户端提交第一个块的写入请求给NameNode。
NameNode根据每个DN的健康状态以及负载情况返回三台DataNode的地址,根据机架感知的分配规则,客户端所在的机架会存放一份,另外2份存储在另外的机架(老版本为了速度,会将2份存储在靠近客户端的机架。新版本是降低了速度,提高了机架的容错)。
客户端得到要写入数据块的三台DataNode地址,客户端会连接第一台(由机架感知决定,node1最近),提交写入。
三台DataNode构建一个数据传输的管道。
客户端将这个块拆分成多个packet【64k】,挨个发送个最近的DataNode1。
逐级返回写入成功的ack确认码,表示这个包写入完成(从硬件集群的机架内、机架间对拷硬盘比重新从客户端接收更高效,且客户端只需要传输一次,体验更好)。
不断发送下一个包,直到整个块写入完成,返回给NameNode,关联元数据。
重复提交下一个块的写入。
数据读取流程
启动方式
单进程访问
每条命令只启动一个进程,一般用于特殊场景。
启动HDFS:
hadoop-daemon.sh start namenode
hadoop-daemon.sh start datanode
启动YARN:
yarn-daemon.sh start resourcemanager
yarn-daemon.sh start nodemanager
分类启动
最常用,一条命令可以启动一类进程。
启动HDFS(NameNode的机器):
start-dfs.sh
stop-dfs.sh
启动YARN(ResourceManager的机器):
start-yarn.sh
stop-yarn.sh
全部启动
start-all.sh
操作不可控,一般不用。
文件管理命令
Client
所有能对HDFS进行读写的命令/程序,都可以作为HDFS的客户端。HDFS中提供了自带的命令客户端。
bin/hdfs
hdfs
Usage: hdfs [--config confdir] [--loglevel loglevel] COMMAND
where COMMAND is one of:
dfs run a filesystem command on the file systems supported in Hadoop.
classpath prints the classpath
namenode -format format the DFS filesystem
secondarynamenode run the DFS secondary namenode
namenode run the DFS namenode
journalnode run the DFS journalnode
zkfc run the ZK Failover Controller daemon
datanode run a DFS datanode
dfsadmin run a DFS admin client
haadmin run a DFS HA admin client
fsck run a DFS filesystem checking utility
balancer run a cluster balancing utility
jmxget get JMX exported values from NameNode or DataNode.
mover run a utility to move block replicas across
storage types
oiv apply the offline fsimage viewer to an fsimage
oiv_legacy apply the offline fsimage viewer to an legacy fsimage
oev apply the offline edits viewer to an edits file
fetchdt fetch a delegation token from the NameNode
getconf get config values from configuration
groups get the groups which users belong to
snapshotDiff diff two snapshots of a directory or diff the
current directory contents with a snapshot
lsSnapshottableDir list all snapshottable dirs owned by the current user
Use -help to see options
portmap run a portmap service
nfs3 run an NFS version 3 gateway
cacheadmin configure the HDFS cache
crypto configure HDFS encryption zones
storagepolicies list/get/set block storage policies
version print the version
Most commands print help when invoked w/o parameters.
可以看到有很多命令。
格式
hdfs dfs 命令 参数
Usage: hadoop fs [generic options]
[-appendToFile <localsrc> ... <dst>]
[-cat [-ignoreCrc] <src> ...]
[-checksum <src> ...]
[-chgrp [-R] GROUP PATH...]
[-chmod [-R] <MODE[,MODE]... | OCTALMODE> PATH...]
[-chown [-R] [OWNER][:[GROUP]] PATH...]
[-copyFromLocal [-f] [-p] [-l] <localsrc> ... <dst>]
[-copyToLocal [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
[-count [-q] [-h] <path> ...]
[-cp [-f] [-p | -p[topax]] <src> ... <dst>]
[-createSnapshot <snapshotDir> [<snapshotName>]]
[-deleteSnapshot <snapshotDir> <snapshotName>]
[-df [-h] [<path> ...]]
[-du [-s] [-h] <path> ...]
[-expunge]
[-find <path> ... <expression> ...]
[-get [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
[-getfacl [-R] <path>]
[-getfattr [-R] {-n name | -d} [-e en] <path>]
[-getmerge [-nl] <src> <localdst>]
[-help [cmd ...]]
[-ls [-d] [-h] [-R] [<path> ...]]
[-mkdir [-p] <path> ...]
[-moveFromLocal <localsrc> ... <dst>]
[-moveToLocal <src> <localdst>]
[-mv <src> ... <dst>]
[-put [-f] [-p] [-l] <localsrc> ... <dst>]
[-renameSnapshot <snapshotDir> <oldName> <newName>]
[-rm [-f] [-r|-R] [-skipTrash] <src> ...]
[-rmdir [--ignore-fail-on-non-empty] <dir> ...]
[-setfacl [-R] [{-b|-k} {-m|-x <acl_spec>} <path>]|[--set <acl_spec> <path>]]
[-setfattr {-n name [-v value] | -x name} <path>]
[-setrep [-R] [-w] <rep> <path> ...]
[-stat [format] <path> ...]
[-tail [-f] <file>]
[-test -[defsz] <path>]
[-text [-ignoreCrc] <src> ...]
[-touchz <path> ...]
[-truncate [-w] <length> <path> ...]
[-usage [cmd ...]]
太多了。。。
列举
hdfs dfs -ls /
路径必须为/开头的绝对路径。
当然也有相对路径(不常用),以/user/root/
开头。
上传
hdfs dfs -put Linux文件地址 HDFS路径地址
hdfs dfs -put /export/data/wordcount.txt /wordcount/input/
这是之前上传文件到HDFS的命令。
下载
hdfs dfs -get HDFS路径地址 Linux文件地址
删除
hdfs dfs -rm [-r|-R] [-skipTrash]
其中-r或者-R是用于递归删除目录(也就是多层的文件夹),-skipTrash用于跳过回收站直接删除,不然还需要手动进入/user/root/.Trash/Current/
目录删除回收站。HDFS还是比较吃硬盘空间的(∵默认要保存3份)。
创建目录
hdfs dfs -mkdir [-p] 目录路径
其中-p是用来创建层级目录的。
查看
hdfs dfs -cat /wordcount/input/wordcount.txt
其它
-cp
-mv
大多数命令和Linux的命令行差不多。
集群管理命令
Client
bin/hadoop command
命令也很多:
Usage: hdfs dfsadmin
Note: Administrative commands can only be run as the HDFS superuser.
[-report [-live] [-dead] [-decommissioning]]
[-safemode <enter | leave | get | wait>]
[-saveNamespace]
[-rollEdits]
[-restoreFailedStorage true|false|check]
[-refreshNodes]
[-setQuota <quota> <dirname>...<dirname>]
[-clrQuota <dirname>...<dirname>]
[-setSpaceQuota <quota> [-storageType <storagetype>] <dirname>...<dirname>]
[-clrSpaceQuota [-storageType <storagetype>] <dirname>...<dirname>]
[-finalizeUpgrade]
[-rollingUpgrade [<query|prepare|finalize>]]
[-refreshServiceAcl]
[-refreshUserToGroupsMappings]
[-refreshSuperUserGroupsConfiguration]
[-refreshCallQueue]
[-refresh <host:ipc_port> <key> [arg1..argn]
[-reconfig <datanode|...> <host:ipc_port> <start|status>]
[-printTopology]
[-refreshNamenodes datanode_host:ipc_port]
[-deleteBlockPool datanode_host:ipc_port blockpoolId [force]]
[-setBalancerBandwidth <bandwidth in bytes per second>]
[-fetchImage <local directory>]
[-allowSnapshot <snapshotDir>]
[-disallowSnapshot <snapshotDir>]
[-shutdownDatanode <datanode_host:ipc_port> [upgrade]]
[-getDatanodeInfo <datanode_host:ipc_port>]
[-metasave filename]
[-triggerBlockReport [-incremental] <datanode_host:ipc_port>]
[-help [cmd]]
Generic options supported are
-conf <configuration file> specify an application configuration file
-D <property=value> use value for given property
-fs <local|namenode:port> specify a namenode
-jt <local|resourcemanager:port> specify a ResourceManager
-files <comma separated list of files> specify comma separated files to be copied to the map reduce cluster
-libjars <comma separated list of jars> specify comma separated jar files to include in the classpath.
-archives <comma separated list of archives> specify comma separated archives to be unarchived on the compute machines.
The general command line syntax is
bin/hadoop command [genericOptions] [commandOptions]
集群状态
hdfs dfsadmin -report
安全模式
hdfs dfsadmin [-safemode <enter | leave | get | wait>]
当NameNode发现块的丢失比例超过0.01%,就会自动进入安全模式,用于恢复对应的数据。安全模式下,HDFS集群不对外提供读写。如果HDFS长久的停留在安全模式,将不能正常使用,虚拟机之间关电经常出现这种问题,可以手动强制退出安全模式:
hdfs dfsadmin -safemode leave