发布于: Aug 12, 2022

企业迁移上云后 SAP 应用依然面临了许多问题,其中包括跨可用区的延迟问题,亚马逊云科技是如何解决的呢?

解决这个问题的最好方法,是将活动的 SAP 应用与 SAP 数据库主实例始终放在同一个可用区里,这样它们之间的交互就不会因为跨可用区的延迟受到影响,也避免了跨可用区流量造成的额外费用;但是这样做的问题也显而易见:SAP 应用实例失去了天然的跨可用区的保护,一旦遇到可用区级的故障,需要额外的方案或人为介入来保障业务连续性。

以此为背景,在本博客中,我们会详述具备 SAP 系统跨可用区高可用冗余与最优延迟兼具的架构方案(SAP 云上自适应跨可用区高可用架构)。

什么是自适应

本博客中最核心的“自适应”的目标是:在总体资源成本不增加的情况下,利用亚马逊云科技云原生服务,在云上构建一套 SAP 高可用系统架构,使得 SAP 的实际负载实例(ABAP/Java Server)以及 SAP ASCS 实例自动随着 SAP HANA 主实例所处之可用区进行平滑转换,从而移除跨可用区访问的延迟问题。

其方案架构概览如下图所示:

在此架构方案中,SAP 应用实例 AS01/02 始终与HANA主实例所在可用区保持一致,在另一个可用区,预先准备好 SAP 应用实例 AS03/04 供自适应流程进行管理,二在自适应流程过程的最后,AS01/02 将被正常关闭。

为了实现这个架构,需要实现以下三个核心功能:

  • 可靠的事件总线、针对事件的处理流程以及关键事件的捕获
  • SAP 系统整体可用区转换的流程处理
  • 使用 SAP 系统即代码思想(SAP as Code)控制 SAP 实例

接下来我们将会逐一介绍如何攻克这些核心点的设计思路

SAP Netweaver 架构回顾

在介绍如何核心功能设计之前我们先快速回顾一下传统的 SAP 的高可用架构。

在 SAP 高可用最佳实践中,一个可靠的高可用集群处于最为重要的位置。纵观 SAP 的整体架构,要构造无单点故障的架构,对以下三个核心组件的保护至关重要。

  • Global Filesystem(/sapmnt/ 等)
  • SAP ASCS 实例
  • SAP HANA 数据库实例
对于这些关键组件如何实现高可用可以参考 SUSE 的官方文档,总体来说,除了 Global Filesystem 这个可以使用云原生服务  Amazon EFS 提供支持的组件,对于 SAP ASCS 实例与 SAP HANA 数据库实例来说,EC2+集群软件是最好的选择,对此客户可以选择 Windows 的集群服务、也可以选择 SLES 与 RHEL 都支持的 Pacemaker Linux 高可用集群,或者像 SIOS、Veritas 等第三方集群件方案。我们将基于客户群体最为广泛的 Pacemaker 进行展开。
 
在 Pacemaker 中,SAP 的应用实例与 HANA 实例均作为集群资源,集群将视资源状态、预设规则、资源分值与节点故障事件等作为触发条件对资源进行管理。在一套 SAP 高可用架构中,通常会存在包含 SAP ASCS/ERS 实例(也可以选择将 SAP 的 ABAP/Java Server 也放在这个集群里)与 SAP HANA 实例的两个核心的高可用集群,其中的 SAP HANA 集群负责着自适应方案最关心的 SAP HANA 主实例的切换。

可靠的事件总线、针对事件的处理流程以及关键事件的捕获

总体来说,要实现一套自适应的自动化流程处理框架,我们需要事件总线、流程引擎以及执行函数。

对于事件总线的选择,亚马逊云科技提供的云原生事件总线服务 – Amazon EventBridge 能够完全满足我们的需要;同时其能够帮助我们集成云原生的流程引擎– Amazon Step Functions, 并最终集成执行函数Amazon Lambda。

由上面提到的 SAP Netwever 高可用架构我们可以知道,事件的来源可以通过持续监控 SAP HANA(集群)的状态来获得,但是我们认为这不是最佳的选择,事实上 SAP HANA 集群本身已经在不断进行 SAP HANA 实例状态的检查了,我们认为最佳的方法是让集群负责推送其关键事件至我们的事件总线,从而形成事件驱动的特性。

基于集群件的功能扩展,Pacemaker 原生提供事件通知的扩展功能,客户可以选择使用底层的alert功能或者自带的监控资源 ClusterMon 来进行。客户可以通过自定制可执行脚本的方式让 alert 或者 ClusterMon 调用,并在脚本中进一步使用 Amazon CLI 或者诸如 boto3 的 sdk 将重新封装的事件推送至由 Amazon EventBridge 的事件总线。

那么事件的内容具体如何获得呢?在 Pacemaker 触发 alert 时,其 fork 的调用进程的环境变量里会包含诸如以下等重要信息:

CRM_alert_kind
CRM_alert_version
CRM_alert_recipient
CRM_alert_node_sequence
CRM_alert_timestamp
CRM_alert_node
CRM_alert_desc
…

以此为基础,客户可以选择自己的方式将这些信息序列化并封装到事件中,一并传至事件总线;同时为了识别事件,客户可以客制事件头信息,诸如

{
  "detail-type": [
    "saptstdb01" <= 数据库节点Hostname
  ],
  "source": [
    "bcs-sac-adaptive-cluster" <= 事件来源标识
  ]
}

以帮助 Amazon EventBridge Rule 以及目标无服务器框架进行捕获。

当然为了让集群的 EC2 实例能够推送事件至 EventBridge 集群总线,可以使用 EC2 Instance Role 并确保附加诸如如下的 Policy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "events:PutEvents",
            "Resource": "<arn-of-the-event-bus>"
        }
    ]
}

在事件总线的另一头,我们将配置合适的 Event Rule 来捕获从集群发来的事件,并过滤关键触发事件(SAP HANA 的切换事件)来触发自适应跨可用区转换流程。

SAP系统整体可用区转换的流程处理

这个流程是整个架构方案的最关键所在。由于事件驱动,自适应的SAP系统可用区转换流程需要能够解决如下问题

  • 能够应对事件乱序送达或者未送达情况
  • 能够在转换过程中针对突发性事件(诸如 SAP HANA 实例切换失败)进行调整
  • 能够保障应用实例可用区转换的效率


亚马逊云科技的 Step Functions 与 Lambda 提供了强大并且足够灵活的编排功能帮助客户克服以上三个难点(当然我们认为拥有一套 SAP as Code 框架将进一步地让整个过程变的更简单)。另外,使用 Amazon SQS 队列提供对事件信息的缓存也是关键;一是这样能够帮助缓解事件乱序的问题,二是流程本身将能随着新事件的到达进行推演与响应;从效率角度来说,等到整个 SAP HANA 主实例切换完成之后再对 SAP 系统进行调整是我们极力想要避免的情况,因为这样做会拉长整个的 RTO 时间,而在切换流程里穿插各种能够提前完成的事情(如 EC2 的启动)可以极大提升效率,再者如果出现中断性时间(如切换失败),流程也可以做到将系统架构回滚至理想状态并触发报警以避免不必要的资源浪费,这样就做到了真正的自适应。

在整个方案中,Cluster Event Poller 是整个流程的大脑,在触发流程之后,其会根据新的事件类型决定下一步的操作,比如 SAP HANA Overlay IP 在某个节点的启动是触发流程的关键事件,在捕获到此事件后Poller会触发目标可用区 SAP 应用实例所在 EC2 的启动流程,在完成之后Poller会等待来自 SAP HANA 集群EC2节点的其他事件,如果收到了 SAP HANA 切换成功的事件,将继续触发启动 SAP 应用实例的启动,在收到到集群对 SAP HANA 主实例的监控成功事件后,流程将启动 ASCS 的切换。具体的参考流程如下图所示。

在转换完成之后,流程最终将处理另一个可用区资源的停止以节省资源,在以上示例中我们直接停止了原可用区中的 SAP 应用实例与 EC2 资源(如对应可用区可以访问);根据客户的实际需求,这个步骤是可以进行进一步优化的,其方向为:将 SAP logon group 与 background job group 的调整集成至此流程,并配合 SAP 的 soft stop 让整个过程变得更加顺滑。

在 SLA 的满足方面,我们将其分为两个场景

以 SAP HANA 主实例故障为例,相较于传统场景,自适应方案下的SAP系统不可用时间不会因为自适应场景变长。

而如果故障场景是整个可用区故障,相较于传统场景,自适应方案下的 SAP 系统不可用时间会比传统方案多1-2分钟(目标可用区 SAP 应用实例的启动时间),但从其对日常 SAP 系统性能的保障(完全移除跨可用区访问的7倍性能差异)等优点来看,以这个微小的延迟作为代价是可以接受的。

使用 SAP 系统即代码思想(SAP as Code)控制 SAP 实例

在自适应转换流程里,有着大量与SAP系统相关的操作步骤,比如SAP应用实例的启停与状态的预检,这往往都涉及相关操作系统命令的执行,而且具体的命令也与操作系统版本与对应SAP应用实例是否由集群件管理有着直接联系。

客户需要通过 Amazon Lambda 以及 Amazon Systems Manager 实现能够基于标签(tag)定位到具体 SAP 应用实例所在的 EC2 实例的方法;针对不同的SAP 应用实例类型将其封装成程序对象进行操作将能够简化这些步骤,并且这将使流程将变得通用化;具体的思路是将 SAP 系统的 SID、实例号以及实例角色等控制 SAP 实例所需要的信息作为元数据保存在 SAP as Code 框架能够访问的持久化服务中,在使用时将这些信息装载到对象中,并对其进行操作。

以下是亚马逊专业咨询服务团队 SAP as Code 框架的配置示例,有这些信息,SAP as Code 框架便能生成 SAP 实例的代码对象,并对其进行操作

#SAP PAS
  saptstas01:
     Template: /sap/instances/sapapp
     System: TST
     Properties:
         InstanceName: D00
         InstanceNumber: 00
         Role: PAS
     EC2Instance: saptstapp01
   
  saptstapp01:
     Template: /ec2/instances/sapapp

定位 SAP 应用实例所在的 EC2 Instance 也很重要,我们同样可以通过上述 SAP 实例配置信息配合 EC2 Tag 最终定位目标 EC2 实例,以下为标签示例:

在定位到 EC2 实例后,我们可以对其执行操作系统级命令,我们建议选择安全可靠的 Amazon Systems Manager Agent,并使用 Amazon SSM 的 SendCommand 在对应 EC2 实例中运行 SAP 实例的启停/监控命令。

示例:

要定位可用区 A1 中的 SAP 系统(TST)的 PAS 与 AAS 应用实例所在 EC2 实例我们需要

通过以下条件进行过滤得到实例信息

  • bcs:sac:sap-sid:TST 等于  True
  • bcs:sac:sap-role 包含  PAS 或者  AAS
  • 实例子网所在可用区等于 AZ1

通过调用 SSM SendCommand 发送启停指令至目标 EC2 实例以控制对应的 SAP 实例,如

例如应用实例不由集群控制,可以围绕 sapcontrol 构建 shell 脚本完成对实例的控制

# sapcontrol -nr <SAPInstanceNumber> -function Stop

例如应用实例由集群控制,则可围绕 crmsh 或者 pcs 来控制 pacemaker 集群资源完成对实例的控制

# crm resource stop <目标 pacemaker 资源名>

相关文章