Hadoop HDFS

Hdfs (Hadoop Distributed Filesystem) 是Hadoop自带的分布式文件系统,它设计用于提供对大规模文件的流式数据访问的能力,运行于由廉价的机器所组成的集群中。

Hdfs的优缺点

优点

  • 能存储大规模文件

    即能存储数百MB,GB,TB设置PB的数据

  • 流式数据访问

    Hdfs提供于一次写入,多次读取的模式

  • 商品性的硬件

    Hadoop不需要昂贵、高可靠的硬件,它设计运行与商品性的硬件中。

缺点

  • 不能进行实时数据访问

  • 很多小文件的情况有限制

    Hadoop的NameNode将文件的元数据(metadata)存储于内存中,这样所能存储的文件的数量就会受到NameNode的内存大小的限制。

  • 多个writer进行任意修改

    不支持多个writer在文件的任意偏移(offset)处进行修改

HDFS的一些关键概念

Blocks

磁盘也有Block size,block是读写数据的最小单位,一般为512字节。同样,HDFS也有block的概念,但其默认大小为128MB,在HDFS中的文件将被划分为block-size的chunk。

不同与单一磁盘的文件系统,HDFS中文件大小小于block-size时,并不会占用多余的空间(1MB的文件只会占用1MB,而不会占用128MB)

采用Block的机制有以下好处:

  • 一个文件可以很大,比如在单个磁盘中的文件会首磁盘空间的限制,而HDFS中文件则可以大很多。
  • 使用block抽象而不是文件简化存储子系统。一是block方便管理(固定大小),二是不需要关心元数据(metadata不和block一起存储)
  • block能够很好地适应replication(复制)机制,其提供了fault tolerance(容错处理)和高可用的特性。(每一个block都会被复制为多份,存储于不同的地方)

我们可以使用hdfs fsck / -files -blocks查看文件系统中每个文件的block的信息

NameNode和DataNode即Secondary NameNode

HDFS采用master-worker的模式:NameNode为Master,DataNode为worker。

NameNode维持filesystem tree,并保存tree中的所有文件的元数据和目录。这些信息存储在本地磁盘的两个文件中:namespace image 和 edit log。NameNode知道对于给定的文件,其知道该文件所有的block存储在哪些DataNode的具体位置。

DataNode存储具体的blocks,并将block list报告给NameNode。

NameNode的数据备份
由于NameNode存储整个文件系统的元数据进行,要是NameNode挂了,则所有的文件都找不到了,所以要做容错措施。其方式主要由以下几种:

1.将持久状态写入多个文件系统(写入方式为synchronized其atomic),例如写入本地文件系统或者远程的NFS

2.使用Second NameNode

Secondary NameNode定期合并NameNode的namespace image和edit log,以防止edit log过大,将合并的文件保存为新的namespace image。
但是要注意的是,这里存在数据丢失的风险(由于Second NameNode并不是实时同步NameNode的数据,所有从上次同步到NameNode挂掉的时间段内,这段时间的数据会丢失)。这种情况下,通常要将NFS(即实时备份数据)中的元数据信息拷贝到Secondary NameNode,并启动它将之设为master。

3.使用HA(High Availiability)模式
可以使用HA模式来保证,具体请看下面对HA的阐述。

Block Cacheing

对于频繁读取的文件的block,DataNode通常会将这些blocks缓存到内存中,以提高读取性能。用户通过向缓存池添加缓存指令来指示namenode缓存哪些文件(以及缓存多长时间)。缓存池是用于管理缓存权限和资源使用情况的管理分组

HA(High Availiability)模式

Secondary NameNode模式并不能提供高可用的文件系统,它仍然存在单点失败(single point of failure),这会导致mapreduce程序失效。当主NameNode失效时,需要重新恢复一个新的NameNode,一般需要以下步骤:

1)加载namespace image到内存
2)重放edit log
3)接收足够的来自datanode的block信息以离开安全模式

而这往往需要花费很长时间(30min以上)。

Hadoop 为了解决该问题,其增加了HDFS high availibility(HA)支持。其包含一对NameNode,以主备(active-standby)的方式配置,当主NameNode失效时,备NameNode则承担其责任并继续提供服务给客户端,为了达到这种效果,必须进行如下设置:

  • namenode必须使用高可用的共享存储(shared storage)来共享edit log,当备NameNode启动时,它读取edit log以同步active namenode的状态,并且继续读取active namenode往其中写的内容
  • datenode必须将block report发送到active namenode和standby namenode,因为block mapping是存储在namnode的内存而不是磁盘中的
  • 客户端必须配置namenode失效处理,并对客户端透明
  • standby namenode仍然包括secondary namenode的角色,其同样采用active namenode的定期检测点(periodic check point)

对于高可用的共享存储有两种方式:NFS 文件、QJM(quorum journal manager), QJM专为HDFS共享edit log而实现,推荐使用QJM。QJM 简介如下

The QJM runs as a group of journal nodes, and each edit must be written to a majority of the journal nodes. Typically, there are three journal nodes, so the system can tolerate the loss of one of them. This arrangement is similar to the way ZooKeeper works, although it is important to realize that the QJM implementation does not use ZooKeeper. (Note, however, that HDFS HA does use ZooKeeper for electing the active namenode.)

其一般采用三个journal节点,类似zookeeper,QJM一次只允许一个namenode写edit log。

故障切换

从active namenode过渡到standby node的过程由failover controller管理,一般有多重failover controller的实现,默认是Zookeeper,其保证只有一个namenode是active状态。任意一个namenode都运行有一个轻量级的failover controller进程,用来监控namenode的失效(使用心跳机制),当namenode失效时触发failover(故障切换)。

有时候,我们需要手动切换namenode,一般这个操作成为graceful failover。在ungraceful failover中,难以保证失效的namenode停止运行,例如慢网络触发failover transition时。怎么办呢?HA为我们提供了fencing机制以阻止先前的active namenode任何有危害性的动作。

客户端的failover transition是怎么做的呢?很简单,客户端定义的HDFS URL使用一个域名,而这个域名会映射到一对namenode,尝试对每个namenode进行访问直到成功为止。

坚持原创技术分享,您的支持将鼓励我继续创作!