一.HDFS概述
` Hadoop Distributed File System----- Hadoop分布式文件存储系统,是hadoop的一个组件,用于数据的存储。
HDFS的总体布局:
HDFS中存在一个名字节点NameNode和多个数据节点DataNode。当用户发送请求后,HDFS会对数据进行切块,然后备份(称为复本replication)并存储到某一个DataNode上,从而保证数据存储的可靠性(复本)和读取速度(切块)。
其中,
NameNode: 是用于管理的节点,存储元数据(MetaData)信息。
元数据信息包括:
a.记录文件所对应的文件块
b.记录每一个文件块存储的节点位置
c.记录每个文件块的复本的存储位置
元数据保存一份在内存中保证读写效率,以及磁盘中为了崩溃恢复,每一个元数据在150个字节左右。
DataNode: 是用于存储数据的节点,存储的文件块(block)内容。
Block信息存储在磁盘中。如果某一个datanode宕机,namenode会将这个datanode中存储的复本自动复制一份放到其他的节点上,保证副本数量。完全分布式中,副本数量默认是3个。3个复本也就意味着,上传一个文件后,HDFS会自动将文件备份2份。
举例:
` 存储10000个10kb的文件,和存储一个1G的文件,虽然前者的内容少,但是存储所需的元数据会有10000条记录,也会占用很多资源。因此,在HDFS中不适合存储大量的小文件,因为大量的小文件会产生大量的元数据,导致namenode的内存被大量占用,会降低namenode的读写速率。
二、HDFS主要技术
1、Block
数据块(Block)是HDFS中存储数据的基本单位。在HDFS中存储的文件都是超大数据的文件,需要把这个超大规模的文件切分成几块,存储到不同的磁盘上,这个块就称为Block。2.0版本中,Block 默认的大小为128M。
分块的好处:
a.可以存储大文件
b.为了能够快速备份
不同于普通文件系统,HDFS中,如果一个文件小于一个数据块的大小,并不占用整个数据块存储空间。
2、Block多复本放置策略
(1)第一个复本:
a.如果是某一个datanode内部上传,将复本放置在这个上传文件的Datanode上
b.如果是集群之外的客户端上传的复本,namenode就随机选择一台磁盘不太满,cpu不太忙的节点来存储复本。
(2)第二个复本:放置在和第一个复本所在机架不同机架的节点上。
(3)第三个复本:放置在与第二个副本所在机架相同机架的节点上。
(4)更多复本:随机节点,哪个空闲放到哪。
补充:
机架感知策略:
通过映射关系建立逻辑机架。习惯上会将同一个物理机架上的节点也设置为同一个逻辑机架。
3、NameNode
NameNode维护着HDFS中的元数据信息。在Hadoop1.0中,namenode只有一个,存在单节点问题,在Hadoop2.0中,完全分布式中,namenode最多可以设置2个。
元数据:
元数据格式如下:
FileName replicas block-Ids id2host
例如: /test/a.log,3,{b1,b2},[{b1:[h0,h1,h3]},{b2:[h0,h2,h4]}]
解释: 文件a.log存储在test目录下,默认复本数量是3 ,切了2块b1,b2,然后将b1的三个复本分别存储到了h0,h1,h3这3个datanode中。
元数据的存储位置由hadoop.tmp.dir属性来决定,所以必须配置这个属性,因为默认的是在/tmp中。
记录元数据的文件:
存储在dfs/name/current/name目录下。
edits文件:记录操作
fsimage文件:记录元数据,这个文件中的元数据并不是实时的。
每一个写操作访问namenode时,先将这个操作记录到edits文件中,如果写成功,再将这个操作更新到内存中,更新成功后,向客户端返回成功消息。这个过程中fsimage中的数据没有变化,所以不是实时的。
NameNode的metadata信息会在启动后加载到内存中。
将edits中的操作更新到fsimage中,这时,fsimage中的数据才能和内存中的数据一致。所以,内存中的元数据是实时的元数据。
如果namenode重启,从磁盘中恢复元数据。在HDFS重启时,HDFS会自动将edits中的操作更新到fsimage文件中,保证内存中的元数据是最新的元数据。
安全模式:
HDFS重启的时候进行数据恢复的过程称为安全模式。在安全模式下,会进行元数据恢复、等待datanode的应答、检查复本数量保证最小复本量等操作。而且安全模式下,只提供读服务,不提供写服务。另外,在伪分布式下,副本数量一定是1;如果伪分布式下复本数量是3,则HDFS将无法离开安全模式。
安全模式中,检查完毕会自动退出安全模式,如果退不出去,就强制退出
hadoop dfsadmin -safemode leave
,但是这样可能造成数据丢失,所以不建议。
为了防止在同一台服务器上启动多个namenode,会在namenode节点上多出一个dfs/name/in_use.lock文件。
将edits文件转化为xml文件进行查看:
hdfs oev -i edits_inprogress_0000000000000000003 -o a.xml
将fsimage文件转化为xml文件进行查看
hdfs oiv -i fsimage_0000000000000000002 -o b.xml
4、DataNode
DataNode存储的数据,是以Block的形式存储的。数据存储在datanode的磁盘上。我自己是存储在:/root/hadoop-2.7.1/tmp/dfs/data/current/BP-1020122231-127.0.0.1-1546505532464/current/finalized/subdir0/subdir0
。
DataNode存储的时候会给文件块编号block ID。
datanode重新启动时,会主动向namenode发送信息,信息包含当前datanode存储的数据信息。
在HDFS启动后,datanode会定时向namenode发送心跳信息。namenode每3秒会收到某个datanode的心跳信息,如果超过十分钟没有收到某个datanode的心跳信息,这时就认为这个datanode已经丢失lost,namenode会将这个节点中存储的block复制到到其他DataNode上。
补充:
心跳机制: 两个节点之间会定时的进行通信。
datanode会每隔3秒向namenode发送一次心跳信息,心跳信息包括:
a.当前节点的信息
b.当前结点存储的数据块的信息
5、SecondaryNameNode
SecondaryNameNode不是NameNode的热备份,而是辅助NameNode进行元数据的合并。SecondaryNameNode也可以提供一定的备份功能(只有在数据产生合并的时候才有这种性能),可以从SecondaryNameNode中恢复部分数据,但是无法恢复全部,因为edits.new中的数据丢失了就找不回了。这意味着在极端情况下,可能会造成数据丢失!
所以,2.0中,抛弃了SecondaryNameNode,而是采用了双namenode机制进行热备份。
何时触发edits和fsimage数据合并?
a.当HDFS重新启动会触发合并
b.空间:在core-site.xml中配置 fs.checkpoint.size设置edits文件的 大小,当edits文件达到指定的大小时就会进行合并, 默认64MB。
c.时间:在core-site.xml中配置fs.checkpoint.period 设置edits操作 时间,每隔指定的时间对edits文件和fsimage文件进行一次合并,默认3600秒。
合并过程发生在SecondaryNameNode。
合并过程:
a.SecondaryNameNode通过网络将edits文件和fsimage文件拷贝到SecondaryNameNode上
b.NameNode中产生一个新文件eidts.new,后续操作写到eidts.new
c.在SecondaryNameNode中,将fsimage文件加载到内存中,然后将edits文件中的操作更新到内存中,然后将内存中的数据写到fsimage.acpk新文件中。
d.SecondaryNameNode通过网络将fsimage.acpk拷贝到NameNode上
e.NameNode将fsimage.acpk重命名为fsimage,将edits.new重命名为edits。
三、HDFS的指令
命令 | 说明 |
---|---|
hadoop fs -mkdir 节点名 | 创建一个节点路径(以目录的形式表示路径) |
hadoop fs - ls 路径 | 查看指定路径下的子文件和子路径 |
hadoop fs -lsr 路径 | 递归查看指定路径下的子文件和子路径的子文件和子路径 |
hadoop fs -put 文件名 路径 | 将文件上传到指定路径下 |
hadoop fs -get 文件名 | 下载指定的文件 |
hadoop fs -cat 文件名 | 查看文件中的数据 |
hadoop fs -tail 文件名 | 文件较大时,查看文件最后1000个字节的数据 |
hadoop fs -rm 路径 | 删除指定的文件或者子路径 |
hadoop fs -rmdir | 删除目录 |
hadoop fs -mv 节点1 节点2 | 移动文件或者目录,也就是剪切1到2 下;还可用于重命名:1重命名为2。 |
hadoop fs -touchz | 创建空文件 |
hadoop fs -getmerge 文件1 文件2 新文件名 | 将文件1和2内容合并到新文件中 |
hadoop fs -cp 节点1 节点2 | 复制文件1到文件2 下 |
hadoop fs -du | 查看文件大小,如果是目录,则列出当前目录下的所有的文件大小 |
hadoop fsck 文件名 -files -blocks -locations -racks | 查看指定文件的存储信息 |
hadoop dfsadmin -rollEdits | 手动合并edits文件和fsimage文件 |
四、HDFS回收站机制
HDFS中回收站默认不开启。
Deletion interval=0 minutes
表示清空周期为0,说明如果数据放入回收站,就会被立即删除。
1、配置回收站:
进入Hadoop安装目录下的etc目录下的子目录hadoop
cd hadoop-2.7.1/etc/hadoop
编辑core-site.xml
添加配置
<!--配置回收站-->
<property>
<name>fs.trash.interval</name>
<value>1440</value>
</property>
保存退出。
2、还原回收站中的文件:
a.配置好回收站之后,再删除文件是将文件挪动到回收站中
b.如果还原文件,可以通过hadoop fs -mv来进行还原
hadoop fs -mv /root/.Trash/current/node01 /a.txt /a.txt
五、dfs路径
命令 | 说明 |
---|---|
dfs目录 | 一般表示HDFS的存储目录 |
dfs/name | 表示NameNode的持久化目录(当执行格式化指令时,会在指定的数据目录下,生成dfs/name目录) |
dfs/data | 表示DataNode的存储目录 |
dfs/namesecondary | 表示SecondaryNameNode的存储目录(name目录和data目录可以分开指定,实际开发中一个节点只有两者中的一个) |
fsimage_0000000000000000000 文件 | 当格式化后,启动HDFS前,会生成一个最初的fsimage_0000000000000000000 文件,该文件中存储的根节点的信息。 |
dfs/name/in_use.lock文件 | 防止在同一台服务器上启动多个NameNode,避免管理紊乱 |
edits文件 | 当启动HDFS时,会生成edits文件 |
edits文件:
` HDFS中有事务id的概念,当HDFS每接收一个事务操作(比如:mkdir put mv),都会分配相应的事务id,然后写到edits文件中。每生成一个新的edits文件,edits文件中都会以OP_START_LOG_SEGMENT开头,当一个edits文件写完后,会以OP_END_LOG_SEGMENT结尾。即在 OP_START_LOG_SEGMENT- OP_END_LOG_SEGMENT存储的是这个edits文件所有的事务记录。
命令 | 说明 |
---|---|
edits_inprogress文件 | 记录当前正在执行的事务文件。后面的编号是以上一次Txid+1来命名的 |
初次使用HDFS时,有一个默认的edits和fsimage的合并周期(1分钟),以后在使用HDFS的过程中,达到条件edits_inprogress会和fsimage进行合并。
上传文件底层的事务过程:
命令 | 说明 |
---|---|
OP_ADD | 将文件加入到指定的HDFS目录下,并以._Copyging_结尾,表示此文件还未写完 |
ALLOCATE_BLOCK_ID | 为文件分配块ID |
SET_GENSTAMP_V2 | 为块生成时间戳版本号,是全局唯一的 |
ADD_BLOCK | 写块数据 |
OP_CLOSE | 表示块数据写完 |
OP_RENAME_OLD | 将文件重命名,表示写完。 |
seen_txid | 记录是的最新的edits_inprogress文件末尾的数字 |
fsimage_N | 文件存储的N号事务前的所有的元数据信息 |
fsimage_N.md5 | 存储的是fsimage文件的md5校验码, |
可以通过MD5的校验和来校验文件的完整性:md5sum fsimage_n