FaaS - Scaling
概述
- Serverless 的弹性扩缩容可以将实例缩容为
0,并根据请求量级自动扩缩容,从而有效地提升资源利用率 极致动态扩缩容是FaaS的核心内涵,是与 PaaS 平台的核心差异 -降本增效
调度形态
- 开源的 Serverless 函数计算引擎核心,一般是基于 Kubernetes
HPA - 云厂商一般有封装好的各种底座服务,可以基于底座服务来做封装
- 云厂商
容器调度服务,通常有两种调度形态- 基于
Node调度 - 基于
容器实例的调度 -Serverless
- 基于
- 云厂商的
函数计算通常是基于容器服务的底座
Node 维度
组件
Scheduler- 负责将请求打到指定的函数实例(Pod)上,同时负责为集群中的 Node 标记状态,记录到
etcd
- 负责将请求打到指定的函数实例(Pod)上,同时负责为集群中的 Node 标记状态,记录到
Local-Controller- Node 上的本地控制器,负责管理 Node 上所有
函数实例的生命周期,以DeamonSet形式存在
- Node 上的本地控制器,负责管理 Node 上所有
AutoScaler- 定期检测集群中
Node和Pod的使用情况,并根据策略进行扩缩容 - 在扩容时,向底层的
PaaS平台申请资源
- 定期检测集群中
PodCold表示该 Pod未被使用Warm表示正在被使用或者处于等待回收的状态
Node- 状态:闲置、占用
- 如果一个 Node 上
所有的 Pod都是cold,该Node为闲置状态
过程
- AutoScaler 会
定期检查集群中所有 Node - 如果检测到 Node 处于一个需要扩容的状态,则根据策略(
完全自定义)进行扩容 - 在 Node 形态下,
Pod通常会作为函数实例的通用状态- 代码以及不同运行时以
挂载的形式注入到容器内 -DeamonSet
- 代码以及不同运行时以
- AutoScaler 会在轮询时,根据 Warm Pod 的
闲置时间将其重置为 Cold Pod - 在缩容时,理想情况下,AutoScaler 可以将
Node缩容为0- 但为了应对
突发流量,会预留一部分 Buffer
- 但为了应对
缺点
- 需要
管理 Node 调度,还需要处理 Node 中 Pod 的安全隔离和使用 - 可以通过
空 Pod来提前占用,预加载一部分 Pod
Pod 维度
以
Pod为扩缩容单元,可以更加细粒度地控制函数实例的数量
HPA
The HorizontalPodAutoscaler is implemented as a Kubernetes API resource and a controller. The resource determines the behavior of the controller. The horizontal pod autoscaling controller, running within the Kubernetes control plane, periodically adjusts the desired scale of its target (for example, a Deployment) to match observed metrics such as average CPU utilization, average memory utilization, or any other custom metric you specify.
定期从 Kubernetes控制面获取资源的各项指标数据(CPU 利用率、内存使用率等)- 根据指标数据将资源数量
控制在一个目标范围内
HPA 通过控制 Deployment 或者 RC 来实现对 Pod 实际数量的控制
- 在 Kubernetes 中,不同的 Metric 会由对应的
Metric Server持续采集 - HPA 会
定期通过 Metric Server 的 API 或者聚合的 API Server 获取到这些 Metric 指标数据(CPU / Memory)- 然后根据
自定义的扩缩容规则计算出 Pod 的期望数量 - 最后,根据 Pod 当前的实际数量对 Deployment / RC 做出调整,使得 Pod 达到期望数量
- 然后根据
HPA 形态的扩缩容不能直接用于 Serverless
- Serverless 语义下的动态扩缩容可以让服务缩容到
0,而 HPA 不能 - HPA 是通过检测
Pod的Metric来完成 Deployment 的扩缩容- 如果 Deployment 的副本缩容到 0,则 Metric 也变为 0,与 HPA 的机制有
根本冲突
- 如果 Deployment 的副本缩容到 0,则 Metric 也变为 0,与 HPA 的机制有
Knative
从 0 到 1的扩缩容过程,需要额外的机制来支持
收集流量指标
- 在 Knative 中,
Revision代表一个不变的、某一时刻的代码和 Configuration 的快照 - 每个
Revision会引用一个特定的容器镜像和运行它所需要的任何特定对象(如环境变量和卷)- 再通过
Deployment控制函数实例(User Pod)的副本数
- 再通过
- 每个
User Pod中都有两个容器:Queue Proxy和User Container Queue Proxy- 每个函数实例被创建时,都会被以
Sidecar的方式将Queue Proxy注入 Queue Proxy作为每个User Pod的流量入口,负责限流和流量统计的工作AutoScaler会定时收集Queue Proxy统计的流量数据,作为后续扩缩容的重要依据
- 每个函数实例被创建时,都会被以
调整实例数量
- 当收集到
流量的指标后,AutoScaler 会通过改变实例Deployment来决定实例最终的个数 - 简单算法 - 按照当前总并发
平均划分到期望数量的实例上,使其符合设定的并发值- 当前总并发为 100,设定的并发值为 10,最终调整出来的实例数量为 100/10 = 10
- 实际上,扩缩容的实例数量还会考虑系统负载和调度周期等因素
从 0 到 1
- Knative 专门引入
Activator组件 - 用于流量暂存和代理负载 - 当 AutoScaler 将函数实例缩容为
0时,会控制Activator作为实例为 0 时的流量接收入口 Activator在收到流量后,会将请求和信息暂时缓存,并主动告知AutoScaler进行扩容- 直到
成功扩容出来函数实例,Activator 才会将缓存的流量转发到新生成的函数实例上
- 直到
扩缩容模型
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.















