1 分布式文件系统(Distributed File System)
- 数据量越来越多,在一个操作系统管辖的范围存不下了,那么就分配到更多的操作系统管理的磁盘中,但是不方便管理和维护,因此迫切需要一种系统来管理多台机器上的文件,这就是分布式文件管理系统
- 是一种允许文件通过网络在多台主机上分享的文件系统,可让多机器上的多用户分享文件和存储空间
- 通透性。让实际上是通过网络来访问文件的动作,由程序与用户看来,就像是访问本地的磁盘一般
- 容错。即使系统中有某些节点脱机,整体来说系统仍然可以持续运作而不会有数据损失
- 分布式文件管理系统很多,hdfs只是其中一种。适用于一次写入多次查询的情况,不支持并发写情况,小文件不合适
2 HDFS 结构
HDFS:Hadoop Distributed File System(Hadoop 分布式文件系统) - 主从结构
- 主节点:只有一个(namenode)
- 从节点:有很多个(datanodes)
注意:主节点和从节点都是不同的物理机器
namenode 负责:
- 接收用户操作请求
- 维护文件系统的目录结构
- 管理文件与 block 之间关系,block 与 datanode 之间关系
datanode 负责:
- 存储文件
- 文件被分成 block 存储在磁盘上
- 为保证数据安全,文件会有多个副本
3 Namenode 结构
- Namenode:是整个文件系统的管理节点。它维护着整个文件系统的文件目录树,文件/目录的元信息和每个文件对应的数据块列表。接收用户的操作请求
- 文件包括:
- fsimage:元数据镜像文件。存储某一时段NameNode内存元数据信息
- edits:操作日志文件
- fstime:保存最近一次checkpoint的时间
在 eclipse 中打开 Project 下**src/hdfs/hdfs-default.xml
**
首先发现注释:
1 | <!-- Do not modify this file directly. Instead, copy entries that you --> |
大概是说,不要在这个文件中修改代码,要先将想修改的代码 copy 到 hdfs-site.xml
这个文件中,然后在那里面修改。如果没有hdfs-site.xml
这个文件,就创建一个。
3.1 fsimage
在hdfs-default.xml
文件中查找“dfs.name.dir”,发现一段代码如下(大概在第 148 行):
1 | <property> |
由 description 可以得知,这段代码是决定 name node 的 name table(fsimage) 也就是文件系统的镜像,在本地文件系统的存储位置
然后发现 value 中有个变量是${hadoop.tmp.dir}
,在文件hdfs-default.xml
中查找,发现没有,然后到文件core-default.xml
中查找,发现如下代码(大概在第 13 行):
1 | <property> |
由 description 可以得知,这是临时目录的基本位置,所以这个值应该会替换上一段代码中的${hadoop.tmp.dir}
的值,然而并不是。。。因为我们已经在core-site.xml
中修改了hadoop.tmp.dir
的值 =_=:
1 | <configuration> |
所以其实文件hdfs-default.xml
中dfs.name.dir
中的${hadoop.tmp.dir}
实际上是/usr/local/hadoop/tmp
于是我们去命令行打开/usr/local/hadoop/tmp/dfs/name
(也就是dfs.name.dir
的位置)去看一下:
1 | [root@hadoop ~]# cd /usr/local/hadoop/tmp/ |
然后本着好奇心,去看一下in_use.lock
这个文件:
1 | [root@hadoop name]# more in_use.lock |
然后发现里面啥也没有。。。
不过虽然啥也没有,也是很重要的,这个文件的存在就表明这个目录已经被某个进程(Namenode 进程)使用了,所以其实如果直接再启动 Namenode 进程会报错,因为这个目录已经进不来了
那么为什么 Namenode 一定要占用这个目录呢?因为目录下的/current
文件夹下存放着 Namenode 存储数据的文件,也就是 Namenode 会编辑这些数据,所以显然不能有多个进程同时编辑这些数据
1 | [root@hadoop name]# cd current/ |
看到了刚刚说的fsimage
,Namenode 的核心数据都存放在这个文件里,所以这个文件比较重要,如果这个文件丢了,这个 Namenode 就不能用了(Datanode 中存放的都是块数据,没有 Namenode 无法读取)
所以会将fsimage
备份 :)
再看文件hdfs-default.xml
中dfs.name.dir
的 description(大概在第 148 行):
1 | <property> |
刚刚只看了 description 的前一句,现在看后一句,大概说的是:如果 value 是一个逗号分隔的目录列表,那么复制进所有的目录中,为了冗余。冗余就是备份,备份为了安全,nice~
注意:如果要改的话,记得复制到hdfs-site.xml
中去改,不要用中文逗号,不要随便加空格
3.2 edits
然后我们刚刚在/current
目录下还看到了edits
文件,所以我们继续本着好奇心,去文件hdfs-default.xml
中查找一下,发现如下一段代码(大概在第 157 行):
1 | <property> |
description 中大概说的是:这决定了 Namenode 的事务文件(edits)的存放位置(参见本文第 4 节)
4 SecondaryNameNode
执行过程:从 NameNode 上下载元数据信息(fsimage, edits),然后把二者合并,生成新的 fsimage,在本地保存,并将其推送到 NameNode,同时重置 NameNode 的 edits
注意:SecondaryNameNode 和 Namenode 是两个独立的 Java 进程,它们之间的数据交换是通过网络 HTTP 完成的
所以其实 Namenode 的 fsimage 在 SecondaryNameNode 中也有备份,所以可以从 SecondaryNameNode 中恢复数据,但是有可能会丢失一部分(没来得及从 edits 合并的)(类似于 Windows 下的“还原点”)
5 Datanode
- 提供真实文件数据的存储服务
- 文件块(block):最基本的存储单位。对于文件内容而言,一个文件的长度大小是size,那么从文件的0偏移开始,按照固定的大小,顺序对文件进行划分并编号,划分好的每一个块称一个Block。HDFS默认Block大小是64MB,以一个256MB文件,共有256/64=4个Block(一个文件的不同 block 不一定存放在一个 Datanode 上)
- 不同于普通文件系统的是,HDFS中,如果一个文件小于一个数据块的大小,并不占用整个数据块存储空间,而是占用源文件实际大小的空间
- Replication:多副本,默认是三个
5.1 block
在文件hdfs-default.xml
中查找“size”,发现如下一段代码(大概在第 157 行):
1 | <property> |
67108864 的单位是 byte(字节)
67108864/1024/1024 = 64
所以,67108864 byte = 64 M
在文件hdfs-default.xml
中查找“data.dir”,发现如下一段代码(大概在第 157 行):
1 | <property> |
description 中大概说的是:这是 Datanode 存放 block 的位置
在命令行中看一下:
1 | [root@hadoop dfs]# ls |
这就是存储的 block,查看一下:
1 | [root@hadoop current]# ll |
现在有一个 block,.meta
表示校验数据
现在上传个文件看看:
再打开一个 PieTTY 终端(为了叙述方便,原来的终端叫做“终端 1”,刚刚打开的叫做“终端 2”),上传文件hadoop-1.1.2.tar.gz
到根目录:
终端 2:
1 | [root@hadoop ~]# cd /usr/local/ |
再次在终端 1 中查看:
1 | [root@hadoop current]# ll |
再将它删了,将文件jdk-6u24-linux-i586.bin
上传到根目录:
终端 2:
1 | [root@hadoop local]# hadoop fs -rmr /hadoop-* |
在终端 1 中查看:
1 | [root@hadoop current]# ll |
发现上传文件hadoop-1.1.2.tar.gz
所产生的数据块没有了,上传文件jdk-6u24-linux-i586.bin
产生了 2 个数据块(因为文件jdk-6u24-linux-i586.bin
大于 64 M)
5.2 replication
Hadoop 默认副本为 3 个,但是用hadoop fs -ls
命令查看的时候,发现副本数为 1。这是因为我们已经在文件hdfs-site.xml
中修改配置:
1 | <property> |
那么为什么要改成 1 呢?因为我配置的是伪分布式环境,只有一个 Datanode。。。
6 使用浏览器查看 HDFS 目录结构
可以在浏览器中访问主机名:50070
来查看 HDFS 的目录结构