HDFS总结
HDFS是Hadoop的一个子系统,Hadoop非常适合存储大数据,使用hdfs作为存储系统,提供统一接口,使用户像访问一个普通文件一样使用分布式文件系统
HDFS的应用场景
适用的场景
- 存储非常大的文件
- 采用流式的数据访问方式,即一次写入,多次读取
- 节约成本和容错性较高,并提供拓展能力
不适合的场景
- 低时延的数据访问
- 大量小文件保存在nameNode的内存中
- 多方读写,支持使用追加的方式写入数据,但是不支持文件任意位置的修改,不支持多个写入器
HDFS的架构
HDFS由HDFS Client,Name Node,DataNode和SecondNod组成。
其架构如下:
- Client负责文件的切分,与NameNode交互获取位置信息,与DataNode交互读取和写入,并提供命令进行管理和访问HDFS。
- NameNode负责元数据的管理,块映射信息,副本策略和客户端读写请求。
- DATa Node实际存储了数据,并执行数据块的读写操作。
- Secondary NameNode并非是热备,当NN挂掉时,并不能马上提供服务 :分担NN的工作量,定期合并fsimage和fedits,辅助NN的恢复
NN和DN
上图是HDFS的工作流程,客户端向NodeNode请求,NameNode向Client返回读取的数据的DataNode位置,Client向相应DataNode进行读写数据。
hdfs的命令行使用
hdfs dfs +命令
ls | 显示文件列表 |
---|---|
lsr | 递归执行,返回文件列表 |
mkdir | 创建文件夹 |
put | 将本地文件拷贝到hdfs上 |
moveFromLocal | 与put相似,但是是移动而不是复制 |
get | 从hdfs文件拷贝到本地 |
cat chomd chown appendTofile(追加文件到hdfs中)
hdfs的高级使用命令
文件限额配置
空间限额
hdfs dfs -count -q -h /user/root/dir1 #查看配额信息
在设置空间配额时,设置的空间至少是block_size * 3大小,否则会报错
hdfs dfsadmin -setSpaceQuota 4k /user/root/dir # 限制空间大小4KB
hdfs dfs -put /root/a.txt /user/root/dir
dd if=/dev/zero of=1.txt bs=1M count=2 #生成2M的文件
清除空间配额限制
hdfs dfsadmin -clrSpaceQuota /user/root/dir
数量限额
hdfs dfs -mkdir -p /user/root/dir #创建hdfs文件夹
hdfs dfsadmin -setQuota 2 dir # 给该文件夹下面设置最多上传两个文件,发现只能
上传一个文件
hdfs dfsadmin -clrQuota /user/root/dir # 清除文件数量限制
HDFS基准测试
测试写入速度
向HDFS文件系统中写入数据,10个文件,每个文件10MB,文件存放到/benchmarks/TestDFSIO中
hadoop jar /export/servers/hadoop-2.7.5/share/hadoop/mapreduce/hadoopmapreduce-client-jobclient-2.7.5.jar TestDFSIO -write -nrFiles 10 -
fileSize 10MB
完成之后查看写入速度结果
hdfs dfs -text /benchmarks/TestDFSIO/io_write/part-00000
清除测试数据
hadoop jar /export/servers/hadoop-2.7.5/share/hadoop/mapreduce/hadoopmapreduce-client-jobclient-2.7.5.jar TestDFSIO -clean
测试读取速度
hdfs dfs -text /benchmarks/TestDFSIO/io_read/part-00000
HDFS写入和读取流程
这是HDFS的写入流程
这是HDFS的读取流程。
HDFS的元数据辅助管理
当 Hadoop 的集群当中, NameNode的所有元数据信息都保存在了 FsImage 与 Eidts 文件当中, 这两个文件就记录了所有的数据的元数据信息, 元数据信息的保存目录配置在了 hdfssite.xml 当中
<property>
<name>dfs.namenode.name.dir</name>
<value>
file:///export/servers/hadoop2.7.5/hadoopDatas/namenodeDatas,
file:///export/servers/hadoop2.7.5/hadoopDatas/namenodeDatas2
</value>
</property>
<property>
<name>dfs.namenode.edits.dir</name>
<value>file:///export/servers/hadoop2.7.5/hadoopDatas/nn/edits</value
</property>>
Fslage和Edits详解(均在NN上)
edits
edits存放了客户端最近的操作日志。
fsimage
fsimage存放了一份完整的元数据信息, 因为 fsimage 是 NameNode 的完整的镜像, 如果每次都加载到内存生成树状拓扑结 构,这是非常耗内存和CPU, 所以一般开始时对 NameNode 的操作都放在 edits 中 。 随着 edits 内容增大, 就需要在一定时间点和 fsimage 合并
- 如下是Fslage和Edits工作流程:
两个节点分别是 SecondaryNameNode 和Name Node
- SecondaryNameNode 定期合并 fsimage 和 edits, 把 edits 控制在一个范围内 ,其配置如下:
在core-site.xml中如下:
<!-- 多久记录一次 HDFS 镜像, 默认 1小时 -->
<property>
<name>fs.checkpoint.period</name>
<value>3600</value>
</property>
<!-- 一次记录多大, 默认 64M -->
<property>
<name>fs.checkpoint.size</name>
<value>67108864</value>
</property>
- fsimage 中的文件信息查看
cd /export/servers/hadoop2.7.5/hadoopDatas/namenodeDatas
hdfs oiv -i fsimage_0000000000000000864 -p XML -o hello.xml
- edits 中的文件信息查看
cd /export/servers/hadoop2.7.5/hadoopDatas/namenodeDatas
hdfs oev -i edits_0000000000000000865-0000000000000000866 -p XML -o
myedit.xml
hdfs的api操作
-
获取文件系统
两种方式:get和newInstance,其对configuration的操作分为两种:
Configuration configuration = new Configuration(); //指定我们使用的文件系统类型: configuration.set("fs.defaultFS", "hdfs://node01:8020/");
或:
FileSystem fileSystem = FileSystem.get(new URI("hdfs://node01:8020"), new Configuration());
-
遍历HDFS的所有文件
调用:fileSystem.listFiles(new Path("/"), true);
返回一个迭代器,使用迭代器的方式进行打印
-
HDFS 上创建文件夹
boolean mkdirs = fileSystem.mkdirs(new Path("/hello/mydir/test"));
- 下载文件 (增删改查均在IOUtils函数)
@Test
public void getFileToLocal()throws Exception{
FileSystem fileSystem = FileSystem.get(new URI("hdfs://node01:8020"),
new Configuration());
FSDataInputStream inputStream = fileSystem.open(new
Path("/timer.txt"));
FileOutputStream outputStream = new FileOutputStream(new
File("e:\\timer.txt"));
IOUtils.copy(inputStream,outputStream );
IOUtils.closeQuietly(inputStream);
IOUtils.closeQuietly(outputStream);
fileSystem.close();
}
-
上传文件
@Test public void putData() throws Exception{ FileSystem fileSystem = FileSystem.get(new URI("hdfs://node01:8020"), new Configuration()); fileSystem.copyFromLocalFile(new Path("file:///c:\\install.log"),new Path("/hello/mydir/test")); fileSystem.close(); }
HDFS的高可用机制
在Hadoop 中,NameNode 所处的位置是非常重要的,整个HDFS文件系统的元数据信息都由 NameNode 来管理,NameNode的可用性直接决定了Hadoop 的可用性,一旦NameNode进程 不能工作了,就会影响整个集群的正常使用。 在 典型的HA集群中,两台独立的机器被配置为NameNode。
在工作集群中,NameNode机器中 的一个处于Active状态,另一个处于Standby状态。Active NameNode负责群集中的所有客户端 操作,而Standby充当从服务器。Standby机器保持足够的状态以提供快速故障切换(如果需 要)。
-
ZKFailoverController
是基于Zookeeper的故障转移控制器,它负责控制NameNode的主备切换, ZKFailoverController会监测NameNode的健康状态,当发现Active NameNode出现异常时会通 过Zookeeper进行一次新的选举,完成Active和Standby状态的切换
-
HealthMonitor
周期性调用NameNode的HAServiceProtocol RPC接口(monitorHealth 和 getServiceStatus), 监控NameNode的健康状态并向ZKFailoverController反馈
-
ActiveStandbyElector
接收ZKFC的选举请求,通过Zookeeper自动完成主备选举,选举完成后回调 ZKFailoverController的主备切换方法对NameNode进行Active和Standby状态的切换
Hadoop的联邦机制(Federation)
Hadoop的联邦机制(Federation) 出现的缘由:
单NameNode的架构使得HDFS在集群扩展性和性能上都有潜在的问题,当集群大到一定程度 后,NameNode进程使用的内存可能会达到上百G,NameNode成为了性能的瓶颈。因而提出 了namenode水平扩展方案-- Federation。
Federation架构设计
Federation意味着在集群中将会有多个namenode/namespace。这些namenode之间是联合的, 也就是说,他们之间相互独立且不需要互相协调,各自分工,管理自己的区域。分布式的 datanode被用作通用的数据块存储存储设备。每个datanode要向集群中所有的namenode注 册,且周期性地向所有namenode发送心跳和块报告(剩余空间),并执行来自所有namenode的命令。
概括:
多个NN共用一个集群里的存储资源,每个NN都可以单独对外提供服务。
每个NN都会定义一个存储池,有单独的id,每个DN都为所有存储池提供存储。
amenode之间是联合的, 也就是说,他们之间相互独立且不需要互相协调,各自分工,管理自己的区域**。分布式的 datanode被用作通用的数据块存储存储设备。每个datanode要向集群中所有的namenode注 册,且周期性地向所有namenode发送心跳和块报告(剩余空间),并执行来自所有namenode的命令。
概括:
多个NN共用一个集群里的存储资源,每个NN都可以单独对外提供服务。
每个NN都会定义一个存储池,有单独的id,每个DN都为所有存储池提供存储。
DN会按照存储池id向其对应的NN汇报块信息,同时,DN会向所有NN汇报本地存储可用资源 情况。