1.概念说明
HDFS是Hadoop分布式文件系统
2.特点特征
1.高容错性和高可用性,硬件错误是常态而不是异常
2.流式数据访问
3.弹性存储,支持大规模数据集
4.简单一致性原则
5.移动计算而非移动数据
6.协议和接口多样性
7.多样的数据管理功能
3.应用场景
- 各大电信运营商
- 中大型互联网公司,如BAT、京东、乐视、美团等
- 金融银行保险类公司
- 各大云平台底层存储平台
- 其他本地系统无法承载存储能力的应用
4.代码实现
public class ReadFromHdfs {
//创建静态变量 只加载一次
static Configuration conf = new Configuration();
/**
* 从hdfs中读取文件
* @param filePath 文件地质
* @return 文件byte数组
* @throws IOException
*/
public static byte[] readFileFromHdfs(String filePath) throws IOException {
// 1. 创建配置文件
// 2. 创建FileSystem
FileSystem fs = FileSystem.get(conf);
// 3. 创建Path(相当于JavaIO里的File)
Path path = new Path(filePath);
// 4. 打开一个输入流 通过FileSystem 和 Path 打开一个 FSDataInputStream
FSDataInputStream fsDataInputStream = fs.open(path);
// 5. 读取输入流的数据获取对应的byte数组
byte[] buffers = new byte[1024];
int len = 0;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
while ((len = fsDataInputStream.read(buffers)) > 0) {
byteArrayOutputStream.write(buffers,0,len);
}
byte[] result = byteArrayOutputStream.toByteArray();
// 6. 关闭输入流
byteArrayOutputStream.close();
fsDataInputStream.close();
return result;
}
private static String getStringByByte(byte[] bytes) {
return new String(bytes, StandardCharsets.UTF_8);
}
public static void main(String[] args) throws IOException {
String filePath = args[0];
byte[] result = readFileFromHdfs(filePath);
// 7. 获取了文件的内容
System.out.println(getStringByByte(result));
}
}
5.HDFS架构设计
HDFS是一个主从式(Master/Slave)的体系结构。HDFS集群中有一个NameNode和一些DataNodes,
NameNode管理文件的元数据,DataNode存储实际的数据。从用户的角度看,就像操作传统的文件系统一样,可以通过目录路径对文件执行创建、读取、删除操作。客户端联系NameNode来获取元数据信息,而真正的文件I/O是直接和DataNode进行交互的
组件角色:
1.Namenode:
HDFS元数据管理者,管理NameSpace(文件系统命名空间),记录文件是如何分割成数据块以及他们分别存储在集群中的哪些数据节点上。
NameSpace或其本身属性的任何更改都由NameNode记录,维护整个文件系统的文件和目录。
2.Datanode:
DataNode是文件系统的工作节点。根据客户端或者NameNode发送的管理指令,负责HDFS的数据块的读写和检索操作。
通过心跳机制定期向NameNode发送他们的存储块的列表。
3.Client:
客户端Client代表用户与NameNode或者DataNode交互来访问整个文件系统的对象。
开发人员面向Client API来编程实现,对NameNode、DataNode来说透明无感。
经典问题
- HDFS为何要将文件分成block块存储?
- 减少底层操作系统的IO读取时的寻址时间
- 方便更高效的流式读取,提高吞吐量
- HDFS block块的默认大小时多少?
- dfs.blocksize为Hadoop定义block块大小的设置参数,在hdfs-site.xml中
- 版本不一样,默认值不同。Hadoop2.2.x及以后版本均为128M
- HDFS block块的大小是否可以更改?
- 可以修改
- 参数修改对以前的文件不起作用,对以后的文件起作用
- 也可针对上传文件临时修改,指定-D dfs.blocksize即可
- 一个block块文件是否可以存储多个文件数据?
- 一个block块文件不会跨文件存储
- 一个block块文件最多只会存储一个文件对应的数据
- 如果一个文件的大小,小于一个blocksize,那么它实际占用多大空间?
- 实际文件多大则占多大空间,但是占了一个block块的元数据空间大小
- 小文件越多,Hadoop NameNode的压力越大。故Hadoop的优势在于处理大文件数据,GB、TB甚至PB等。
- HDFS block越大越好?还是越小越好?
- 越大则分块越少,则NameNode压力将减小,但并行的IO和处理能力降低
- 越小则分块越多,则NameNode处理压力越大,但因为寻址时间太久,不利于提高吞吐量
- 适中即可,一般采用官方的128M即可
HDFS高可用性措施:
1、冗余备份
数据存储在这些HDFS中的节点上,为了防止因为某个节点宕机而导致数据丢失,HDFS对数据进行冗余备份,至于具体冗余多少个副本,在dfs.replication中配置。
2、跨机架副本存放
仅仅对数据进行冗余备份还不够,假设所有的备份都在一个节点上,那么该节点宕机后,数据一样会丢失,因此HDFS要有一个好的副本存放策略,该策略还在开发中。目前使用的是,以dfs.replication=3为例,在同一机架的两个节点上各备份一个副本,然后在另一个机架的某个节点上再放一个副本。前者防止该机架的某个节点宕机,后者防止某个机架宕机。
3、心跳检测
DataNode节点定时向NameNode节点发送心跳包,以确保DataNode没有宕机。如果宕机,会采取相应措施,比如数据副本的备份。
4、数据完整性检测
NameNode在创建HDFS文件时,会计算每个数据的校验和并储存起来。当客户端从DataNode获取数据时,他会将获取的数据的校验和与之前储存的校验和进行对比。
5、安全模式
HDFS启动时,会进入安全模式,此时不允许写操作。这时,NameNode会收到所有DataNode节点的数据块报告,在确认安全之后,系统自动退出安全模式。
6、核心文件备份
HDFS的核心文件是映像文件(image file)和事务日志(edit log),如果这些文件损坏,将会导致HDFS不可用。系统支持对这两个文件的备份,以确保NameNode宕机后的恢复。
7、空间回收
从HDFS中删除的文件会首先被放入到/trash中,/trash文件夹中的内容是被删除文件最后的副本,该文件夹会被定时清空。该文件夹中不存在的文件就彻底不存在了。