HDFS概述

HDFS是以流式数据访问的模式来存储超大文件的一个文件系统,运行与集群上。

  • 流式数据访问:HDFS的构建思路是这样的:一次写入、多次读取是比较高效的访问模式。
  • 运行与商用的硬件中:商用的硬件在生产环境中出现故障的概率是比较大的。HDFS对数据进行数据备份,一般来讲,一份存储在HDFS集群中数据会有3份副本存储在不同的集群节点上,保证了单点数据损失的问题,HDFS保证了在集群中其中的节点发生故障后仍然可以稳定的运行,用户丝毫没有察觉。
  • 不适合低时延的数据访问:HDFS是为高数据吞吐量设计的,会以提高数据的访问时间延迟为代价。
  • 不适合大量小文件的场景:由于NameNode是将文件的元数据信息存储在内存中,大量的小文件会大大降低内存的利用率。
  • 只能文件内容追加:HDFS中的文件写入只支持单个写入,而且只能够以添加的方式写入。

HDFS-数据块

HDFS中的数据是按照块进行存储的,默认的块大小为128MB,这个块大小比一般的磁盘以及以及一些本地的文件系统的块大小要大得多,这是为什么呢?

HDFS的块大小比较大的目的是为了能够尽可能地减小寻址的开销。

假设一个12800MB的文件按照两种方式来分块:(寻址时间固定为:10ms;数据读取速度为100MB/s)

  1. 块大小为1MB->分成12800个数据块,总共需要的时间为:

    10ms*12800 + 12800MB/(100MB/s) = 128s + 128s = 256s

  2. 块大小为128MB->分成100个数据块,总共需要的时间为:

    10ms*100 + 1280MB/(100MB/s) = 1s + 128s = 129s

一般来讲,HDFS的数据块大小为128MB或者256MB,如果太大了,会导致程序在处理这块数据的时候,会非常慢,一直等待数据传输。

为什么要进行分块存储?

  1. HDFS面向的是大数据,数据文件通常比较大,可能会大于集群中单节点的磁盘容量,采用数据分块可以将大文件分成不同的数据块存放在不同的节点上
  2. 块大小是固定的,因此每个节点的容量可以用块的个数来衡量,另外块数据和元数据分块,类似于权限信息可以不和数据本身一起存储,只用存放在元数据中即可。

NameNode and DataNode

NameNode:用于存储文件的元数据(meta data),维护某个文件对应的文件块以及其所在的位置,同时还维护着整个集群的文件目录树结构。

DataNode:实际存储数据的地方。

由此可见, 当NameNode宕机之后,整个集群的数据将会丢失,因为文件数据时混乱地存放在集群中的,因此对NameNode实现容错机制非常重要,Hadoop提供两种机制:

  1. 备份元数据信息到本地或者网络文件系统,将内存中元数据信息持久化到磁盘中或者其他的网络文件系统中,在将元数据写入到本地磁盘的同时,写入到一个网络文件系统中,以备后续的数据恢复。
  2. 运行一个辅助的NameNode节点,该节点和NameNode节点不运行在同一个机器上,辅助NameNode会定期的合并NameNode的编辑日志以及命名空间镜像,当NameNode发生故障宕机时,可以临时使用辅助NameNode代替NameNode,但是这样会有数据的丢失,辅助NameNode 的数据时滞后于NameNode的。

Java client API

Hadoop是使用Java编写的,所以原生支持Java的API.

我提前搭建好了Hadoop集群

模板代码(JUnit)

public class HDFSDemo {

    private FileSystem fs;

    final String HADOOP_URI_ADDRESS = "hdfs://192.168.10.102:8020";

    final String HADOOP_USER = "root";

    @Before
    public void init() throws URISyntaxException, IOException, InterruptedException {
        // 获取文件系统
        fs = FileSystem.get(new URI(HADOOP_URI_ADDRESS), 
                            new Configuration(), 
                            HADOOP_USER);
    }

    @After
    public void after() throws IOException {
        // 关闭资源
        fs.close();
    }
}

文件下载

@Test
public void downloadFile() throws IOException {
    fs.copyToLocalFile(false,//是否删除源文件
                       new Path("/input/word.txt"),//hdfs中的文件地址
                       new Path("d:/word_down.txt"),//本地的文件地址
                       true);//是否开启校验
}

文件上传

@Test
public void uploadFile() throws IOException {
    fs.copyFromLocalFile(new Path("d:/word_down.txt"), new Path("/input/"));
}

HDFS提供很多Java的API,这里不再做过多的展示。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值