阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

集群应用之Heartbeat

169次阅读
没有评论

共计 10400 个字符,预计需要花费 26 分钟才能阅读完成。

[首卷话]我们用到的集群系统主要就 2 种:

高可用 (High Availability)HA 集群, 使用 Heartbeat 实现; 也会称为”双机热备”,“双机互备”,“双机”。
负载均衡群集 (Load Balance Cluster),使用 Linux Virtual Server(LVS) 实现;

heartbeat(Linux-HA)的工作原理:heartbeat 最核心的包括两个部分,心跳监测部分和资源接管部分,心跳监测可以通过网络链路和串口进行,而且支持冗 余链路,它们之间相互发送报文来告诉对方自己当前的状态,如果在指定的时间内未受到对方发送的报文,那么就认为对方失效,这时需启动资源接管模块来接管运 行在对方主机上的资源或者服务。

LVS 是 Linux Virtual Server 的简写,意即 Linux 虚拟服务器,是一个虚拟的服务器集群系统。本项目在 1998 年 5 月由章文嵩博士成立,是中国国内最早出现的自由软件项目之一。章文嵩博士目前工作于中国国家并行与分布式处理重点实验室,主要从事集群技术、操作系统、对象存储与数据库的研究。

目标

使用集群技术和 Linux 操作系统实现一个高性能、高可用的服务器.
很好的可伸缩性(Scalability)
很好的可靠性(Reliability)
很好的可管理性(Manageability)。

 

1.Heartbeat 项目是 Linux-HA 工程的一个组成部分,它实现了一个高可用集群系统。心跳服务和集群通信是高可用集群的两个关键组件,在 Heartbeat 项目里,由 heartbeat 模块实现了这两个功能。随着 Linux 在关键行业应用的逐渐增多,它必将提供一些原来由 IBM 和 SUN 这样的大型商业公司所提供的服务,这些商业公司所提供的服务都有一个关键特性,就是高可用集群。下面描述了 heartbeat 模块的可靠消息通信机制,并对其实现原理做了一些介绍。

 

2 原理

heartbeat(Linux-HA)的工作原理:heartbeat 最核心的包括两个部分,心跳监测部分和资源接管部分,心跳监测可以通过网络链路和串口进行,而且支持冗 余链路,它们之间相互发送报文来告诉对方自己当前的状态,如果在指定的时间内未收到对方发送的报文,那么就认为对方失效,这时需启动资源接管模块来接管运 行在对方主机上的资源或者服务。

3 高可用集群

高可用集群是指一组通过硬件和软件连接起来的独立计算机,它们在用户面前表现为一个单一系统,在这样的一组计算机系统内部的一个或者多个节点停止工作,服务会从故障节点切换到正常工作的节点上运行,不会引起服务中断。从这个定义可以看出,集群必须检测节点和服务何时失效,何时恢复为可用。这个任务通常由一组被称为“心跳”的代码完成。在 Linux-HA 里这个功能由一个叫做 heartbeat 的程序完成。

4 消息通信模型

Heartbeat 包括以下几个组件:
heartbeat – 节点间通信校验模块
CRM – 集群资源管理模块
CCM – 维护集群成员的一致性
LRM – 本地资源管理模块
StonithDaemon – 提供节点重启服务
logd – 非阻塞的日志记录
apphbd – 提供应用程序级的看门狗计时器
Recovery Manager – 应用故障恢复
底层结构–包括插件接口、进程间通信等
CTS – 集群测试系统,集群压力测试
这里主要分析的是 Heartbeat 的集群通信机制,所以这里主要关注的是 heartbeat 模块。
heartbeat 模块由以下几个进程构成:
master 进程(masterprocess)
FIFO 子进程(fifochild)
read 子进程(readchild)
write 子进程(writechild)
在 heartbeat 里每一条通信通道对应于一个 write 子进程和一个 read 子进程,假设 n 是通信通道数,p 为 heartbeat 模块的进程数,则 p、n 有以下关系:
p=2*n+2
在 heartbeat 里,master 进程把自己的数据或者是客户端发送来的数据,通过 IPC 发送到 write 子进程,write 子进程把数据发送到网络;同时 read 子进程从网络读取数据,通过 IPC 发送到 master 进程,由 master 进程处理或者由 master 进程转发给其客户端处理。
Heartbeat 启动的时候,由 master 进程来启动 FIFO 子进程、write 子进程和 read 子进程,最后再启动 client 进程。
5 可靠消息通信

Heartbeat 通过插件技术实现了集群间的串口、多播、广播和组播通信,在配置的时候可以根据通信媒介选择采用的通信协议,heartbeat 启动的时候检查这些媒介是否存在,如果存在则加载相应的通信模块。这样开发人员可以很方便地添加新的通信模块,比如添加红外线通信模块。
对于高可用集群系统,如果集群间的通信不可靠,那么很明显集群本身也不可靠。Heartbeat 采用 UDP 协议和串口进行通信,它们本身是不可靠的,可靠性必须由上层应用来提供。那么怎样保证消息传递的可靠性呢?
Heartbeat 通过冗余通信通道和消息重传机制来保证通信的可靠性。Heartbeat 检测主通信链路工作状态的同时也检测备用通信链路状态,并把这一状态报告给系统管理员,这样可以大大减少因为多重失效引起的集群故障不能恢复。例如,某个工作人员不小心拨下了一个备份通信链路,一两个月以后主通信链路也失效了,系统就不能再进行通信了。通过报告备份通信链路的工作状态和主通信链路的状态,可以完全避免这种情况。因为这样在主通信链路失效以前,就可以检测到备份工作链路失效,从而在主通信链路失效前修复备份通信链路。
Heartbeat 通过实现不同的通信子系统,从而避免了某一通信子系统失效而引起的通信失效。最典型的就是采用以太网和串口相结合的通信方式。这被认为是当前的最好实践,有几个理由可以使我们选择采用串口通信:
(1)IP 通信子系统的失效不太可能影响到串口子系统。
(2)串口不需要复杂的外部设备和电源。
(3)串口设备简单,在实践中非常可靠。
(4)串口可以非常容易地专用于集群通信。
(5)串口的直连线因为偶然性掉线事件很少。
不管是采用串口还是以太网 IP 协议进行通信,heartbeat 都实现了一套消息重传协议,保证消息包的可靠传递。实现消息包重传有两种协议,一种是发送者发起,另一种是接收者发起。
对于发送者发起协议,一般情况下接收者会发送一个消息包的确认。发送者维护一个计时器,并在计时器到时的时候重传那些还没有收到确认的消息包。这种方法容易引起发送者溢出,因为每一台机器的每一个消息包都需要确认,使得要发送的消息包成倍增长。这种现像被称为发送者(或者 ACK)内爆(implosion)。
对于接收者发起协议,采用这种协议通信双方的接收者通过序列号负责进行错误检测。当检测到消息包丢失时,接收者请求发送者重传消息包。采用这种方法,如果消息包没有被送达任何一个接收者,那么发送者容易因 NACK 溢出,因为每个接收者都会向发送者发送一个重传请求,这会引起发送者的负载过高。这种现像被称为 NACK 内爆(implosion)。
Heartbeat 实现的是接收者发起协议的一个变种,它采用计时器来限制过多的重传,在计时器时间内限制接收者请求重传消息包的次数,这样发送者重传消息包的次数也被相应的限制了,从而严格的限制了 NACK 内爆。

更多详情见请继续阅读下一页的精彩内容:http://www.linuxidc.com/Linux/2013-11/92911p2.htm

推荐阅读

Linux 高可用(HA)集群之 heartbeat 基于 crm 进行资源管理详解 http://www.linuxidc.com/Linux/2013-08/89167.htm

Heartbeat+httpd+NFS 实现高可用的 Web 服务器 http://www.linuxidc.com/Linux/2013-08/88520.htm

Linux 高可用(HA)集群之 Heartbeat 详解 http://www.linuxidc.com/Linux/2013-08/88521.htm

Linux 高可用性方案之 Heartbeat 的 CRM 配置 http://www.linuxidc.com/Linux/2012-05/60838.htm

高可用集群 Heartbeat v1 实例 http://www.linuxidc.com/Linux/2013-09/90757.htm

6 可靠消息通信的实现

一般集群通信有两类消息包,一类是心跳消息包,这类消息包通告集群内节点的存活情况;另一类是控制消息包,这类消息包负责集群的节点和资源管理。heartbeat 把心跳消息包看成是控制消息包的一个特例,采用相同的通信通道进行发送,这使得协议的实现简单化,而且很有效,并把相应的代码限制在几百行之内。
在 heartbeat 里,一切流向网络的数据都由 master 进程发送到 write 子进程进行发送。master 进程调用 send_cluster_msg()函数把消息发送到所有的 write 子进程。下面通过一些代码片段看看 heartbeat 是怎么发送消息的。在介绍代码之前先介绍相关的重要数据结构
Heartbeat 的消息包数据结构 structha_msg{intnfields;/* 消息包数据域的个数 */intnalloc;/* 己分配的内存块个数 */char**names;/* 消息包数据域的名称 */size_t*nlens;/* 各个数据域称的长度 */void**values;/* 与数据域名称对应的数据值 */size_t*vlens;/* 各个数据域对应的数据值的长度 */int*types;/* 消息包的类型 */};
Heartbeat 的历史消息队列 structmsg_xmit_hist{structha_msg*msgq[MAXMSGHIST];/* 历史消息队列 */seqno_tseqnos[MAXMSGHIST];/* 历史消息序列号 */longclock_tlastrexmit[MAXMSGHIST];/* 上一次重传的时间 */intlastmsg;/* 上一次重传到的消息序列号 */seqno_thiseq;/* 最大消息序列号 */seqno_tlowseq;/* 最小消息序列号 */seqno_tackseq;/* 确认了的消息序列号 */structnode_info*lowest_acknode;/* 确认的节点 */};
代码所属文件 heartbeat/heartbeat.c
intsend_cluster_msg(structha_msg*msg){…pid_tourpid=getpid();…
if(ourpid==processes[0]){/* 来自 master 进程的消息 *//* 添加控制信息,包括源节点名,源节点全局标识符,序列号,代数,时间等 */if((msg=add_control_msg_fields(msg))!=NULL){/* 可靠的多播消息包传递 */rc=process_outbound_packet(&msghist,msg);}}else{/* 来自 client 进程的消息 */intffd=-1;char*smsg=NULL;

/* 发送到 FIFO 进程 */
if((smsg=msg2wirefmt_noac(msg,&len))==NULL){…}elseif((ffd=open(FIFONAME,O_WRONLY|O_APPEND))nodename)==0);
/* 把消息转换成字符串 */smsg=msg2wirefmt(msg,&len);

if(cseq!=NULL){/* 存放到历史消息队列里,通过序列号记录,如果需要,则进行重传 */add2_xmit_hist(hist,msg,seqno);}

/* 通过 write 子进程发送到所有的网络接口上 */send_to_all_media(smsg,len);

returnHA_OK;}
add2_xmit_hist()函数把发送的消息发到一个历史消息队列里去,队列的最大长度为 200。如果接收者请求重传消息,发送者通过序列号在该队列里查找要重传的消息,如果找到则进行重传。下面是相关代码。
staticvoidadd2_xmit_hist(structmsg_xmit_hist*hist,structha_msg*msg,seqno_tseq){intslot;structha_msg*slotmsg;

/* 查找队列里消息存放的位置 */slot=hist->lastmsg+1;if(slot>=MAXMSGHIST){/* 到达队尾,从头开始。在这里实现循环队列 */slot=0;}
hist->hiseq=seq;slotmsg=hist->msgq[slot];
/* 删除队列中找到的位置上的旧消息 */if(slotmsg!=NULL){hist->lowseq=hist->seqnos[slot];hist->msgq[slot]=NULL;if(!ha_is_allocated(slotmsg)){…}else{ha_msg_del(slotmsg);}}
hist->msgq[slot]=msg;hist->seqnos[slot]=seq;hist->lastrexmit[slot]=0L;hist->lastmsg=slot;
if(enable_flow_control&&live_node_count>1&&(hist->hiseq–hist->lowseq)>((MAXMSGHIST*3)/4)){/* 消息队列长度大于告警长度,记录日志 */…}if(enable_flow_control&&hist->hiseq–hist->ackseq>FLOWCONTROL_LIMIT){/* 消息队列的长度大于流控限制长度 */if(live_node_counthiseq–(FLOWCONTROL_LIMIT–1));all_clients_resume();}else{/*client 进程发送消息过快,暂停所有的 client 进程 */all_clients_pause();hist_display(hist);}}
}
当发送者收到接收者的重传请求后,通过回调函数 HBDoMsg_T_REXMIT()函数调用 process_rexmit()函数进行消息重传。
#defineMAX_REXMIT_BATCH50/* 每次最多重传的消息包数 */
staticvoidprocess_rexmit(structmsg_xmit_hist*hist,structha_msg*msg){constchar*cfseq;constchar*clseq;seqno_tfseq=0;seqno_tlseq=0;seqno_tthisseq;intfirstslot=hist->lastmsg–1;intrexmit_pkt_count=0;constchar*fromnodename=ha_msg_value(msg,F_ORIG);structnode_info*fromnode=NULL;

/* 取得要重传的消息包的起始序列号 */if((cfseq=ha_msg_value(msg,F_FIRSTSEQ))==NULL||(clseq=ha_msg_value(msg,F_LASTSEQ))==NULL||(fseq=atoi(cfseq))lseq){/* 无效序列号,记录日志信息 */…}

/* 重传丢失的消息包 */for(thisseq=fseq;thisseqtrack.ackseq){/* 该消息包已经被确认过,可以忽略掉 */continue;}if(thisseqlowseq){/* 序列号小于消息队列里的最小序列号,该消息己不存在于历史消息队列中 *//* 告知对方,不重传该消息 */nak_rexmit(hist,thisseq,fromnodename,“seqnotoolow”);continue;}if(thisseq>hist->hiseq){/* 序列号大于消息队列中最大序列号 */…continue;}
for(msgslot=firstslot;!foundit&&msgslot!=(firstslot+1);–msgslot){char*smsg;longclock_tnow=time_longclock();longclock_tlast_rexmit;size_tlen;

/* 重传上一次重传剩下的消息包 */last_rexmit=hist->lastrexmit[msgslot];
if(cmp_longclock(last_rexmit,zero_longclock)!=0&&longclockto_ms(sub_longclock(now,last_rexmit))<(ACCEPT_REXMIT_REQ_MS)){gotoNextReXmit;}
/* 一次不能发送太多数据包,如果数据包太多的话,可能会引起串口溢出 */++rexm

[首卷话]我们用到的集群系统主要就 2 种:

高可用 (High Availability)HA 集群, 使用 Heartbeat 实现; 也会称为”双机热备”,“双机互备”,“双机”。
负载均衡群集 (Load Balance Cluster),使用 Linux Virtual Server(LVS) 实现;

heartbeat(Linux-HA)的工作原理:heartbeat 最核心的包括两个部分,心跳监测部分和资源接管部分,心跳监测可以通过网络链路和串口进行,而且支持冗 余链路,它们之间相互发送报文来告诉对方自己当前的状态,如果在指定的时间内未受到对方发送的报文,那么就认为对方失效,这时需启动资源接管模块来接管运 行在对方主机上的资源或者服务。

LVS 是 Linux Virtual Server 的简写,意即 Linux 虚拟服务器,是一个虚拟的服务器集群系统。本项目在 1998 年 5 月由章文嵩博士成立,是中国国内最早出现的自由软件项目之一。章文嵩博士目前工作于中国国家并行与分布式处理重点实验室,主要从事集群技术、操作系统、对象存储与数据库的研究。

目标

使用集群技术和 Linux 操作系统实现一个高性能、高可用的服务器.
很好的可伸缩性(Scalability)
很好的可靠性(Reliability)
很好的可管理性(Manageability)。

 

1.Heartbeat 项目是 Linux-HA 工程的一个组成部分,它实现了一个高可用集群系统。心跳服务和集群通信是高可用集群的两个关键组件,在 Heartbeat 项目里,由 heartbeat 模块实现了这两个功能。随着 Linux 在关键行业应用的逐渐增多,它必将提供一些原来由 IBM 和 SUN 这样的大型商业公司所提供的服务,这些商业公司所提供的服务都有一个关键特性,就是高可用集群。下面描述了 heartbeat 模块的可靠消息通信机制,并对其实现原理做了一些介绍。

 

2 原理

heartbeat(Linux-HA)的工作原理:heartbeat 最核心的包括两个部分,心跳监测部分和资源接管部分,心跳监测可以通过网络链路和串口进行,而且支持冗 余链路,它们之间相互发送报文来告诉对方自己当前的状态,如果在指定的时间内未收到对方发送的报文,那么就认为对方失效,这时需启动资源接管模块来接管运 行在对方主机上的资源或者服务。

3 高可用集群

高可用集群是指一组通过硬件和软件连接起来的独立计算机,它们在用户面前表现为一个单一系统,在这样的一组计算机系统内部的一个或者多个节点停止工作,服务会从故障节点切换到正常工作的节点上运行,不会引起服务中断。从这个定义可以看出,集群必须检测节点和服务何时失效,何时恢复为可用。这个任务通常由一组被称为“心跳”的代码完成。在 Linux-HA 里这个功能由一个叫做 heartbeat 的程序完成。

4 消息通信模型

Heartbeat 包括以下几个组件:
heartbeat – 节点间通信校验模块
CRM – 集群资源管理模块
CCM – 维护集群成员的一致性
LRM – 本地资源管理模块
StonithDaemon – 提供节点重启服务
logd – 非阻塞的日志记录
apphbd – 提供应用程序级的看门狗计时器
Recovery Manager – 应用故障恢复
底层结构–包括插件接口、进程间通信等
CTS – 集群测试系统,集群压力测试
这里主要分析的是 Heartbeat 的集群通信机制,所以这里主要关注的是 heartbeat 模块。
heartbeat 模块由以下几个进程构成:
master 进程(masterprocess)
FIFO 子进程(fifochild)
read 子进程(readchild)
write 子进程(writechild)
在 heartbeat 里每一条通信通道对应于一个 write 子进程和一个 read 子进程,假设 n 是通信通道数,p 为 heartbeat 模块的进程数,则 p、n 有以下关系:
p=2*n+2
在 heartbeat 里,master 进程把自己的数据或者是客户端发送来的数据,通过 IPC 发送到 write 子进程,write 子进程把数据发送到网络;同时 read 子进程从网络读取数据,通过 IPC 发送到 master 进程,由 master 进程处理或者由 master 进程转发给其客户端处理。
Heartbeat 启动的时候,由 master 进程来启动 FIFO 子进程、write 子进程和 read 子进程,最后再启动 client 进程。
5 可靠消息通信

Heartbeat 通过插件技术实现了集群间的串口、多播、广播和组播通信,在配置的时候可以根据通信媒介选择采用的通信协议,heartbeat 启动的时候检查这些媒介是否存在,如果存在则加载相应的通信模块。这样开发人员可以很方便地添加新的通信模块,比如添加红外线通信模块。
对于高可用集群系统,如果集群间的通信不可靠,那么很明显集群本身也不可靠。Heartbeat 采用 UDP 协议和串口进行通信,它们本身是不可靠的,可靠性必须由上层应用来提供。那么怎样保证消息传递的可靠性呢?
Heartbeat 通过冗余通信通道和消息重传机制来保证通信的可靠性。Heartbeat 检测主通信链路工作状态的同时也检测备用通信链路状态,并把这一状态报告给系统管理员,这样可以大大减少因为多重失效引起的集群故障不能恢复。例如,某个工作人员不小心拨下了一个备份通信链路,一两个月以后主通信链路也失效了,系统就不能再进行通信了。通过报告备份通信链路的工作状态和主通信链路的状态,可以完全避免这种情况。因为这样在主通信链路失效以前,就可以检测到备份工作链路失效,从而在主通信链路失效前修复备份通信链路。
Heartbeat 通过实现不同的通信子系统,从而避免了某一通信子系统失效而引起的通信失效。最典型的就是采用以太网和串口相结合的通信方式。这被认为是当前的最好实践,有几个理由可以使我们选择采用串口通信:
(1)IP 通信子系统的失效不太可能影响到串口子系统。
(2)串口不需要复杂的外部设备和电源。
(3)串口设备简单,在实践中非常可靠。
(4)串口可以非常容易地专用于集群通信。
(5)串口的直连线因为偶然性掉线事件很少。
不管是采用串口还是以太网 IP 协议进行通信,heartbeat 都实现了一套消息重传协议,保证消息包的可靠传递。实现消息包重传有两种协议,一种是发送者发起,另一种是接收者发起。
对于发送者发起协议,一般情况下接收者会发送一个消息包的确认。发送者维护一个计时器,并在计时器到时的时候重传那些还没有收到确认的消息包。这种方法容易引起发送者溢出,因为每一台机器的每一个消息包都需要确认,使得要发送的消息包成倍增长。这种现像被称为发送者(或者 ACK)内爆(implosion)。
对于接收者发起协议,采用这种协议通信双方的接收者通过序列号负责进行错误检测。当检测到消息包丢失时,接收者请求发送者重传消息包。采用这种方法,如果消息包没有被送达任何一个接收者,那么发送者容易因 NACK 溢出,因为每个接收者都会向发送者发送一个重传请求,这会引起发送者的负载过高。这种现像被称为 NACK 内爆(implosion)。
Heartbeat 实现的是接收者发起协议的一个变种,它采用计时器来限制过多的重传,在计时器时间内限制接收者请求重传消息包的次数,这样发送者重传消息包的次数也被相应的限制了,从而严格的限制了 NACK 内爆。

更多详情见请继续阅读下一页的精彩内容:http://www.linuxidc.com/Linux/2013-11/92911p2.htm

推荐阅读

Linux 高可用(HA)集群之 heartbeat 基于 crm 进行资源管理详解 http://www.linuxidc.com/Linux/2013-08/89167.htm

Heartbeat+httpd+NFS 实现高可用的 Web 服务器 http://www.linuxidc.com/Linux/2013-08/88520.htm

Linux 高可用(HA)集群之 Heartbeat 详解 http://www.linuxidc.com/Linux/2013-08/88521.htm

Linux 高可用性方案之 Heartbeat 的 CRM 配置 http://www.linuxidc.com/Linux/2012-05/60838.htm

高可用集群 Heartbeat v1 实例 http://www.linuxidc.com/Linux/2013-09/90757.htm

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-20发表,共计10400字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中