探索Knative中的Target Burst Capacity 2021-09-06 Serverless 暂无评论 2397 次阅读 > 本文首发于我的博客:[探索Knative中的Target Burst Capacity](https://myrat.top/archives/30/) > 本文基于Knative/serving [v0.24.0](https://github.com/knative/eventing/tree/v0.24.0) ![object_model.png](/usr/uploads/2021/09/962650651.png) 服务接收到流量请求后,从0自动扩容为N,以及没有流量时自动缩容为0,是Serverless平台最核心的一个特征。 当服务副本数为0时,Knative自动将请求转发到Activator组件,Activator会保持请求,同时Autoscaler组件会负责将副本数扩容,之后Activator再将请求导入到实际的Pod,并且在副本数不为0时,Route会直接将流量负载均衡到Pod,不再走Activator组件。这也是Knative实现冷启动的一个基本思路。 但当有突发大流量来临时,多个Pod启动速度不一致,会导致大量请求全部打在一个Pod中,导致请求延迟的增大,极端情况queue-proxy可能会丢弃请求导致请求的失败。所以Knative使用了Target Burst Capacity来应对这种情况。 ##### Target Burst Capacity Target Burst Capacity(TBC)配置了应用在没有缓存下禁得起的突发流量。当应用的空闲容量低于TBC时,Activator组件就会参与到流量路径中,作为流量的缓存和负载均衡。如果没有该功能,突发请求会在queue-proxy中缓存,请求延迟会增大,并且queue-proxy可能会丢弃请求。 TBC(`autoscaling.knative.dev/targetBurstCapacity`)默认值为200,如果设置为0,则除了冷启时,Activator都不会在服务路径中。如果设置为-1,则Activator会一直在服务路径中。 ##### Soft limit & hard limit 并发决定了应用每个副本在任何给定时间可以处理的同时请求的数量,Knative中可以使用`autoscaling.knative.dev/metric`和`autoscaling.knative.dev/target`作为soft limit,`containerConcurrency`作为hard limit。如果同时设置了两个值,则会取两者之间小的那个。 Soft limit不是严格的强制限制,在某些突发大量请求下,可能会超过这个值。Hard limit是一个强制的限制,如果并发数达到限制,多余的请求会被缓冲。只有应用有明确的限制时才建议使用hard limit,不然可能会对应用的吞吐和延迟产生负面影响,并导致额外的冷启动。 ##### ExcessBurstCapacity(EBC) EBC决定了Activator是否参与服务路径中,当EBC为负值时,Activator会参与到服务路径中。 ```golang // pkg/reconciler/autoscaling/kpa/kpa.go func (c *Reconciler) ReconcileKind(ctx context.Context, pa *autoscalingv1alpha1.PodAutoscaler) pkgreconciler.Event { ... if want == 0 || decider.Status.ExcessBurstCapacity < 0 || want == scaleUnknown && pa.Status.IsInactive() { mode = nv1alpha1.SKSOperationModeProxy } ... } ``` EBC计算公式如下: EBC = TotCapacity - observedPanicValue - TargetBurstCapacity ```golang // pkg/autoscaler/scaling/multiscaler.go func (m *MultiScaler) createScaler(decider *Decider, key types.NamespacedName) (*scalerRunner, error) { ... d.Status.ExcessBurstCapacity = int32(float64(d.Spec.InitialScale)*d.Spec.TotalValue - tbc) ... } ``` `observedPanicValue` 为观测到的实际流量情况。 TotCapacity TotCapacity = originalReadyPodsCount(Ready的Pod数) * TotalValue TotalValue TotalValue根据是否设置`autoscaling.knative.dev/target`分为两种情况 - 设置了`autoscaling.knative.dev/target`。TotalValue为`autoscaling.knative.dev/target`的值,如果`autoscaling.knative.dev/metric`为`concurrency`(默认)并且又设置了`containerConcurrency`,则TotalValue为`autoscaling.knative.dev/target`和`containerConcurrency`小的那一个。 - 没有设置`autoscaling.knative.dev/target`。根据`autoscaling.knative.dev/metric`是否为`rps`又可分两种情况。 - 如果`autoscaling.knative.dev/metric`为`rps`,TotalValue为`requests-per-second-target-default`的值。 - 如果`autoscaling.knative.dev/metric`不为`rps`,TotalValue为`containerConcurrency`的值。如果`containerConcurrency`为0,则为`container-concurrency-target-default`的值。 Knative在遇到突发流量时会通过TBC和target等参数控制Activator参与服务路径,使用Activator做流量的负载均衡,将流量分发给后面新扩容出来的Pod,从而避免请求失败等问题。 参考链接: - https://knative.dev/v0.24-docs/serving/load-balancing/target-burst-capacity/ 打赏: 微信, 支付宝 标签: Knative 本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。本站myrat.top所有文章均为原创,转载请注明出处。