本文转载自微信公众号《KK架构师》,作者wangkai。转载请联系KKarchitects公众号。一、分布式系统中的心跳技术心跳是分布式技术中常用的技术手段。心跳,顾名思义,就是一种以固定的频率向其他节点报告当前节点状态的方式。收到心跳后,一般可以认为发送心跳的节点在当前网络拓扑中是好的。当然,心跳上报的时候,一般还会携带一些额外的状态,元数据信息,当前节点的信息,以便于其他节点进行管理。心跳有两种方式:单向心跳;互动乒乓;在第一种方式中,目标进程需要定期向检测器发送消息,以告知自身其生存能力。检测器不需要向目标回复任何消息,而只是定期检查目标进程是否有报告。第二种方法更常见。比如我们的redis就是采用这样的方式:detector->target:Areyouok?它被认为处于非活动状态。那么常用的心跳检测机制有哪些:(1)传统的周期性心跳检测机制的检测方式很粗糙:设置一个超时时间T,只要对方在T内没有收到对方的心跳包,可以认为对方倒下了,该方法简单有效,应用广泛。因此,该方法的重点在于超时时间T的设置,如果设置过短,可能会因当前网络拥塞导致误判,导致节点下线,造成其他不必要的后果;如果设置过长,会导致判断“慢”,所以需要根据各种情况权衡设置。HDFS使用这种心跳机制。(2)累积故障检测机制随着网络负载的增加,Server心跳的接收时间可能大于上限值T;但当网络压力降低时,心跳的接收时间会小于T,如果用常量T来反映心跳情况会造成“慢”或误判。这时候我们可以计算出心跳延迟的概率,通过这个概率来判断是否发生故障,提高准确率。2.DataNode如何向NameNode发送心跳从hadoop源码看DataNode如何发送心跳1.从DataNode类的main方法开始2.创建DataNode3,实例化DataNode4,创建实例5.新建DataNode6,该方法构造了函数有点长,拉到最下面的7,再来这个方法。从表面上看,这个方法似乎是在刷新NameNode。其实它在里面做了两件事,一是把自己注册到NameNode上,二是定时发送给NameNode。心跳。8.点击进入,现在是在BlockPoolManager中9.然后来到这个方法10.发现是在遍历BPOfferService。这是对数据结构offerServices是什么的一般解释。用一张图说明offerServices其实是和最左边的BPOfferService一起安装的。每个BPOfferService中有两个BpServiceActor,每个BpServiceActor对应一个NameNode。如果是上图中的高可用,那么有两个NameNode,一主一备,分别对应一个BpServiceActor。所以遍历offerService其实就是遍历整个集群的每个federation中的每个NameNode节点。11.开始遍历(当前类:BpOfferService)12.线程启动(当前类:BPServiceActor)已经是Thread的一个方法,所以可以看出其实是一个线程。那么我们应该看看这个类的run方法。13.线程的运行内容run方法前半部分是向NameNode注册,后半部分是发送心跳14.发送心跳,可以看到这是一个while循环,每一次在awhile(dnConf.heartBeatInterval=3seconds)会执行一次可以看到DataNode的心跳是一个周期性检测机制,每3s向所有NameNode发送一次心跳。15、再次点击,已经是NameNode的proxy代理方法了。因为是rpc通信,所以此时DataNode是client,NameNode是server。这时候就要看NameNodeRpcServer这个方法了,具体的实现就在这个方法中。16.查看服务器的处理。这个时候我们先不看NameNodeRpcServer类中这个方法的具体细节(其实它也很重要)。基本上就是将DataNode心跳包的基本信息(比如本节点的存储容量信息等)更新到NameNode的相应结构中。并更新上次心跳时间,以判断下次DataNode心跳是否超时。其实心跳就是这么简单。最后,NameNode会在心跳响应中告诉DataNode要做什么,比如将本节点的block备份到其他节点。也就是说,NameNode本身并不与DataNode通信,而是在心跳消息中告诉DataNode该做什么。3、总结这次浏览DataNode的代码,知道了DataNode的心跳是DataNode在后台启动一个线程,定时向整个集群中的所有NameNode发送心跳信息。NameNode会在心跳响应信息中告诉DataNode这次要做什么。某物。
