HDFS

提供分布式存储机制, 提供可线性增长的海量存储能力

自动数据冗余, 无须使用Raid, 无须另行备份

为进一步分析计算提供数据基础

 

HDFS设计基础与目标

硬件错误是常态, 因此需要冗余

流式数据访问. 即数据批量读取而非随机读写, hadoop擅长做的是数据分析而不是事务处理

大规模数据集

简单一致性模型. 为了降低系统复杂度, 对文件采用一次性写多次读的逻辑设计, 即是文件一写入, 关闭, 就再也不能修改.

程序采用 "数据就近" 原则分配节点执行

 

Namenode

管理文件系统的命名空间

记录每个文件数据块在各个Datanode上的位置和副本信息

协调客户端对文件的访问

记录命名空间内的改动和空间本身属性的改动

Namenode使用事务日记记录HDFS元数据的变化. 使用映像文件存储文件系统的命名空间,包括文件映射, 文件属性等.

[hadoop@hadoop1 name]$ cat /home/hadoop/hadoop-1.2.1/tmp/dfs/name/current/VERSION   
#Sat Aug 30 19:07:22 CST 2014
namespaceID=335444029                               #记录整个集群的标识号
cTime=0                                             #current time 新创建的系统,hdfs升级后会发生改变,升级的时间
storageType=NAME_NODE                               #标识存储结构, 主要用于存放NAME_NODE
layoutVersion=-41                                   #hdfs的构造版本, 和hadoop版本不一样

[hadoop@hadoop1 name]$ ll /home/hadoop/hadoop-1.2.1/tmp/dfs/name/current
total 16
-rw-rw-r--. 1 hadoop hadoop    4 Aug 30 19:07 edits                #编辑日志
-rw-rw-r--. 1 hadoop hadoop 2356 Aug 30 19:07 fsp_w_picpath              #内存文件系统的映像
-rw-rw-r--. 1 hadoop hadoop    8 Aug 30 19:07 fstime               #
-rw-rw-r--. 1 hadoop hadoop  100 Aug 30 19:07 VERSION

每隔一段时间系统会触发一个检查点,将内存中的数据写入到fsp_w_picpath中

用户的每一个操作都会记录在edits中,  每个一段时间数据写回到fsp_w_picpath中,这个文件就会被重写

当发生停电时,系统先恢复fsp_w_picpath中的内容,在从edits中进行恢复


Datanode

负责所在物理节点的存储管理

一次写入,多次读取(不修改)

文件由数据块组成, 典型的块大小是64MB

数据块尽量散布到各个节点

[hadoop@hadoop2 hadoop-1.2.1]$ ll /home/hadoop/hadoop-1.2.1/tmp/dfs/data/current/
total 116
-rw-rw-r-- 1 hadoop hadoop 51123 Aug 31 06:48 blk_276792134037850529
-rw-rw-r-- 1 hadoop hadoop   407 Aug 31 06:48 blk_276792134037850529_1025.meta
-rw-rw-r-- 1 hadoop hadoop     4 Aug 31 06:33 blk_-3599005811278314526
-rw-rw-r-- 1 hadoop hadoop    11 Aug 31 06:33 blk_-3599005811278314526_1003.meta
-rw-rw-r-- 1 hadoop hadoop    12 Aug 31 06:43 blk_-3834237939477806474
-rw-rw-r-- 1 hadoop hadoop    11 Aug 31 06:43 blk_-3834237939477806474_1007.meta
-rw-rw-r-- 1 hadoop hadoop    12 Aug 31 06:43 blk_-5998706687984379827
-rw-rw-r-- 1 hadoop hadoop    11 Aug 31 06:43 blk_-5998706687984379827_1006.meta
-rw-rw-r-- 1 hadoop hadoop    16 Aug 31 06:48 blk_-7414615467806892780
-rw-rw-r-- 1 hadoop hadoop    11 Aug 31 06:48 blk_-7414615467806892780_1026.meta
-rw-rw-r-- 1 hadoop hadoop 16375 Aug 31 06:48 blk_-8851236697157798264
-rw-rw-r-- 1 hadoop hadoop   135 Aug 31 06:48 blk_-8851236697157798264_1027.meta
-rw-rw-r-- 1 hadoop hadoop  1446 Aug 31 07:42 dncp_block_verification.log.curr
-rw-rw-r-- 1 hadoop hadoop   160 Aug 31 06:32 VERSION

每一个blk的文件,就是一个数据块(block)

 

读取数据流程

客户端要访问HDFS中的一个文件

首先从namenode获得组成这个文件的数据块位置列表

根据列表知道存储数据块的datanode

访问datanode获取数据

Namenode并不参与数据实际传输

 

写入数据流程

客户端请求namenode创建新文件

客户端将数据写入DFSOutputStream

建立pipeline依次将目标数据块写入各个datanode, 建立多个副本

 

HDFS的可靠性

冗余副本策略

机架策略

心跳机制

安全模式

效验和

回收站

元数据包含

快照机制

 

冗余副本策略

可以在hdfs-site.xml中设置复制因子指定副本数量

所有数据块都有副本

Datanode启动时, 遍历本地文件系统, 产生一份hdfs数据块和本地文件的对应关系列表(blockreport)汇报给namenode

 

 机架策略

集群一般放在不同机架上, 机架间带宽要比机架内带宽要小

HDFS的 "机架感知"

一般在本机架存放一个副本, 在其他机架在存放别的副本, 这样可以防止机架失效时丢失数据, 也可以提高带宽利用率

机架感知,在core-site.xml配置中定义

topology.script.file.name
/opt/modules/hadoop/hadoop-1.0.3/bin/RackAware.py



topology.script.number.args
20


然后重启hadoop的namenode和jobtracker,可以在logs里看下namenode和jobtracker的日志,看
到机架感知功能已经启用了
RackAware.py
#!/usr/bin/python
#-*-coding:UTF-8 -*-
import sys
rack = {"hadoop-node-31":"rack1",
  "hadoop-node-32":"rack1",
  "hadoop-node-49":"rack2",
  "hadoop-node-50":"rack2",
  "hadoop-node-51":"rack2",
  "192.168.1.31":"rack1",
  "192.168.1.32":"rack1",
  "192.168.1.49":"rack2",
  "192.168.1.50":"rack2",
  "192.168.1.51":"rack2",
}
if __name__=="__main__":
  print "/" +rack.get(sys.argv[1],"rack0")

 

心跳机制

Namenode周期性从datanode接收心跳信号和块报告

Namenode根据块报告验证元数据

没有按时发送心跳的datanode会被标记为宕机, 不会在给它任何I/O请求

如果datanode失效造成副本数量下降, 并且低于预先设置的阈值, namenode会检测出这些数据块, 并在合适的时机进行重新复制.

引发重新复制的原因还包括数据副本本身损坏, 磁盘错误, 复制因子被增大等

 

 安全模式

Namenode启动时会先经过一个 "安全模式" 阶段

安全模式阶段不会产生数据写

在此阶段Namenode收集各个datanode报告, 当数据块达到最小副本数以上时, 会被认为是 "安全" 的

在一定比例(可设置) 的数据块被确定为 "安全" 后, 再过若干时间, 安全模式结束

当检测到副本数不足的数据块时, 该块会被复制直到达到最小副本数

[hadoop@hadoop1 ~]$ hadoop dfsadmin -safemode enter 
Safe mode is ON
[hadoop@hadoop1 ~]$ hadoop fs -put inp/test2.txt .
put: org.apache.hadoop.hdfs.server.namenode.SafeModeException: Cannot create /user/hadoop/test2.txt. Name node is in safe mode.
[hadoop@hadoop1 ~]$ hadoop dfsadmin -safemode leave 
Safe mode is OFF

 

效验和

在文件创立时, 每个数据块都产生效验和

效验和保存在.meta文件内(CRC效验)

客户端获取数据时可以检查效验和是否相同, 从而发现数据块是否损坏

如果正在读取的数据块损坏, 则可以继续读取其他副本

[hadoop@hadoop3 current]$ pwd
/home/hadoop/hadoop-1.2.1/tmp/dfs/data/current
[hadoop@hadoop3 current]$ ll
total 116
-rw-rw-r--. 1 hadoop hadoop 51123 Aug 30 18:17 blk_276792134037850529
-rw-rw-r--. 1 hadoop hadoop   407 Aug 30 18:17 blk_276792134037850529_1025.meta
-rw-rw-r--. 1 hadoop hadoop    12 Aug 30 18:12 blk_-3834237939477806474
-rw-rw-r--. 1 hadoop hadoop    11 Aug 30 18:12 blk_-3834237939477806474_1007.meta
-rw-rw-r--. 1 hadoop hadoop    12 Aug 30 18:12 blk_-5998706687984379827
-rw-rw-r--. 1 hadoop hadoop    11 Aug 30 18:12 blk_-5998706687984379827_1006.meta
-rw-rw-r--. 1 hadoop hadoop     4 Aug 30 20:25 blk_7056849419228654158
-rw-rw-r--. 1 hadoop hadoop    11 Aug 30 20:25 blk_7056849419228654158_1028.meta
-rw-rw-r--. 1 hadoop hadoop    16 Aug 30 18:17 blk_-7414615467806892780
-rw-rw-r--. 1 hadoop hadoop    11 Aug 30 18:17 blk_-7414615467806892780_1026.meta
-rw-rw-r--. 1 hadoop hadoop 16375 Aug 30 18:17 blk_-8851236697157798264
-rw-rw-r--. 1 hadoop hadoop   135 Aug 30 18:17 blk_-8851236697157798264_1027.meta
-rw-rw-r--. 1 hadoop hadoop  1639 Aug 30 20:28 dncp_block_verification.log.curr
-rw-rw-r--. 1 hadoop hadoop   160 Aug 30 18:01 VERSION

 

回收站

删除文件时,  其实是放入回收站/trash

回收站里的文件可以快速恢复

可以设置一个时间阈值, 当回收站里的文件的存放时间超过这个阈值, 就被彻底删除, 并且施放占用的数据块

vi conf/core-site.xml

  fs.trash.interval
  21600
  
    Number of minutes between trashcheckpoints. If zero, the trash feature is disabled
  

 回收站功能测试...

[hadoop@hadoop1 hadoop-1.2.1]$ hadoop fs -ls ./inp                                                      #查看inp目录下的文件
Found 2 items
-rw-r--r--   2 hadoop supergroup         12 2014-08-30 18:12 /user/hadoop/inp/test1.txt
-rw-r--r--   2 hadoop supergroup         12 2014-08-30 18:12 /user/hadoop/inp/test2.txt
[hadoop@hadoop1 hadoop-1.2.1]$ hadoop fs -rmr ./inp/test1.txt                                           #删除一个文件
Moved to trash: hdfs://hadoop1:9000/user/hadoop/inp/test1.txt                                           #提示放到了回收站
[hadoop@hadoop1 hadoop-1.2.1]$ hadoop fs -ls .                                                          
Found 3 items
drwxr-xr-x   - hadoop supergroup          0 2014-08-31 18:37 /user/hadoop/.Trash                        #发现多了一个.Trash的目录
drwxr-xr-x   - hadoop supergroup          0 2014-08-31 18:37 /user/hadoop/inp
drwxr-xr-x   - hadoop supergroup          0 2014-08-30 18:18 /user/hadoop/out
[hadoop@hadoop1 hadoop-1.2.1]$ hadoop fs -ls ./.Trash/Current/user/hadoop/inp                           #了解.Trash的目录结构
Found 1 items 
-rw-r--r--   2 hadoop supergroup         12 2014-08-30 18:12 /user/hadoop/.Trash/Current/user/hadoop/inp/test1.txt

回收站的恢复和清空

 

[hadoop@hadoop1 hadoop-1.2.1]$ hadoop fs -mv ./.Trash/Current/user/hadoop/inp/test1.txt ./              #直接mv移出来就可以了.
[hadoop@hadoop1 hadoop-1.2.1]$ hadoop fs -ls
Found 4 items
drwxr-xr-x   - hadoop supergroup          0 2014-08-31 18:37 /user/hadoop/.Trash
drwxr-xr-x   - hadoop supergroup          0 2014-08-31 18:37 /user/hadoop/inp
drwxr-xr-x   - hadoop supergroup          0 2014-08-30 18:18 /user/hadoop/out
-rw-r--r--   2 hadoop supergroup         12 2014-08-30 18:12 /user/hadoop/test1.txt                     #刚移出来的文件
[hadoop@hadoop1 hadoop-1.2.1]$ hadoop fs -expunge                                                       #清空回收站
14/08/31 18:41:52 INFO fs.Trash: Created trash checkpoint: /user/hadoop/.Trash/1408311841

 

 元数据保护

 映像文件刚和事务日志是Namenode的核心数据, 可以配置为拥有多个副本

副本会降低Namenode的处理速度, 但增加安全性

Namenode依然是单点, 如果发生故障要手工切换

 

快照

支持存储某个时间点的映像, 需要时可以使数据重返这个时间点的状态

Hadoop目前还不支持快照, 已经列入开发计划, 传说在Hadoop 2.x 某版本里将获得此功能

 

 

HDFS文件操作

 命令行方式

列出hdfs下的文件,  hadoop没有当前目录的概念, 也没有cd命令切换目录..(需要全路径)

hadoop fs -ls

上传文件到hdfs

hadoop fs -put filename ./dest

数据写在哪儿?(从OS层面看)

/home/hadoop/hadoop-1.2.0/tmp/dfs/data/current

将hdfs的文件复制到本地

hadoop fs -get ./filename /dest

删除hdfs下的文档

hadoop fs -rmr ./filename

查看某个文件的内容

hadoop fs -cat ./filename

查看hdfs基本统计信息

hadoop dfsadmin -report

查看当前块大小

hadoop fs -stat "%o" ./filename


API方式

参看另一篇HDFS的api.

 

 

怎样添加节点?

在新节点安装好hadoop

把namenode的有关配置文件复制到该节点

修改masters和slaves文件, 增加该节点

设置ssh免密码登录该节点

单独启动该节点上的datanode和tasktracker( hadoop-daemon.sh start  datanode/tasktracker )

运行start-balancer.sh进行数据负载均衡

是否要重启集群?