Heartbeat HA高可用软件的一些使用技巧以及资源管理超时问题的分析

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/watermelonbig/article/details/100110900

heartbeat之集群组件

Heartbeat 从3.x开始,架构拆分为heartbeat、pacemaker(资源管理器)、cluster-glue(集群黏合器)几个相互独立的软件,它们可以结合起来工作。

  • heartbeat:负责维护集群节点间的通信以及信息传递。
  • pacemaker:也就是CRM,它是管理HA的控制中心,客户端通过它配置和监控整个集群。Pacemaker在后续发展中使用Corosync作为消息层,和Corosync紧密结合,同时也保留Heartbeat作为可选的消息层。
  • cluster-glue:相当于一个中间件,它将heartbeat和pacmaker关联起来,主要包含LRM和STONITH
  • resource agent:用于控制服务的启动和停止,监控脚本服务的脚本集合;LRM调用这些脚本从而实现资源的启动、停止和重启等。

在逻辑架构中,Heartbeat作为heartbeat软件的通信模块。CCM(cluster consensus menbership)是集群成员共识模块。CRM(cluster resource manager)集群资源管理器,也就是pacemaker。LRM(local resource manager) 本地资源管理器,它是heartbeat中一个直接操作集群管理中各个资源的模块,负责对资源的启动、停止、重启或监控等。

新、旧CRM资源管理器

在Heartbeat v2.x中的集群资源管理器是使用haresource配置被管理的资源,Heartbeat v3.x中为了兼容保留了对haresource文件的支持,但同时又新增了一个功能更强大的crm资源管理器。crm管理方式有,一种是基于命令行crmsh,一种是基于图形界面的hb_gui。作为新一代的CRM资源管理器,pacemaker提供了更多更灵活也更复杂的管理功能,也使得软件的安装、配置和维护变得更加复杂。

对于我们使用比较多的双机+DRBD,或者是双机+共享存储实现mysql服务高可用的简单使用需求来说,继续延用源自1.x版本和2.x版本时代的haresources资源文件,是一个更简单和容易管理的方案。

而Heartbeat 3.x版本默认配置也仍然是使用的haresources,而未启用pacemaker服务。

节点和首选节点角色(node and prefered node)

运行heartbeat进程的一个独立主机,称为节点。在heartbeat集群软件中,节点分为首选节点、备用节点,主、备节点都有各自的hostname。
我们在配置haresources资源文件中,每行内容的第一列便是一个Heartbeat HA集群中节点的主机名,在这里指定的主机名便会成为HA集群中的一个prefrered node,即首选节点。

#cat /etc/ha.d/haresources
DB_HA1 10.17.130.11/24/eth0 Filesystem::/dev/mapper/mpath0p1::/data::ext4 mysqld

根据heartbeat的资源调度算法,在很多条件下都会优先在首选节点上运行服务程序。而且如果启用了auto_failback配置项,在首选节点故障恢复后,还会自动抢占资源和运行管理的服务程序。在使用hb_takeover和hb_standby命令管理heartbeat资源与服务时,这两个命令所支持的参数主要就是根据主机的 node 和 prefered node 角色来设计的。

切换heartbeat服务的几种操作方法

正常情况下,在heartbeat的工作节点上会托管着一套资源和服务,对外提供服务,这个主机节点可能是首选节点,也可能是备节点。

注:以下描述的操作方法,假定heartbeat双机服务的两个节点上heartbeat服务当前均处在正常运行状态中。请执行service heartbeat status确认一下。

当我们因故需要执行双机切换命令,将全套托管资源和服务切到另一个节点上运行时,可以有以下几种办法:

  1. service heartbeat stop ,在当前运行着资源与服务的节点上执行该命令,该节点会关停服务、释放资源、关闭heartbeat,在另外一个节点上则会接收资源并启动指定的服务程序。切换后,执行命令的节点上heartbeat服务处于关停状态,需要人工启动并恢复到standby状态。
  2. /usr/share/heartbeat/hb_standby local , 当执行命令的节点是首选节点时使用local参数,当托管的资源与服务运行在首选节点上时,在该节点上执行该命令可以将本节点的资源与服务切换到备用节点上运行。首选节点在释放资源后进入standby状态。
  3. /usr/share/heartbeat/hb_takeover local ,当执行命令的节点是首选节点时使用local参数,当托管的资源与服务运行在备用节点上时,在首选节点上执行该命令可以将资源与服务抢占到首选节点上运行。备用节点会在释放资源后进入standby状态。
  4. /usr/share/heartbeat/hb_standby foreign , 当执行命令的节点是备用节点时使用foreign参数,当托管的资源与服务运行在备用节点上时,在该节点上执行该命令可以将资源与服务切换到另一个节点(即prefered node)上运行。备用节点会在释放资源后进入standby状态。
  5. /usr/share/heartbeat/hb_takeover foreign , 当执行命令的节点是备用节点时使用foreign参数,当托管的资源与服务运行在首选节点节点上时,在备用节点上执行该命令可以将资源与服务抢占到本节点上运行。首选节点在释放资源后进入standby状态。
  6. /usr/share/heartbeat/hb_standby [all] , 如果在执行该命令的节点上 运行着 heartbeat管理的资源与服务,则在执行该命令后会将所有资源与服务切换到另一个节点上运行。不带参数时,默认为等同于使用参数 all 。执行该命令的节点会进入standby状态。
  7. /usr/share/heartbeat/hb_takeover [all] ,如果在执行该命令的节点上 没有运行 heartbeat管理的资源与服务,则在执行该命令后会将所有资源与服务抢占到本节点上运行。不带参数时,默认为等同于使用参数 all 。原来运行着资源与服务的节点会进入standby状态。

注意:

  • 以上命令均是幂等的,在一个节点上连续反复执行并不会改变结果。

  • 除了第一个shutdown服务的命令外,其它命令与参数均可在首选节点和备用节点上任意执行。唯一的区别是,只有在符合上面描述的节点角色、资源与服务分布条件的情况下,才会触发资源与服务的迁移切换行为。

推荐记住命令6和7,在需要管理heartbeat和切换服务节点的情况下,简单易用。

注:一般来说我们把heartbeat的日志输出到/var/log/ha-debug文件中,在执行上面的服务切换命令时,建议打开两个窗口,同时跟踪查看主备节点上的该日志文件输出内容。如果切换失败,且日志文件中缺少足够的信息,可以再多查看下操作系统的/var/log/messages文件。

关于Heartbeat资源管理超时时间的一个问题分析

在我们为一个客户处理mysql双机高可用服务无法正常切换的故障时,遇到这样一个问题,即因为客户一些无法确认的操作,导致在关停备用节点上heartbeat服务进程时遇到了一个时长达一个小时的时间锁,即资源配置与调度管理的超时时间为3600s 。
问题的现象如下图所示:
在这里插入图片描述

  • 该日志是在备用节点(资源与服务当前运行在备用节点上)上面执行service heartbeat stop 命令时,命令被卡住,不能执行完并退出。
  • 此时在heartbeat双机高可用服务的首选节点上执行 /usr/share/heartbeat/hb_takeover 命令时, 该备用节点的/var/log/messages文件中会打印上图所示的警告信息。每重复一次,就多打印 harc、hb_standby、heartbeat开头的日志一次。不同之处是在每次日志中携带的[ ? seconds left ]字符串部分,这里的秒数是一个倒计时的计时器。
  • 后来经过进一步分析,确认该计时器是从3600s开始倒计时的。在该计时器数秒结束之前,heartbeat双机高可用服务的两个节点上,执行任何管理命令均无效,最多是触发上面的计时信息。
  • 当该计时器数秒结束后,备用节点上的heartbeat服务自动关停掉,托管的资源与服务被迁移到首选节点上并运行。

由于这个超时时间着实奇特,而且故障很难重现,所以去heartbeat源码中查找了一下有关的代码片段。虽然仍然未能理清heartbeat处理关停服务进程,抢占资源与服务的处理逻辑,尤其是资源调度处理加锁的逻辑部分,但确实看到heartbeat出于提高服务可用性、避免轻易发生脑裂或者是损坏数据资源的目的,在进程启动和关停进都设计了很多资源检查、配置、调度和锁定的设计,其中便有一个长达3600s的资源处理超时时间的使用,从代码上看有很多情况下都会导致触发该超时时间。

heartbeat.c程序中hb_initiate_shutdown(int quickshutdown)函数部分代码:

    if (!quickshutdown && DoManageResources) {
        /* THIS IS RESOURCE WORK!  FIXME */
        procinfo->giveup_resources = TRUE;
        hb_giveup_resources();
        /* Do something more drastic in 60 minutes */
        Gmain_timeout_add(1000*60*60, EmergencyShutdown, NULL);
        return;
    }

hb_resource.c程序中ask_for_resources(struct ha_msg *msg)函数部分代码:

#define    HB_STANDBY_RSC_TO_MS    60L*(60L*1000L)    /* resource handling timeout */

......
const longclock_t    standby_rsc_to
    =            msto_longclock(HB_STANDBY_RSC_TO_MS);

......
standby_running = add_longclock(now
                ,    standby_rsc_to);
......

    if (cmp_longclock(standby_running, zero_longclock) != 0
    &&    cmp_longclock(now, standby_running) < 0
    &&    strcasecmp(info, "me") == 0) {
        unsigned long    secs_left;
        secs_left = longclockto_ms(sub_longclock(standby_running, now));
        secs_left = (secs_left+999)/1000;
        cl_log(LOG_WARNING
        ,    "Standby in progress"
        "- new request from %s ignored [%ld seconds left]"
        ,    from, secs_left);
        return;
    }
  • 在日志截图中打印的 seconds left信息,便是出自上面的这个ask_for_resources函数。

由于缺少适用的IDE工具,以上问题没有做更进一步的逻辑分析,如果有哪位同学对这一问题的根源原因有更多认识,也请分享给我。

需要了解关于heartbeat更多的原理和概念,可以参考以下几篇资料:
https://blog.51cto.com/ccschan/1922193
https://yq.aliyun.com/articles/447958
https://linux.die.net/man/1/hb_standby
https://linux.die.net/man/1/hb_takeover

猜你喜欢

转载自blog.csdn.net/watermelonbig/article/details/100110900