在当前,由于集群庞大的组织体系和复杂性,以及用户普遍要求低成本硬件,使得集群在运行过程中发生的错误概率,远远高于单一且性能稳定的小型机服务器,并且集群在运行过程中几乎是不允许停止的,这就更需要提供比单机环境复杂得多的错误管理方案。实际上,我们在产品设计、开发、运营的各个阶段,有相当大一部分精力,都是用来获取各种故障,和解决各种故障发生后的错误处理问题。对于这些错误处理,我们整体遵循这样一个思路来解决:首先由软件感知来发现和定位故障点,然后进行判断,如果属于软件可以解决的故障,那么通过软件自修复机制来完成,否则,这个错误就提交给集群管理员人工处理。按照这样的两条错误处理基线,我们把各种错误处理分别融入到它们的模块中,并与这些模块嵌合,实现整个集群的容错管理。下面我们将从硬件和软件两个角度,来阐述Laxcus会面对的一些主要故障以及处理这些故障的办法。
在Laxcus集群错误管理中,我们把运行环境或者硬件本身问题所造成、且不能通过软件自行修复来解决的错误,统一称为硬件错误。硬件错误的处理工作由集群管理员来完成,软件在这里起发现和报警的作用。根据我们过往的一些经验,本节就介绍一些经常发生的硬件故障和软件感知它们的办法。
目前的网络故障由以下硬件部件造成:交换机、路由器、集线器、网线、接线头、网卡。在这些故障中,其中一部分是可以人工方式修复的,比如接线头松动、网卡接触不良等。另一部分属于硬件损坏,需要关闭设备更换。软件发现这些故障的办法也很简单,主要是通过网络握手来侦测发现,比如在软件里集成ICMP这样的功能,在运行时去追踪节点,发现可疑现象后,通过在本网段和外网段之间对比排查,可以很快判断和定位故障点。这类故障检查工作一般由管理节点来执行,其它类型的节点如果在运行过程中发现问题或者故障,也会主动提交给管理节点,供管理节点做进一步检查核对。
计算机故障是由计算机内部部件失效引发的错误,这部件包括了主板、芯片、内存、网卡、硬盘、电源。根据我们过往的使用经验,大部分计算机故障是由主板和硬盘导致,其中主板又占了相当大部分。计算机故障通过内、外两种手段来检查发现。在内部,由节点自检机制来探测部件,在外部,由管理节点来追踪节点。无论谁先检测得到,软件感知之后,都会马上提交给管理员处理。
硬盘故障有三种情况:硬盘完全损坏(通常是引导区损坏导致)、扇区损坏、磁盘空间已满。第一种情况通常在计算机启动时发生,对于这种故障,最好的解决办法是管理员在开机时跟踪一下计算机的运行情况。第二种故障通常是节点读写数据过程中产生,这种情况软件通过故障实时感知能够马上发现,会立即报告给管理员。第三种情况由写入数据太多溢出导致,不是硬盘本身问题,这种情况也会被节点马上捕捉到,然后去通知管理员。
本节点所说的“节点”,包含了软件的”进程“和硬件的”计算机“两个概念。这和之前所提略有不同,请诸位注意一下。在早期版本中,节点故障更多是软件故障造成的,比如节点的运行管理机制处理不善,模块间的API接口协同、衔接的错误。这些问题都与详细设计和编程有很大关系,随着版本演进,现在越来越多的情况是硬件问题导致。在Laxcus集群里,由于Front节点归用户使用,而且功能简单,实质只是一个用于输入输出的显示终端,所以本节忽略它,将主要介绍集群管理员管理下的节点容错。
前面已经提到过,无论是主域集群还是子域集群,都只能有一个Master管理节点来负责所属集群的管理工作,它在自己集群里的地位是独一无二的,是保证整个集群正常运行的关键。同时,为保证集群不会因为Master节点故障造成集群的管理混乱,通常还有一至数个Monitor管理节点做为备份存在着,它们将监视Master节点运行。
在我们的测试环境,有1个Master节点和2个Monitor节点。为检查管理节点容错能力,我们进行了这样的试验。我们使用Linux kill命令杀掉一个Master节点进程,在第5秒钟的时候,其中一个Monitor节点感知到Master节点发生了故障,并且立即启动故障协商机制,询问另一个Monitor节点,它对Master节点的判断,双方很快共同确认了Master节点发生了故障。然后,它们按照自己的网络地址排序,选择数字最大的那个Monitor节点,成为新的Master节点。新Master节点立即将自己从Monitor状态转入Master状态,并且通知原来所有下属节点(包括另一个Monitor节点),让它们重新注册到新Master节点下面,同时将故障的Master节点和切换过程通知给Watch节点。整个容错处理在20秒内完成。
图9.2.1 管理节点容错处理流程
Data节点保存着集群的全部数据,它的重要性仅次于管理节点,所以Data节点的容错管理也与其它节点大不相同。上面已经介绍过,每个节点宕机都会被管理节点及时捕捉到。在Data节点宕机后,管理节点会在报警的同时,对Data节点的数据做出如下处理:取出这个Data节点的数据块编号,按照数据块编号,找到同源备份,产生一个新的备份到其它节点上,如果是Data主节点,其它从节点备份会恢复到一个新的主节点上,并且这些从块也升级成主块。如果是Data从节点,这些备份会从主节点产生备份,分发到其它从节点上。由于Data主节点的数据量一般都比较大(最多时候有几个TB),又要保证不能太过于占用网络带宽,实际上这个恢复备份过程是缓慢的。在这段时间里,管理员有足够的时间来检查和恢复故障计算机。当重新启动计算机后,它会在网络上进行主块冲突检查,避免同质数据块出现。尤其是主节点故障,在恢复完成前,存在着数据不全的可能性,这个时间内发生的更新/删除操作,Call节点将拒绝它们执行,直到全部数据完成恢复。
图9.2.2 Data节点容错
相较于以上两种,集群内的其它节点不保存数据,也不负责集群管理工作,它们只是为了满足分布处理流程而存在,运行过程中通常也不止一个节点,每类节点之间可以互相替代。这些单个节点的退出和加入,对于整个集群的运行来说,只产生微小的影响。所以在Laxcus容错设计里,对这些节点的容错管理要宽泛很多,它们的故障,通常都是以报警方式通知给Watch节点,由管理员来进行判断和处理。它们缺失的工作,也会由管理节点通知其它同类节点来取代。
在我们统计的多组Laxcus集群故障中,因为节点导致的故障概率并不高,大量发生的是数据错误。造成数据错误的主要原因是磁盘出现了坏区,这种故障通常在计算机读写磁盘数据被捕获。处理数据错误的办法是冗余复制,由出现错误块的Data节点使用自修复机制来实现。其过程是错误块所属Data节点通过网络去查找其它Data节点上同编号的数据块,然后把正确的数据块下载下来,取代已经出现错误的数据块。在数据块复制过程中,这个表下面的全部数据块将被锁定,直到完成更新后才被解锁。错误的数据块将被Data节点标记起来,并且停止使用它。最后Data节点将数据块编号和自己的网络地址发送给Watch节点上,提供管理员注意已经发生了数据错误。
现在的分布任务组件故障基本都来源于用户,是程序员在编程时处理不善导致。这样的错误在程序员编程过程中,以及集群测试环境里都难以发现,只有在正式的运营环境才有可能发生。负责监管分布任务组件错误的是沙箱,这是它在安全管理之外的另一个主要责任。为了防止故障扩散,沙箱将分布任务组件错误限制在它自己的空间里,不会波及节点和其它分布任务组件。故障发生后,沙箱会立即卸载这个分布任务组件,并且向源头发送一个错误码和它的错误堆栈,同时也把这些信息提交给管理员,由管理员去负责和用户交涉。
虽然集群提供了故障感知能力,也实现了一些错误自恢复处理,但是仍然有各种后期管理工作,需要管理员来执行才能解决。要完成这些工作,管理员应该具备一定的专业知识和职业责任。
对于很多因为软件问题产生的故障,现在已经基本可以通过追踪日志和断点分析得到;对于硬件故障,则更需要维护经验和专业知识,这些都需要一定时间的工作积累,付出很多时间和学习为代价。实际上,根据我们的运营和管理集群的经历,随着未来大数据市场需要的存储量和计算量的增加,网络和集群规模会越来越大。要做好集群管理工作,不是一件轻松的事,集群管理员要能够了解集群和各种节点的性能参数、执行处理范围、故障特点和原因,并且能够在发现问题后能够很快解决问题,在线上和线下与各种人进行沟通和联络。这些要求,做为集群管理员,需要有充分准备。