hdfs详解

hdfs简介

hdfs是hadoop中分布式的文件存储系统;具有高容错、可扩展;广泛的用于大数据项目中(不仅仅是hadoop)

优点

  • 容错性高
    • 数据自动保存多个副本(可设置)
    • 副本丢失后,自动恢复
  • 适合批处理
    • 移动计算而非移动数据
    • 数据位置暴露给计算框架
  • 适合大数据处理
    • GB、TB、甚至PB级数据
    • 百万规模以上的文件数量
    • 10K+节点
  • 可以搭建在廉价的服务器上
    • 通过副本提高可靠性
    • 提高了容错和恢复机制

缺点

  • 无法做到低延迟数据访问(比如毫秒级别的)
  • 不适合处理小文件
    • 占用namenode大量内存
    • 寻道时间会比较长(可能占整个读时间的80-90%)
  • 并发写入、文件随机修改
    -一个文件只能有一个写者
    • 不支持文件的修改(2.X版本中增加了append功能,不过在生产环境中,绝对不会开启该功能,代价太大)

hdfs架构

图片.png

这个是1.x版本的架构图

NameNode

namenode主要功能是接受客户端的读写请求,和管理metadata信息;

  • NameNode保存metadata信息包括
    • 文件权限(permissions)
    • 文件包含哪些块
    • Block保存在哪个DataNode(DataNode启动时上报)
  • NameNode的metadata信息会在启动后加载到内存中
    • metadata持久化后的文件名为 fsimage
    • block的位置信息不回保存到fsimage(由DataNode上报)
    • edits记录的是对metadata的操作日志
  • NameNode启动时,会将fsimage文件加载到内存中,并将edits文件执行一遍。这样内存中的文件就是最新的了。(注意:此时会将内存中的信息持久化到fsimage文件中)

Secondary NameNode

首先需要明白一点,Secondary NameNode不是NameNode的副本(可以充当副本的作用);

主要作用是帮助Namenode合并fsimage、edits文件;在NameNode介绍中,提到NameNode启动时会将fsimage加载到内存中,并将edits文件执行一遍。这里会有个问题,如果系统运行的时间很长,那edits文件会非常巨大,那NameNode启动的时间就会非常长(简称安全模式,后面会说到)。
因此就出现了Secondary NameNode;工作原理如下:

图片.png
  1. Secondary NameNode会将NameNode上的edits和fsimage文件通过http get的方式拉取过来,NameNode会生成edits.new文件记录接下来的操作
  2. SNN会将fsimage文件加载到内存中,并执行edits文件生成fsimage.ckpt文件
  3. SNN用http post方式将生成的fsimage.ckpt文件发送个NameNode文件
  4. NN会将fsimage文件更名为fsimage,edits.new更名为 edits

如何会触发这个合并操作?
有两个指标,一个是edits文件的大小,一个是时间

  • dfs.namenode.checkpoint.period 默认是一个小时
  • dfs.namenode.checkpoint.txns 默认是1 million,没有合并的transactions的次数

如果在这个过程中NN节点挂掉了,会不会造成数据丢失呢?

如果只是断电,服务器没有损坏,数据是不会丢失的,edits.new会持久化到磁盘中;如果服务器彻底坏了,那edits.new中的数据就会丢失。

这里有个问题需要注意下:NameNode中edits文件是实时更新的,相当于日志文件,而fsimage不是实时更新的,合并操作完之后,才会持久化到硬盘中。 也就是说只有两个时机才回持久化fsimage文件,一是启动hdfs时,NameNode在安全模式下合并fsimage文件,二是Secondary NameNode合并之后,post给NameNode时。

DataNode

  • 存储数据(block)
  • 启动DN线程的时候向NN汇报block信息
  • 通过向NN发送心跳保持联系(3秒一次),如果NN10分钟没有收到DN的心跳,则认为DN已经lost,并copy其上的block到其他的DN节点

高容错性

这里单独讲一下,hdfs高容错性是如何实现的;后面很多知识都是和它相关的。高容错体现在hdfs会对数据有个备份,hdfs默认是>=3个副本数。

如果需要修改副本数,可以修改dfs.replication参数


        dfs.replication
        3

hdfs会对文件进行拆分,按block进行拆分,1.x中每个block默认大小是64M,2.X中每个block默认大小是128M。也就是说一个文件是由多个block块组成。这里需要注意的是:block是一个逻辑的概念,一个129M的文件,会占用两个block(假设block是128M),但是这个文件占用的空间还是129M,不会占用256M的空间。

block放置的策略是:

  • 首先会选择一台负载较轻,网络比较好的机器放置第一个副本
  • 第二副本会放在和第一台不同的机架上
  • 第三个副本一般来说会和第二个在同一个机架,不同服务器上。能减少网络的IO
  • 后面的副本随机放置。

这个放置策略可以很好避免数据丢失的情况,如果某个节点挂了,hdfs会对该节点的上block都复制一份。如果该节点恢复了,hdfs不会对复制过block进行删除操作。

安全模式

安全模式是hdfs启动时,进行一些初始化的工作;这段时间;安全模式期间NN处于一个read-only状态,无法进行任何更新操作。
安全模式主要做的事是NN将fsimage文件加载内存,将edits文件执行一遍,进行合并,生成新的fsimage文件,并将其持久化到硬盘中;NN只有在启动的时候才会去合并fsimage和edits文件。NN还会等待DN上报它的block信息;当hdfs中的大部分block都是可用的时候;hdfs会自动退出安全模式;可以显示指定 dfsadmin -safemode进入安全模式。

恢复模式

如果metadata数据只有一份,并且已经损坏了;我们可以用Recovery mode启动NN,这可以恢复大部分数据。
命令是

namenode -recover

这里会有很多步,每步都会有一些选项;可以加上 -force参数;这样每次都会选择第一个。
注意:Recovery mode 可能会造成数据的丢失;所以建议进入Recovery模式之前,先备份fsimage和edits文件。

写流程

图片.png
  1. 首先创建FileSystem,和hdfs打交道,基本上都是通过FileSystem;FileSystem调用create接口向NameNode发送请求,NameNode会进行权限的检查,以及文件目录是否已经存在,父目录是否存在等检查。
  2. 第一步NameNode会返回是否可以上传
  3. client先对文件进行切分,如果block是128M,200M的文件会切分成128和72M的两个block块。client会首先请求NameNode第一个block块应该存放到那个DataNode上。NameNode会返回一些DataNode
  4. client会选择一个负载较轻,网络较好的DataNode上传数据,RPC调用,会建立pipeline进行传输,第一个DataNode接收请求,会调用第二个DataNode,然后第二个调用第三个DataNode,这样整个pipeline就建立好了。然后写入数据(以packet为单位,每个packet为64kb)
  5. 第一台DataNode收到一个packet之后,就会发送给第二台DataNode,第二台发给第三台。然后第三台应答,报告收据接收完成。重复第五步直到block写入完成
  6. 然后client写另外的block(必须在之前的block写入完成之后,才能写下一个block,而且必须是按顺序的)
  7. 写入完成之后,告诉NameNode写入完毕,然后NameNode更新元数据信息

读流程

图片.png
  1. 第一步还是通过FileSystem和NameNode进行交互。通过open方法(也会有文件是否存在的,是否有权限的一些验证),得到文件block的位置信息(在哪些DataNode节点上)
  2. client通过FSDataInputStream进行读取。
  3. client选择合适一台DataNode进行读取block。
  4. 上一个block读取完之后,再读下一个block(一定是上一个读取完了之后,才会读下一个,而且必须是按顺序来的),直到所有的block读取完毕

你可能感兴趣的:(hdfs详解)