(一)分布式文件系统概述
数据量越来越多,在一个操作系统管辖的范围存不下了,那么就分配到更多的操作系统管理的磁盘中,但是不方便管理和维护,因此迫切需要一种系统来管理多台机器上的文件,这就是分布式文件管理系统 。是一种允许文件通过网络在多台主机上分享的文件系统,可让多机器上的多用户分享文件和存储空间。通透性。让实际上是通过网络来访问文件的动作,由程序与用户看来,就像是访问本地的磁盘一般。 容错。即使系统中有某些节点脱机,整体来说系统仍然可以持续运作而不会有数据损失。分布式文件管理系统很多,hdfs只是其中一种,不合适小文件。
HttpFS访问方式
1:httpfs是一个hadoop hdfs的一个http接口,通过WebHDFS REST API 可以对hdfs进行读写等访问
2:与WebHDFS的区别是不需要客户端可以访问hadoop集群的每一个节点,通过httpfs可以访问放置在防火墙后面的hadoop集群
3:httpfs是一个Web应用,部署在内嵌的tomcat中
NFS:
The NFS Gateway supports NFSv3 and allows HDFS to be mounted as part of the client’s local file system. Currently NFS Gateway supports and enables the following usage patterns: Users can browse the HDFS file system through their local file system on NFSv3 client compatible operating systems. Users can download files from the the HDFS file system on to their local file system. Users can upload files from their local file system directly to the HDFS file system. Users can stream data directly to HDFS through the mount point. File append is supported but random write is not supported. The NFS gateway machine needs the same thing to run an HDFS client like Hadoop JAR files, HADOOP_CONF directory. The NFS gateway can be on the same host as DataNode, NameNode, or any HDFS client.
HDFSNFSGateway能够把HDFS挂载到客户机上作为本地文件系统来管理,支持NFSv3。当前版本的NFSGateway有如下可用特性。用户在支持NFSv3的操作系统上可以通过本地文件系统浏览HDFS。使用NFSGateway用户能够直接下载和上传HDFS文件到本地文件系统中。用户可以通过挂载点直接传输数据流至HDFS,但只能增量添加不能随机写数据。
NameNode之间共享数据(NFS 、QuorumJournalNode(用得多)):
两个NameNode为了数据同步,会通过一组称作JournalNodes的独立进程进行相互通信。当active状态的NameNode的命名空间有任何修改时,会告知大部分的JournalNodes进程。standby状态的NameNode有能力读取JNs中的变更信息,并且一直监控editlog的变化,把变化应用于自己的命名空间。standby可以确保在集群出错时,命名空间状态已经完全同步了。
hadoop2.2.0(HA)中HDFS的高可靠指的是可以同时启动2个NameNode。其中一个处于工作状态,另一个处于随时待命状态。这样,当一个NameNode所在的服务器宕机时,可以在数据不丢失的情况下,手工或者自动切换到另一个NameNode提供服务。这些NameNode之间通过共享数据,保证数据的状态一致。多个NameNode之间共享数据,可以通过Nnetwork File System或者QuorumJournalNode。前者是通过linux共享的文件系统,属于操作系统的配置;后者是hadoop自身的东西,属于软件的配置。使用QuorumJournalNode的配置方式,方式是手工切换。
集群启动时,可以同时启动2个NameNode。这些NameNode只有一个是active的,另一个属于standby状态。active状态意味着提供服务,standby状态意味着处于休眠状态,只进行数据同步,时刻准备着提供服务,如图2所示。
在一个典型的HA集群中,每个NameNode是一台独立的服务器。在任一时刻,只有一个NameNode处于active状态,另一个处于standby状态。其中,active状态的NameNode负责所有的客户端操作,standby状态的NameNode处于从属地位,维护着数据状态,随时准备切换。
两个NameNode为了数据同步,会通过一组称作JournalNodes的独立进程进行相互通信。当active状态的NameNode的命名空间有任何修改时,会告知大部分的JournalNodes进程。standby状态的NameNode有能力读取JNs中的变更信息,并且一直监控edit
log的变化,把变化应用于自己的命名空间。standby可以确保在集群出错时,命名空间状态已经完全同步了,如图3所示。
为了确保快速切换,standby状态的NameNode有必要知道集群中所有数据块的位置。为了做到这点,所有的datanodes必须配置两个NameNode的地址,发送数据块位置信息和心跳给他们两个。
对于HA集群而言,确保同一时刻只有一个NameNode处于active状态是至关重要的。否则,两个NameNode的数据状态就会产生分歧,可能丢失数据,或者产生错误的结果。为了保证这点,JNs必须确保同一时刻只有一个NameNode可以向自己写数据。
为了部署HA集群,应该准备以下事情:
* NameNode服务器:运行NameNode的服务器应该有相同的硬件配置。
*JournalNode服务器:运行的JournalNode进程非常轻量,可以部署在其他的服务器上。注意:必须允许至少3个节点。当然可以运行更多,但是必须是奇数个,如3、5、7、9个等等。当运行N个节点时,系统可以容忍至少(N-1)/2(N至少为3)个节点失败而不影响正常运行。
在典型的HA架构中,有两个独立的机器作为Namenode,任何时刻,只有一个Namenode处于Active状态,另一个处于standby状态(passive,备份);Active
Namenode用于接收Client端请求,Standy节点作为slave保持集群的状态数据以备快速failover。
为了支持快速failover,Standbynode持有集群中blocks的最新位置是非常必要的。为了达到这一目的,Datanodes上需要同时配置这两个Namenode的地址,同时和它们都建立心跳链接,并把block位置发送给它们。
任何时刻,只有一个Active Namenode是非常重要的,否则将会导致集群操作的混乱,那么两个Namenode将会分别有两种不同的数据状态,可能会导致数据丢失,或者状态异常,这种情况通常称为“split-brain”(脑裂,三节点通讯阻断,即集群中不同的Datanodes却看到了两个Active Namenodes)。对于JNS(JournalNodes)而言,任何时候只允许一个Namenode作为writer;在failover期间,原来的StandbyNode将会接管Active的所有职能,并负责向JNS写入日志记录,这就阻止了其他Namenode基于处于Active状态的问题。
自动Failover
上述介绍了如何配置手动failover,在这种模式下,系统不会自动触发failover,即不会将Standby提升为Active,即使Active已经失效。接下来介绍如何实现自动failover。
一)、组件
Automatic Failover中,增加了2个新的组件:zookeeper集群,ZKFailoverController进程(简称为ZKFC)。
Zookeeper是一个高可用的调度服务,可以保存一系列调度数据,当这些数据变更(notify)时可以通知Client,以及监控(montitor)Clients失效,自动failover的实现将依赖于Zookeeper的几个特性:
1、Failure delection:失效检测,每个Namenode将会和zookeeper建立一个持久session,如果Namenode失效,那么次session将会过期失效,此后Zookeeper将会通知另一个Namenode,然后触发Failover。
2、Active Namenode election:zookeeper提供了简单的机制来实现AcitveNode选举,如果当前Active失效,Standby将会获取一个特定的排他锁(lock),那么获取(持有)锁的Node接下来将会成为Active。
ZKFailoverControllor(ZKFC)是一个zookeeper客户端,它主要用来监测和管理Namenodes的状态,每个Namenode机器上都会运行一个ZKFC程序,它的职责为:1、Health monitoring:ZKFC间歇性的使用health-check指令ping本地的Namenode,Namenode也会及时的反馈自己的health status。如果Namenode失效,或者unhealthy,或者无响应,那么ZKFS将会标记其为“unhealthy”。
2、Zookeeper session manangement:当本地Nanenode运行良好时,ZKFC将会持有一个zookeeper session,如果本地Namenode为Active,它同时也持有一个“排他锁”(znode);这个lock在zookeeper中为“ephemeral” znode(临时节点),如果session过期,那么次lock所对应的znode也将被删除。
3、Zookeeper-based election:如果本地Namenode运行良好,并且ZKFS没有发现其他的的Namenode持有lock(比如Active失效后,释放了lock),它将尝试获取锁,如果获取成功,即“赢得了选举”,那么此后将会把本地Namenode标记为Active,然后触发Failover:首先,调用fencing method,然后提升本地Namenode 为Active。
在Automatic Failover中,需要把一个重要的配置项添加到hdfs-site.xml中。dfs.ha.automatic-failover.enabled设置为true,
1、ZKFC和Namenodes守护进程的启动顺序是否重要?
No,对于指定的Namenode,你可以在其之前或者之后启动ZKFC均可以,ZKFC只是调度Namenode的存活状态,如果不启动ZKFC,此Namenode将无法参与自动failover过程。
2、是否需要额外的monitoring?
你需要在Namenode机器上,添加额外的monitor用来监控ZKFC是否运行。在某些情况下,zookeeper集群的故障可能导致ZKFC意外中断,你需要适时的重启ZKFC。此外,还需要监控Zookeeper集群的运行状况,如果Zookeeper集群失效,那么HA集群将无法failover。
3、如果Zookeeper失效,将会怎么样?
如果zookeeper集群故障,那么Automatic Failover将不会触发,即使Namenode失效,这也意味着ZKFC无法正常运行。不过,如果Namenodes正常(即使有一个失效),那么HDFS系统将不会受到影响。因为HDFSClient并没有基于zookeeper做任何事情,当zookeeper集群仍需要尽快的恢复以避免当前Active失效而造成的“split-brain”等问题。
4、是否可以在Namenodes之间指定优先级?
NO,这是不能支持的。首先启动的Namenode将作为Active,我们只能认为控制Namenode启动的顺序来做到“优先级”。
5、在Automatic Failover中,手动Failover怎么做?
和普通的Failover一样,我们总是可以通过"hdfshaadmin -DFSHAAdmin -failover"来实现手动Failover。
在Automatic Failover中,需要把一个重要的配置项添加到hdfs-site.xml中。
zkfailover:
1.基本原理
zk的基本特性:(1) 可靠存储小量数据且提供强一致性 (2) ephemeral node, 在创建它的客户端关闭后,可以自动删除 (3) 对于node状态的变化,可以提供异步的通知(watcher)
zk在zkfc中可以提供的功能:(1) Failure detector: 及时发现出故障的NN,并通知zkfc (2) Active node locator: 帮助客户端定位哪个是Active的NN (3) Mutual exclusion of active state: 保证某一时刻只有一个Active的NN
2. 模块
(1) ZKFailoverController(DFSZKFailoverController): 驱动整个ZKFC的运转,通过向HealthMonitor和ActiveStandbyElector注册回调函数的方式,subscribe HealthMonitor和ActiveStandbyElector的事件,并做相应的处理
(2) HealthMonitor: 定期check NN的健康状况,在NN健康状况发生变化时,通过回调函数把变化通知给ZKFailoverController
(3) ActiveStandbyElector: 管理NN在zookeeper上的状态,zookeeper上对应node的结点发生变化时,通过回调函数把变化通知给ZKFailoverController
(4) FailoverController: 提供做gracefulfailover的相关功能(dfs admin可以通过命令行工具手工发起failover)
3. 系统架构
如上图所示,通常情况下Namenode和ZKFC同布署在同一台物理机器上,HealthMonitor, FailoverController,ActiveStandbyElector在同一个JVM进程中(即ZKFC),Namenode是一个单独的JVM进程。如上图所示,ZKFC在整个系统中有几个重要的作用:
(1) Monitor and try to take active lock: 向zookeeper抢锁,抢锁成功的zkfc,指导对应的NN成为active的NN; watch锁对应的znode,当前active NN的状态发生变化导致失锁时,及时抢锁,努力成为active NN
(2) Monitor NN liveness and health: 定期检查对应NN的状态, 当NN状态发生变化时,及时通过ZKFC做相应的处理
(3) Fences other NN when needed: 当前NN要成为active NN时,需要fence其它的NN,不能同时有多个active NN
4. 线程模型
ZKFC的线程模型总体上来讲比较简单的,它主要包括三类线程,一是主线程;一是HealthMonitor线程; 一是zookeeper客户端的线程。它们的主要工作方式是:
(1) 主线程在启动所有的服务后就开始循环等待
(2) HealthMonitor是一个单独的线程,它定期向NN发包,检查NN的健康状况
(3) 当NN的状态发生变化时,HealthMonitor线程会回调ZKFailoverController注册进来的回调函数,通知ZKFailoverController NN的状态发生了变化
(4) ZKFailoverController收到通知后,会调用ActiveStandbyElector的API,来管理在zookeeper上的结点的状态
(5) ActiveStandbyElector会调用zookeeper客户端API监控zookeeper上结点的状态,发生变化时,回调ZKFailoverController的回调函数,通知ZKFailoverController,做出相应的变化
5. 类关系图
ZKFC的主类是org.apache.hadoop.hdfs.tools.DFSZKFailoverController。
formatZK 创建特定目录,作为后续写节点状态的父路径。如果该目录已经存在,清理原有目录为空目录。
HealthMonitor 在一个独立线程中,通过RPC方式,周期性的调用HAServiceProtocol接口的monitorHealth方法,获取NN的状态。并把状态报告给ActiveStandbyElector。
ActiveStandbyElector ActiveStandbyElector负责判断哪个NN可以成为Active。它通过ZK,看哪个能够成功的创建一个特定的ephemeral lock file (znode),哪个就是Active,其它的成为Standby。在一个节点被通知变成Active后,它必须确保自己能够提供一致性的服务(数据一致性),否则它需要主动退出选举。
如果一个Active因HealthMonitor监控到状态异常,这里会作出判断,先通过Fenceing功能关闭它(确保关闭或者不能提供服务),然后在ZK上删除它对应ZNode。发送上述事件后,在另外一台机器上的ZKFC中的ActiveStandbyElector会收到事件,并重新进行选举(尝试创建特定ZNode),它将获得成功并更改NN中状态,从而实现Active节点的变更。
HDFS体系结构
Client客户端+Namenode+DataNode
是整个文件系统的管理节点。它维护着1.整个文件系统的文件目录树,2.文件/目录的元信息和每个文件对应的数据块列表。3.接收用户的操作请求。文件包括:(hdfs-site.xml的dfs.namenode.name.dir属性)
fsimage:元数据镜像文件。存储某一时段NameNode内存元数据信息。edits:操作日志文件。fstime:保存最近一次checkpoint的时间 以上这些文件是保存在linux的文件系统中。
NameNode维护着2张表:1.文件系统的目录结构,以及元数据信息;2.文件与数据块(block)列表的对应关系
元数据存放在fsimage中,在运行的时候加载到内存中的(读写比较快)。操作日志写到edits中。(类似于LSM树中的log)
(刚开始的写文件会写入到内存中和edits中,edits会记录文件系统的每一步操作,当达到一定的容量会将其内容写入fsimage中)
dfs.namenode.name.dir -- /lvm/dfs/nn
/lvm/dfs/nn/current
保存有fsimage和edit文件 确定namenode在本地文件系统上的DFS名称节点应存储名称表(fsimage)。
fsimage的内容会被存储到以逗号分隔的列表的目录中,然后在所有的目录中复制名称表目录,用于冗余。
查看NameNode内容
启动服务器bin/hdfs oiv -i 某个fsimage文件 --offline image viewer -i(input) -o(output)
查看内容bin/hdfs dfs -ls -R webhdfs://127.0.0.1:5978/
导出结果bin/hdfs oiv -p XML -i tmp/dfs/name/current/fsimage_0000000000000000055 -o fsimage.xml
查看edtis内容bin/hdfs oev -i tmp/dfs/name/current/edits_0000000000000000057-0000000000000000186 -o edits.xml
2.Datanode
提供真实文件数据的存储服务。
文件块(block):最基本的存储单位。对于文件内容而言,一个文件的长度大小是size,那么从文件的0偏移开始,按照固定的大小,顺序对文件进行划分并编号,划分好的每一个块称一个Block。HDFS默认Block大小是128MB(dfs.blocksize,dfs.block.size),以一个256MB文件,共有256/128=2个Block. 不同于普通文件系统的是,HDFS中,如果一个文件小于一个数据块的大小,并不占用整个数据块存储空间。(这样设置可以减轻namenode压力,因为namonode维护者文件与数据块列表的对应大小) Replication。多复本。默认是三个。(hdfs-site.xml的dfs.replication属性).注意区别:一个文件可以产生多个块,多个文件是不可能成为一个块信息的,处于减轻namenode的压力,最好的方式就是一个文件一个块.
文件块存放路径查看与具体信息解释
(a)查找datanode存放数据的位置,配置信息在hdfs-site.xml中
cd /lvm/data8/dfs/dn/current/BP-625280320-192.168.191.130-1483628038952/current/finalized/subdir0/subdir0
DataNode:使用block形式存储。在hadoop2中,默认的大小是128MB。使用副本形式保存数据的安全,默认的数量是3个。