AWS 弹性伸缩特性介绍
01 什么是弹性伸缩组
随着云计算技术的不断发展与云原生理念的深入人心,更加多种多样的基础部署模式层出不穷。弹性伸缩组作为一个相对较为“传统”的云技术概念,可能还是有不少同学有些陌生。今天我就以云计算鼻祖 AWS 的弹性伸缩组为例,谈一谈这个伴随着云计算发展的基础产品。弹性伸缩组是 Iaas 基础设施发展晚期被提出的一类云产品,相信大家对于 k8s 都会有所了解,基于容器的弹性扩缩容方案不是一个新鲜的概念。弹性伸缩组我们可以理解为是基于云虚拟机的解决动态扩缩容需求的产品。AWS 于 2006 年 8 月推出了 EC2 产品,由于动态扩缩容是天然存在的基础需求,于是从 2008 年 4 月开始,各类三方弹性伸缩软件出现,包括 Scalr 和 RightScale。2009 年 5 月 18 日,AWS 推出了自己的弹性伸缩功能[1]。总结一下,弹性伸缩组主要的目的是为了解决多变的流量需求而诞生的产品,核心概念可以分解为两个部分:“弹性伸缩”与“组”。
02 弹性伸缩组都有什么功能
围绕“弹性伸缩”与“组”,我们可以将弹性伸缩组的主要功能拆分为两个主要部分:
节点管理
弹性伸缩组管理的核心资源还是我们的计算节点,所以本质上弹性伸缩组一个节点组,管理了一组同构或异构的节点,把节点管理好自然是这个产品的基础能力。围绕节点管理 AWS 定义了几个基础概念:
启动模板
为了应对灵活的扩缩容需求,必须需要支持快捷的节点新增与销毁;同时被归纳到一个组内,节点必然存在着或多或少的共性。这时一个能快捷创建节点的模板是一个最好的选择。AWS 的启动模板支持配置大部分的 EC2 参数属性,为伸缩组提供了一个基础性的属性模板。
期望,最大,最小数量
当手动进行节点容量管理时,用户可以设置一个期望的节点数量,来控制节点的数量。当实际的节点数量不等于期望数量时,弹性伸缩组会自动进行节点的创建与回收,来匹配期望数量。当使用自动弹性策略时,本质也是通过修改期望数量来达到控制扩缩的效果。而最大、最小数量则可以理解为一个约束值,来限制期望数量的范围,防止出现集群水位过低或服务器成本过高的问题。
健康检查
对于期望数量的修正的前提是节点处于『健康』状态,对于『不健康』的节点,弹性伸缩组会对其进行置换,以保证组内的节点均处于健康状态,能够正常提供服务。识别节点是否处于健康状态,大体上可以分为两类方法:
◦ 当设置负载均衡器时,会通过负载均衡器的健康检查来判断节点的健康状态
◦ 可以通过 API 手动设置节点的健康状态,往往适配于自定义健康检查逻辑
机型管理策略
一个高可用的集群往往需要若干个可用区的服务节点,但由于在不同可用区往往存在着库存与机型的差异,我们很难预先设置一种机型适配所有的可用区,这时我们需要更加智能的策略来管理机型。
AWS 提供了两种方式来管理机型:
手动配置机型:手动指定若干个机型,按照某种规则选择库存充足的机型
◦ 优先级模式:按照配置的顺序选择第一个库存充足的机型
◦ 价格优先模式:选择库存充足中价格最低的机型
自动机型筛选:可以配置 cpu 核数、内存和其他指标来动态筛选合适的机型
弹性扩缩容能力
定时策略
当一个应用流量具有明显的周期性特征,可以采用定时策略实现周期性的扩容与缩容
基于指标的自动策略
基于云提供的监控指标,随着指标的上升自动扩容,或随着指标的下降自动缩容
冷却时间
过于频繁的进行集群数量的变更不但不会提高服务的质量,而且会导致集群的不稳定,为了防止此类问题,会有一个冷却时间进行限制,实现最小的变更时间间隔
03AWS 弹性伸缩的高级特性
除了上述的一些基础能力,AWS 弹性伸缩还提供了更加高级的特性提供更好的体验。
生命周期钩子
在组内节点进行状态变更时,用户可以加入自定义逻辑,来实现对于节点状态切换时进行的额外操作,例如资源的初始化或清理。自定义操作的实现方式主要有几种:
使用 cloud-init 来执行自定义脚本,此种方式严格来说不属于生命周期钩子的概念范畴,且只能针对启动周期进行操作,但也是一种最为简单实现自定义操作的可用方案。
使用 Lambda 服务实现自定义操作,通过监听 EventBridge 事件来触发配置的 Lambda 操作。
使用自研程序监听 SNS 或者 SQS 事件,执行自定义的程序流程
自定义操作一般都配置有超时时间,用户可以定义超时后的操作方式,因此在自定义程序执行结束后,应当要调用 AWS 的 API 通知弹性伸缩组已完成生命周期钩子逻辑。
暖池
为了提高节点扩容的敏捷性,AWS 提出了暖池的概念,独立于弹性伸缩组的节点之外,最大限度的减少节点提供服务的预热时间,提供应对突发容量时的应变能力。暖池内的节点有三种状态:
Stopped:节点处于关机状态,这样可以节省创建节点的时间。
Hibernated:节点运行的内存状态将以快照形式保存到磁盘中,可以进一步减少开机所需的时间。
Running:节点处于运行状态,几乎可以瞬间加入的弹性伸缩组中,加入负载均衡,提供服务(当然如果设置了生命周期钩子,还有执行自定义逻辑的时间),当然同时也必须支付全部的节点运行费用。
基于权重的多机型策略、
当基础的机型指标不能准确描述节点的服务能力时,AWS 支持用户为指定的机型设置权重,代表机型的相对服务能力。举个例子,机型 a 与 b 均为 2 核 4G 的配置,但因为其他的综合指标,经过压测结果,a 机型的服务能力是 b 机型的两倍,此时我们就可以设置 a 机型的权重为 2,b 为 1。弹性伸缩组的期望、最大最小容量就可以不代表节点数量,而代表抽象的服务能力,当我们指定期望值为 8 时,使用 a 机型需要 4 个节点,而使用 b 机型则需要 8 个节点。这样就会更加准确的描述总服务能力,或者保证多可用区间的能力平衡。
04AutoMQ 是如何使用 AWS 弹性伸缩的
存算分离的 Kafka 节点
由于 AutoMQ 的存算分离架构,几乎所有的状态信息均存储于对象存储中(有部分写缓冲数据在 EBS 卷中,目前已经推出无 EBS 的 Direct S3 版本[3]),我们可以认为节点都是可以随时被终止和替换的。这样就完全具备了利用弹性伸缩管理集群的前提条件,随着负载的变化,可以借助弹性伸缩实现分钟级甚至秒级的容量增减。我们在使用弹性伸缩组时,将 kafka 的 controller 与 broker 节点进行了区分,采用了不同的伸缩组,在此我们提出了一个概念,把同时具备 controller 和 broker 功能的节点称为 server 节点。随着集群规模的增大,我们会根据特性不同将纯 broker 节点按照特性切分为不同的弹性伸缩组。
利用机型策略解决多可用区库存问题
以目前 AutoMQ 使用的两类机型为例,r6in.large 与 r6i.large 均为 2 核 16G 内存的机型,但在实际综合测试中,两者的服务能力存在着本质的区别,可以几乎认为 r6in.large 的服务能力为 r6i.large 的两倍,而两者在不同地域与可用区的分布并不均匀,当我们选择使用多可用区高可用布局的情况下,很难做到不同可用区的服务能力是平衡的。因此使用机型权重即可有效的解决此类问题,将 r6in.large 的权重设置为 r6i.large 的两倍,在多可用区均衡策略下,使用 r6in.large 的可用区可以使用一半的节点数量达到同等的服务能力。
利用健康检查及生命周期钩子保持集群的健康
对于常规的 web 应用,利用负载均衡的自动健康检查是一个最为高效的手段。但对于 Kafka 此类应用来说,往往会有更加复杂的节点健康评估机制。因此,我们需要借助自定义的方案来保证集群节点的健康。我们会根据内部的巡检及一些额外的机制,对于节点进行健康评估,如果发现节点处于非健康状态,我们会利用 AWS 的健康状态设置接口,手动的更改节点的健康状态。此时,弹性伸缩组会自动执行节点的替换操作,得益于 AutoMQ 的无状态架构,可以平滑的进行节点的替换。通过节点关闭的生命周期钩子,我们可以确保边界情况下数据的完整性与可靠性。
利用自动弹性策略实现秒级扩容体验
由于 Kafka 主要运用于大数据量,高吞吐的场景,其运行特征不同于常规的计算密集型应用,对于 cpu 与内存指标并不敏感,决定其负载的核心指标为网络吞吐量,所以我们需要将弹性的核心指标定位至服务器的网络出入带宽。正如我们前面介绍的多弹性伸缩组的架构,我们还需要利用 AWS 的一个关键特性:通过本伸缩组的弹性指标对另外一个组进行伸缩。例如一个规模较小的集群,往往只包含 server 节点,分配了一个伸缩组,当流量规模达到一定比例时,平均的流量已经超过了安全阈值,此时我们需要增加节点数量,由于 server 节点的数量往往是固定的,不可通过简单的增加 server 节点提高整体集群的节点数量。所以我们会在初始化集群的时候,创建两个弹性伸缩组,同时将另一个伸缩组容量设置为 0。这样我们可以通过 server 伸缩组的指标,增加另一个伸缩组的节点数量,整体集群节点的平均流量就会符合预期地下降至合理水位。
05 结语
今天我们简单介绍了 AWS 弹性伸缩组的基本概念与 AutoMQ 是如何使用弹性伸缩组实现产品特性的,接下来我们会针对 AutoMQ 是如何利用云基础设施这一话题展开介绍,请大家敬请期待。
参考资料
[1]https://docs.aws.amazon.com/autoscaling/ec2/userguide/what-is-amazon-ec2-auto-scaling.html[2]https://zh.wikipedia.org/wiki/%E5%BC%B9%E6%80%A7%E4%BC%B8%E7%BC%A9[3]https://docs.automq.com/automq/getting-started/deploy-direct-s3-cluster
关于我们
我们是来自 Apache RocketMQ 和 Linux LVS 项目的核心团队,曾经见证并应对过消息队列基础设施在大型互联网公司和云计算公司的挑战。现在我们基于对象存储优先、存算分离、多云原生等技术理念,重新设计并实现了 Apache Kafka 和 Apache RocketMQ,带来高达 10 倍的成本优势和百倍的弹性效率提升。
🌟 GitHub 地址:https://github.com/AutoMQ/automq
评论