Hadoop服务器的错误恢复

在分布式环境中,哪台服务器 牺牲都是常见的事情,牺牲不可怕,可怕的是你都没有时刻准备好它们会牺牲。作为一个合格的分布式系统,HDFS当然时刻准备好了前赴后继奋勇向前。 HDFS有三类服务器,每一类服务器出错了,都有相应的应急策略。。。
a. 客户端
生命最轻如鸿毛的童鞋,应该就是客户端了。毕 竟,做为一个文件系统的使用者,在整个文件系统中的地位,难免有些归于三流。而作为客户端,大部分时候,牺牲了就牺牲了,没人哀悼,无人同情,只有在在辛 勤写入的时候,不幸辞世(机器挂了,或者网络断了,诸如此类...),才会引起些恐慌。因为,此时此刻,在主控服务器上对应的文件,正作为 INodeFileUnderConstruction 活 着,仅仅为占有它的那个客户端服务者,做为一个专一的文件,它不允许别的客户端染指。这样的话,一旦占有它的客户端服务者牺牲了,此客户端会依然占着茅坑 不拉屎,让如花似玉INodeFileUnderConstruction孤孤单单守寡终身。这种事情当然无法容忍,因此,必须有办法解决这个问题,办法 就是: 租约 。。。
租约,顾名思义,就是 当客户端 需要占用某文件的时候,与主控服务器签订的一个短期合同 。这个合同有一个期限,在这个期限内,客户端可以延长合同期限,一旦超过期限, 主控服务器会强行终止此租约,将这个文件的享用权,分配给他人。。。
在打开或创建一个文件,准备追加写之前,会调用 LeaseManageraddLease 方 法,在指定的路径下与此客户端签订一份租约。客户端会启动 DFSClient.LeaseChecker 线程,定时轮 询调用 ClientProtocolrenewLease 方法,续签租约。在主 控服务器一端,有一个 LeaseManager.Monitor 线程,始终在轮询检查所有租约,查看是否有到期未续的 租约。如果一切正常,该客户端完成写操作,会关闭文件,停止租约,一旦有所意外,比如文件被删除了,客户端牺牲了,主控服务器都会剥夺此租约,如此,来避 免由于客户端停机带来的资源被长期霸占的问题。。。
b. 数据服务器
当然,会挂的不只是客户端,海量的数据服务器是 一个更不稳定的因素。一旦某数据服务器牺牲了,并且主控服务器被蒙在鼓中,主控服务器就会变相的欺骗客户端,给它们无法连接的读写服务器列表,导致它们处 处碰壁无法工作。因此,为了整个系统的稳定,数据服务器必须时刻向主控服务器汇报,保持主控服务器对其的完全了解,这个机制,就是心跳消息。在HDFS 中,主控服务器 NameNode 实现了 DatanodeProtocol 接口,数 据服务器 DataNode 会在主循环中,不停的调用该协议中的 sendHeartbeat 方 法,向NameNode汇报状况。在此调用中,DataNode会将其整体运行状况告知NameNode,比如:有多少可用空间、用了多大的空间,等等之 类。NameNode会记住此DataNode的运行状况,作为新的数据块分配或是负载均衡的依据。当NameNode处理完成此消息后,会将相关的指令 封装成一个 DatanodeCommand 对象,交还给DataNode,告诉数据服务器什么数据块要删除什么数据块 要新增等等之类,数据服务器以此为自己的行动依据。。。
但是,sendHeartbeat并没有提供本 地的数据块信息给NameNode,那么主控服务器就无法知道此数据服务器应该分配什么数据块应该删除什么数据块,那么它是如何决定的呢?答案就是 DatanodeProtocol定义的另一个方法, blockReport 。DataNode也是在主循环中定时调 用此方法,只是,其周期通常比调用sendHeartbeat的更长。它会提交本地的所有数据块状况给NameNode,NameNode会和本地保存的 数据块信息比较,决定什么该删除什么该新增,并将相关结果缓存在本地对应的数据结构中,等待此服务器再发送sendHeartbeat消息过来的时候,依 照这些数据结构中的内容,做出相应的DatanodeCommand指令。blockReport方法同样也会返回一个DatanodeCommand给 DataNode,但通常,只是为空(只有出错的时候不为空),我想,增加缓存,也许是为了确保每个指令都可以重复发送并确定被执行。。。
c. 主控服务器
当然,作为整个系统的核心和单点,含辛茹苦的主 控服务器含泪西去,整个分布式文件服务集群将彻底瘫痪罢工。如何在主控服务器牺牲后,提拔新的主控服务器并迅速使其进入工作角色,就成了系统必须考虑的问 题。解决策略就是: 日志 。。。
其实这并不是啥新鲜东西,一看就知道是从数据库那儿偷师而来的。在主控服务器上,所有对文件目录操作的关键步骤(具体文件内容所处的数据服务器,是不会被 写入日志的,因为这些内容是动态建立的...),都会被写入日志。另外,主控服务器会在某些时刻,将当下的文件目录完整的序列化到本地,这称为 镜 像 。一旦存有镜像,镜像前期所写的日志和其他镜像,都纯属冗余,其历史使命已经完成,可以报废删除了。在主控服务器不幸牺牲,或者是战 略性的停机修整结束,并重新启动后,主控服务器会根据 最近的镜像 + 镜像之后的所有日志 ,重建整个文件目录,迅速将 服务能力恢复到牺牲前的水准。。。
对于数据服务器而言,它们会通过一些手段,迅速 得知顶头上司的更迭消息。它们会立刻转投新东家的名下,在新东家旗下注册,并开始向其发送心跳消息,这个机制,可能用分布式协同服务来实现,这里不说也 罢。。。
在HDFS的实现中, FSEditLog 类 是整个日志体系的核心,提供了一大堆方便的日志写入API,以及日志的恢复存储等功能。目前,它支持若干种日志类型,都冠以OP_XXX,并提供相关 API,具体可以参见 这里 。为了保证日志的安全性,FSEditLog提供了 EditLogFileOutputStream 类 作为写入的承载类,它会同时开若干个本地文件,然后依次写入,防止日志的损坏导致不可估量的后果。在FSEditLog上面,有一个 FSImage 类, 存储文件镜像并调用FSEditLog对外提供相关的日志功能。FSImage是Storage类的子类,如果对数据块的讲述有所印象的话,你可以回忆起 来,凡事从此类派生出来的东西,都具有版本性质,可以进行升级和回滚等等,以此,来实现产生镜像是对原有日志和镜像处理的复杂逻辑。。。
目前,在HDFS的日志系统中,有些地方与 GFS的描述有所不同。在HDFS中,所有日志文件和镜像文件都是本地文件,这就相当于,把日志放在自家的保险箱中,一旦主控服务器挂了,别的后继而上的 服务器也无法拿到这些日志和镜像,用于重振雄风。因此,在HDFS中,运行着一个 SecondaryNameNode 服 务器,它做为主控服务器的替补,隐忍厚积薄发为篡位做好准备,其中,核心内容就是: 定期下载并处理日志和镜像 。 SecondaryNameNode看上去像客户端一样,与NameNode之间,走着 NamenodeProtocol 协 议。它会不停的查看主控服务器上面累计日志的大小,当达到阈值后,调用 doCheckpoint 函数,此函数的主要步 骤包括:
  • 首先是调用startCheckpoint 做 一些本地的初始化工作;
  • 然后调用rollEditLog , 将NameNode上此时操作的日志文件从edit 切到edit.new 上来,这 个操作瞬间完成,上层写日志的函数完全感觉不到差别;
  • 接着,调用downloadCheckpointFiles , 将主控服务器上的镜像文件和日志文件都下载到此候补主控服务器上来;
  • 并调用doMerge , 打开镜像和日志,将日志生成新的镜像,保存覆盖;
  • 下一步,调用putFSImage 把 新的镜像上传回NameNode;
  • 再调用rollFsImage , 将镜像换成新的,在日志从edit.new改名为edit;
  • 最后,调用endCheckpoint 做 收尾工作。
整个算法涉及到NameNode和 SecondaryNameNode两个服务器,最终结果是NameNode和SecondaryNameNode都依照 算法进行前 的 日志生成了镜像。而两个服务器上日志文件的内容,前者是整个 算法进行期间 所写的日志,后者始终不会有任何日志。当主控 服务器牺牲的时候,运行SecondaryNameNode的服务器立刻被扶正,在其上启动主控服务,利用其日志和镜像,恢复文件目录,并逐步接受各数据 服务器的注册,最终向外提供稳定的文件服务。。。
同样的事情,GFS采用的可能是另外一个策略, 就是在写日志的时候,并不局限在本地,而是同时书写 网络日志 ,即在若干个远程服务器上生成同样的日志。然后,在某些时 机,主控服务器自己,生成镜像,降低日志规模。当主控服务器牺牲,可以在拥有网络日志的服务器上启动主控服务,升级成为主控服务器。。。
GFS与HDFS的策略相比较,前者是化整为 零,后者则是批量处理,通常我们认为,批量处理的平均效率更高一些,且相对而言,可能实现起来容易一些,但是,由于有间歇期,会导致日志的丢失,从而无法 100%的将备份主控服务器的状态与主控服务器完全同步。。。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值