心跳机制通过定期向对方发送请求方式用于检测客户端或者服务端是否存活的一种机制,常见的心跳检测有两种:
socket 套接字SO_KEEPALIVE
本身带有的心跳机制,定期向对方发送心跳包,对方在收到心跳包后会自动回复;
应用自身实现心跳机制,同样也是使用定期发送请求
的方式
Flink中ResourceManager、JobMaster、TaskExecutor三者之间存在相互检测的心跳机制,ResourceManager会主动发送请求探测JobMaster、TaskExecutor是否存活,JobMaster也会主动发送请求探测TaskExecutor是否存活,以便进行任务重启或者失败处理。
Flink中心跳机制主要由以下几个类(接口)协作完成:
HeartbeatTarget
接口,表示监控目标,包含两个方法,requestHeartbeat
发送心跳请求,receiveHeartbeat
接受心跳请求;
HeartbeatManager接口,继承了HeartbeatTarget接口,心跳管理者,用于start/stop 监控对象;
HeartbeatManagerImpl类,实现了HeartbeatManager接口,其内部包含一个实现了Runnable接口的HeartbeatMonitor静态内部类,它包含了心跳目标HeartbeatTarget以及其状态,如果超时就会调用HeartbeatListener心跳监听者进行相应的处理,HeartbeatManagerImpl所处位置可以理解为client,存在于JobMaster与TaskExecutor中;
HeartbeatManagerSenderImpl类,继承 HeartbeatManagerImpl类,用于周期发送心跳请求,所处位置可以理解为server, 存在于JobMaster、ResourceManager中。
以JobMaster与TaskExecutor之间的心跳检测为例,看下其具体的请求流程。
一、JobMaster在启动过程中会调用HeartbeatServices.createHeartbeatManagerSender
方法创建一个HeartbeatManagerSenderImpl对象taskManagerHeartbeatManager,会反复启动一个定时器,定时扫描需要探测的对象并且发送心跳请求
private void startHeartbeatServices() {
// 创建 HeartbeatManagerSenderImpl
taskManagerHeartbeatManager = heartbeatServices.createHeartbeatManagerSender(
resourceId,
new TaskManagerHeartbeatListener(),
getMainThreadExecutor(),
log);
resourceManagerHeartbeatManager = heartbeatServices.createHeartbeatManager(
resourceId,
new ResourceManagerHeartbeatListener(),
getMainThreadExecutor(),
log);
}
二、 JobMaster在执行任务部署时会向ResourceManager申请slot资源,ResourceManager在向yarn申请到资源后会启动TaskExecutor进程,在TaskExecutor启动过程中会调用HeartbeatServices.createHeartbeatManager方法创建一个HeartbeatManagerImpl对象jobManagerHeartbeatManager
private HeartbeatManager<Void, TaskExecutorHeartbeatPayload> createResourceManagerHeartbeatManager(HeartbeatServices heartbeatServices, ResourceID resourceId) {
return heartbeatServices.createHeartbeatManager(
resourceId,
new ResourceManagerHeartbeatListener(),
getMainThreadExecutor(),
log);
}
private HeartbeatManager<AllocatedSlotReport, AccumulatorReport> createJobManagerHeartbeatManager(HeartbeatServices heartbeatServices, ResourceID resourceId) {
return heartbeatServices.createHeartbeatManager(
resourceId,
new JobManagerHeartbeatListener(),
getMainThreadExecutor(),
log);
}
一、在启动TaskExecutor之后,会向其申请slot,调用requestSlot方法,在这个过程中会向JobMaster注册自身信息,通过rpc调用其registerTaskManager方法;
二、JobMaster在收到rpc请求后调用registerTaskManager方法,会通过taskManagerHeartbeatManager.monitorTarget方法将其添加到监控目标中,monitorTarget方法会将监控对象HeartbeatTarget封装在HeartbeatMonitor里面,初始化会调用resetHeartbeatTimeout重置心跳超时时间,启动一个超时时间heartbeatTimeout的定时器;
三、在注册完之后TaskManager之后,TaskExecutor会收到一个注册成功的请求,会调用其establishJobManagerConnection方法,用于与JobMaster建立连接,会向jobManagerHeartbeatManager添加监控目标,同样会封装成为一个HeartbeatMonitor并且启动一个定时器;
由此可见JobMaster与TaskExecutor是双向检测的,在heartbeatTimeout时间内没有收到心跳信息就会认为已超时,JobMaster认为TaskExecutor出现timeout 会调用TaskManagerHeartbeatListener的notifyHeartbeatTimeout方法,TaskExecutor任务JobMaster出现timeout会调用JobManagerHeartbeatListener的notifyHeartbeatTimeout方法。但是需要明确心跳的主动请求者是JobMaster。
一、在TaskExecutor注册到JobMaster中之后就代表了心跳机制开始,在taskManagerHeartbeatManager中也就是HeartbeatManagerSenderImpl中定时schedual调用HeartbeatTarget.requestHeartbeat,最后会通过rpc方式调用taskManager的heartbeatFromJobManager方法;
二、TaskExecutor收到heartbeatFromJobManager的rpc请求之后,会调用jobManagerHeartbeatManager也就是HeartbeatManagerImpl的requestHeartbeat方法,在这个过程中有两个处理步骤:
调用对应HeartbeatMonitor的reportHeartbeat方法,cancelTimeout取消注册时候的超时定时任务,并且注册下一个超时检测futureTimeout;
调用monitorTarget的receiveHeartbeat方法,也就是会通过rpc调用JobMaster的heartbeatFromTaskManager方法返回一些负载信息;
三、JobMaster在接收到rpc请求后调用其heartbeatFromTaskManager方法,会调用taskManagerHeartbeatManager的receiveHeartbeat方法,在这个过程中同样有两个处理步骤:
调用对应HeartbeatMonitor的reportHeartbeat方法,cancelTimeout取消注册时候的超时定时任务,并且注册下一个超时检测futureTimeout;
调用TaskManagerHeartbeatListener的reportPayload方法,上报收到TaskExecutor的负载信息
至此一次完整心跳过程已经完成,会根据heartbeatInterval执行下一次心跳。