- 论坛徽章:
- 0
|
Heartbeat项目是Linux-HA工程的一个组成部分,它实现了一个高可用集群系统。心跳服务和集群通信是高可用集群的两个关键组件,在Heartbeat项目里,由heartbeat模块实现了这两个功能。
目前Heartbeat已经发展到了2.1.2版本,最新版本可以在自行下载安装。建议安装源码的,无论在rhel还是lfs构建的系统上都可以成功安装。有几个以来的软件包只要根据提示依次找出依赖的包进行安装即可。
http://www.linux-ha.org/download/heartbeat-2.1.2.tar.gz 。
高可用集群是指一组通过硬件和软件连接起来的独立计算机,它们在用户面前表现为一个单一系统,在这样的一组计算机系统内部的一个或者多个节点停止工作,服务会从故障节点切换到正常工作的节点上运行,不会引起服务中断。从这个定义可以看
出,集群必须检测节点和服务何时失效,何时恢复为可用。这个任务通常由一组被称为“心跳”的代码完成。在Linux-HA里这个功能由一个叫做 heartbeat的程序完成。
Heartbeat消息通信模型
Heartbeat包括以下几个组件:
heartbeat – 节点间通信校验模块
CRM - 集群资源管理模块
CCM - 维护集群成员的一致性
LRM - 本地资源管理模块
Stonith Daemon - 提供节点重启服务
logd - 非阻塞的日志记录
apphbd - 提供应用程序级的看门狗计时器
Recovery Manager - 应用故障恢复
底层结构–包括插件接口、进程间通信等
CTS – 集群测试系统,集群压力测试
这里主要分析的是Heartbeat的集群通信机制,所以这里主要关注的是heartbeat模块。heartbeat模块由以下几个进程构成:
master进程(master process)
FIFO子进程(fifo child)
read子进程(read child)
write子进程(write child)
Heartbeat启动的时候,由master进程来启动FIFO子进程、write子进程和read子进程,最后再启动client进程。
Heartbeat通过插件技术实现了集群间的串口、多播、广播和组播通信,在 配置的时候可以根据通信媒介选择采用的通信协议,heartbeat启动的时候检查这些媒介是否存在,如果存在则加载相应的通信模块。这样开发人员可以很 方便地添加新的通信模块,比如添加红外线通信模块。
对于高可用集群系统,如果集群间的通信不可靠,那么很明显集群本身也不可靠。Heartbeat采用UDP协议和串口进行通信,它们本身是不可靠的,可靠性必须由上层应用来提供。那么怎样保证消息传递的可靠性呢?
Heartbeat通过冗余通信通道和消息重传机制来保证通信的可靠性。 Heartbeat检
测主通信链路工作状态的同时也检测备用通信链路状态,并把这一状态报告给系统管理员,这样可以大大减少因为多重失效引起的集群故障不 能恢复。例如,某个工作人员不小心拨下了一个备份通信链路,一两个月以后主通信链路也失效了,系统就不能再进行通信了。通过报告备份通信链路的工作状态和
主通信链路的状态,可心完全避免这种情况。因为这样在主通信链路失效以前,就可以检测到备份工作链路失效,从而在主通信链路失效前修复备份通信链路。
不管是采用串口还是以太网IP协议进行通信,heartbeat都实现了一套消息重传协议,保证消息包的可靠传递。实现消息包重传有两种协议,一种是发送者发起,另一种是接收者发起。
对于发送者发起协议,一般情况下接收者会发送一个消息包的确认。发送者维护一个计时 器,并在计时器到时的时候重传那些还没有收到确认的消息包。这种方法容易引起发送者溢出,因为每一台机器的每一个消息包都需要确认,使得要发送的消息包成
倍增长。这种现像被称为发送者(或者ACK)内爆(implosion)。
对于接收者发起协议,采用这种协议通信双方的接收者通过序列号负责进行错误检测。 当检测到消息包丢失时,接收者请求发送者重传消息包。采用这种方法,如果消息包没有被送达任何一个接收者,那么发送者容易因NACK溢出,因为每个接收者 都会向发送者发送一个重传请求,这会引起发送者的负载过高。这种现像被称为NACK内爆(implosion)。
Heartbeat实现的是接收者发起协议的一个变种,它采用计时器来限制过多的重传,在计时器时间内限制接收者请求重传消息包的次数,这样发送者重传消息包的次数也被相应的限制了,从而严格的限制了NACK内爆。
可靠消息通信的实现
一般集群通信有两类消息包,一类是心跳消息包,这类消息包通告集群内节点的存活情 况;另一类是控制消息包,这类消息包负责集群的节点和资源管理。heartbeat把心跳消息包看成是控制消息包的一个特例,采用相同的通信通道进行发 送,这使得协议的实现简单化,而且很有效,并把相应的代码限制在几百行之内。
Heartbeat通信结构概述主要分两种:
1.HBcomm 通信层PLUGIN (节点之间的进程通信)
实现主要是在各个媒介的Plugin里,通过PILS动态连接库加载。比如支持多播,单播,串口等通信方式。所有节点间通信PLUGIN模块放在lib/plugins/hbcomm/路径下。
2.Unix Domain Socket (节点内的进程通信)
/include/clplumbing/Ipc.h, IPC抽象层数据结构定义
/lib/clplumbing/ocf_ipc.c, IPC底层抽象实现
/lib/clplumbing/ipcsocket.c, IPC的unix域套接字具体实现
交叉点:
节点间和节点内2种通信方式的交接点在heartbeat.c的read_child(), write_child()等函数中, 在这里实现消息的转发。
Heartbeat API
是基于ipc抽象层的Unix域实现基础上,用于满足heartbeat和client子模块之间的应用层通信需求。:
client_lib.c实现了Heartbeat API 客户端部分。
hb_api.c实现了heartbeat API服务器端部分。
1. client子模块通过FIFO管道把消息发送到FIFO子进程fifo_child。为什么使用FIFO来进行通信呢,应该是有些进程不能很 方便的和Heartbeat主进程建立Unix域IPC通道的关系,比如执行的脚本和集群管理程序, 集群状态查询程序。
2. FIFO子进程通过msgfromstream()从fifo管道收到消息后,利用事先建立好的和Heartbeat之间的IPC通道转发给Heartbeat主进程
3. 主进程判断消息是发给自己的则调用process_msg()进行处理,否则调用send_to_all_media()通过各个媒介的wchan通道发送给write_child子进程。
4. write_child子进程通过ipcmsgfromIPC()从主进程收到消息,调用各个媒介结构hb_media的write函数把消息发送到集群其他节点。
5. 其他节点的read_child子进程通过各个媒介结构hb_media的read函数读到消息后,使用事先和Heartbeat主进程建立的IPC通道发送消息到Heartbeat主进程
6. Heartbeat主进程通过msgfromIPC()收到消息后,调用process_clustermsg()函数进行处理。具体为,如果 是主进程处理的消息调用HBDoMsgCallback进行处理,否则通过newstartha_monitor发送到各个client子进程
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/39370/showart_437403.html |
|