引言:
心跳是用于OSD节点间检测对方是否故障的,以便及时发现故障节点进入相应的故障处理流程。故障检测需要在故障的发现时间和心跳带来的负载之间做权衡,如果心跳频率太高则过多的心跳报文会影响系统性能,如果心跳频率过低则会延长发现故障节点的时间,从而影响系统的可用性。
两种心跳消息机制:
1、OSD之间的心跳检测
属于同一个pg的OSD我们称之为伙伴OSD,他们会相互发送PING\PONG信息,并且记录发送和接收的时间。OSD在cron中发现有伙伴OSD相应超时后,会将其加入failure_queue队列,等待后续汇报。
在大规模部署的场景中,如果任意两个OSD节点间都建立心跳连接将带来巨大的负担。尤其,当新加入一个OSD节点时这个负担就会几倍地增加。Ceph中每个OSD只和以下两类节点建立心跳连接:一类是同个PG下的OSD节点之间,因为属于同个PG的OSD节点会保存同份数据的副本,
如若出现故障则会直接影响数据的可用性。另一类是OSD的左右两个相邻的节点,这两个节点同自己物理上存在比较紧密的联系,例如可能连接在同台交换机。另外,如果建立心跳的Peer数目少于osd_heartbeat_min_peers,那么OSD会继续同离他较近的几个OSD建立心跳连接。
OSD节点会监听public、cluster、front和back四个端口,其中front和back两个端口都是用于心跳的,cluster端口用来监听来自OSD Peer的连接,public用来监听来自Monitor和Client的连接。如果启动OSD时没有提供back的IP地址,
则back使用cluster的IP地址;而front不单独提供IP地址,直接使用public的IP地址。另外,OSD单独创建了一个名为hbclient的Messenger,作为心跳的客户端,单独用来建立连接发送心跳报文。心跳报文优先发送给back连接。
OSD使用T_Heartbeat线程定时向Peer OSDs发送心跳报文,发送报文的时间间隔在0.5~6.5之间,由osd_heartbeat_interval配置选项决定。心跳报文会同时向Peer OSD的front和back端口发送。心跳报文分两种类型一种是Ping类型,另一种是Reply类型。Ping类型的报文是OSD主动发送给Peer OSD的报文,而Reply是Peer OSD回应给自己的报文。两种类型的心跳报文都携带时间戳,但它们的时间戳代表的含义不一样。Ping类型报文的时间戳是发送报文时的时间,而Reply类型报文的时间戳是从Ping报文中读取出来的,不是代表它自己的发送时间而是代表它对应的Ping报文的发送时间。OSD接收到Reply报文时将记录报文的时间戳,并以此来判断是否超时。
对每个Peer节点,如果其最近的应答的时间(最近的Reply报文的时间戳)位于cutoff之前(即超时grace秒),则将其加入到failure_queue队列。OSD会定时向Monitor汇报自己的状态,在汇报状态时将failure_queue队列中Peer发送给Monitor,并将失败信息加入到failure_pending队列,然后将其从failure_quue移除。
Monitor收到OSD对其伙伴OSD的汇报后,并没有马上将目标OSD下线,而是周期性的等待几个条件:1,目标OSD的失效时间大于通过固定量osd_heartbeat_grace和历史网络条件动态确定的阈值;2,来自不同主机的汇报达到mon_osd_min_down_reporters。3,满足前两个条件前失效汇报没有被源OSD取消,如果满足上述条件,则MON会将该OSD下线,标记为Down状态。如果Monitor将Peer OSD标记为Down状态,那么将更新OSD MAP,OSD接收到OSD Map更新的消息后,断开和Peer OSD的心跳连接。
如果在向Monitor报告故障之后但在接收到OSD Down消息之前,再次接收到Peer OSD对心跳报文的回应,则将Peer OSD从failure_queue队列和failure_pending队列中移除,并通知Monitor该节点依旧存活着,告知Monitor取消之前的失效报告。
发送心跳检测的周期:6s osd_heartbeat_interval
判断无反馈消息返回的时间:20s,osd_heartbeat_grace, 如果20s没有收到回复,则判断对方已经下线。
2、 OSD到MON的心跳
OSD当有pg状态改变等事件发生,或达到一定的时间间隔后,会向Monitor发送MSG_PGSTATS消息,这里称之为OSD到Monitor的心跳。
Monitor收到消息,回复MSG_PGSTATSACK,并记录心跳时间到last_osd_report。
Monitor周期性的检查所有OSD的last_osd_report,发现失效的节点,并标记为Down。
可以看出,Ceph中可以通过伙伴OSD汇报失效节点和Monitor统计来自OSD的心跳两种方式发现OSD节点失效。
其中MON统计来自OSD的心跳,可以看做是故障检测的一种保险措施,所以周期较长。
默认参数
mon_osd_report_timeout(900):多久没有收到osd的汇报,Monitor会将其标记为Down;
osd_mon_report_interval_max(600):OSD最久多长时间向Monitor汇报一次;
osd_mon_report_interval_min(5):OSD向Monitor汇报的最小时间间隔
总结:
发送心跳消息
void OSD::heartbeat()
void OSD::handle_osd_ping(MOSDPing *m)
处理心跳和心跳响应消息
每一个heartbeatinfo中记录了一个目标osd的链接信息(connection)
在OSD初始化的时候,会单独创建一个线程用于心跳检测
int OSD::init()
heartbeat_thread.create("osd_srv_heartbt");
heartbeat_check 心跳消息检测函数
参考及引用文献:
https://www.jianshu.com/p/9191a70d37e6
https://www.cnblogs.com/shanno/p/4017641.html




