主节点和从节点之间的通信是通过心跳机制实现的,如NameNode与DataNode之间,JobTracker和TaskTracker之间。所谓“心跳”是一种形象化描述,指的是持续的按照一定频率在运行,类似于心脏在永无休止的跳动。
图7-6指的是dataNode向NameNode发送心跳的周期是3秒。
图7-6
当长时间没有发送心跳时,NameNode就判断DataNode的连接已经中断,不能继续工作了,就把他定性为”dead node”。NameNode会检查dead node中的副本数据,复制到其他的data node中。
我们现在来看一下他们之间通过心跳是如何实现通信的。
通过前面的RPC机制介绍,我们知道NameNode与DataNode直接的通信是通过DataNodeProtocol接口实现的。如图7-7所示。
图7-7
该接口的实现类是NameNode,是由DataNode调用的。下面我们就来分析一下他们之间是如何通信的。
先看一下DataNode中的代码,如图7-8所示。
图7-8
该方法是DataNode中非常重要的方法,该方法在系统运行时会进入一个死循环中,定期的调用方法访问NameNode,访问周期见第963行代码,这里的变量heatBeatInterval是从配置文件读取的,如图7-9所示,默认值是3000毫秒,也就说循环间隔不低于3秒钟。快过频繁的运行会增加系统的负载。
那么,当进入if条件语句时,就会执行第972行的代码。这里就是通过namenode调用其sendHearbeat方法。这里的namenode其实是DataNode获得的NameNode实例的代理对象,如图7-10所示。DataNode与NameNode的通信是通过DataNodeProtocol接口实现的。那么,我们下面重点看一下调用的sendHeartbeat方法,如图7-11。
图7-9
图7-10
图7-11
在图7-11中,sendHeartbeat方法的原型定义位于DataNodeProtocol接口的定义中。该传递的第一个形参是包含DataNode注册信息的类,包含DataNode的唯一标示、名称、版本、ipc端口等信息,这些信息可以让NameNode把这个DataNode与其他DataNode区分开。第二、三、四个形参表示当前DataNode上面的容量空间、使用量、剩余量。DataNode把这些信息告诉NameNode后,供NameNode做决策。
还要注意,该方法有返回值,是一个DatanodeCommand数组。也就是说NameNode根据DataNode送来的信息做出决策,并把这些决策封装为DatanodeCommand,发送回DataNode。DataNode拿到NameNode送来的命令后,就要进行处理,见代码第980行。
从上面的分析可以看出,所有的DataNode是通过不断的死循环来向NameNode发送自身状况信息,NameNode在拿到所有DataNode的汇报信息后,综合权衡各种情况,然后向DataNode发回命令。这正是前面分析的RPC机制的客户机与服务器关系的体现。
MapReduce的计算机制是通过一个JobTracker和很多的TaskTracker之间的协作完成的。JobTracker作为管理端,是负责接收用户的作业请求,然后分配秩序任务给TaskTracker去执行的。在TaskTracker执行过程中,通过心跳机制会不断的向JobTracker汇报自己的执行情况,供JobTracker做出决策。下面分析一下心跳的过程。
二者的心跳通信是通过接口InterTrackerProtocol实现的,如图7-12所示。
图7-12
该接口的实现类是JobTracker,是被TaskTracker调用的。下面我们看一下TaskTracker是如何调用的。TaskTracker会调用接口的heartbeat方法,如图7-13所示。
图7-13
该方法的形参有5个。第一个形参是TaskTrackerStatus最重要,包括TaskTracker的通信端口、最多运行Map任务数、最多运行Reduce任务数、失败任务数等。目的是给JobTracker提供足够的信息做出决策。JobTracker在综合了所有TaskTracker提交的各种状态报告后,会对不同TaskTracker做出决策,通过返回值HeartbeatResponse实现的,该返回值中包含对TaskTracker的各种指示,具体信息如图7-14所示。
图7-14
在图7-14中,TaskTracker发送心跳请求,接收到JobTracker发送回来的HeartbeatResponse对象。该对象中含有新的任务,TaskTracker就需要处理新的任务了。这就是心跳机制主要做的事情。
那么,什么情况下TaskTracker可以接受新任务哪?如图7-15所示。
图7-15
从图7-15中可以看到,是否有能力接受新任务要看几个参数的值。分别是maxMapSlots、maxReduceSlots、acceptNewTasks。前两者相当于map任务、reduce任务执行最大限制数。如果超过这个数,那么就不再接受新的任务。默认值,二者都是2。参数acceptNewTasks的取值,取决于本地文件系统(linux系统)的剩余空间。如果本地文件系统还有剩余磁盘空间,足够任务运行,那么改值就是true。否则,就是false。默认情况下,只要磁盘有剩余空间,acceptNewTasks的值就是true。
以上就是对MapReduce的心跳机制的简单分析。通过上面的分析,我们看到只要TaskTracker条件允许,就不断的接受JobTracker分配的任务。这就保证了整个作业的正常运行。