Skip to content

Commit 1eaa7c8

Browse files
authored
[Bug] handle metricKey creation with MetricsSources (#498)
* handle metricKey creation with MetricsSources or not * removed duplcate metrickey creation * consolidate createMetricKey functionality into NewNamespaceNameMetric. * NewNamespaceNameMetric single argument
1 parent a1e28d8 commit 1eaa7c8

File tree

5 files changed

+54
-20
lines changed

5 files changed

+54
-20
lines changed

pkg/controller/podautoscaler/metrics/interface.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,19 @@ type NamespaceNameMetric struct {
3333
MetricName string
3434
}
3535

36-
func NewNamespaceNameMetric(namespace string, name string, metricName string) NamespaceNameMetric {
37-
return NamespaceNameMetric{NamespacedName: types.NamespacedName{Namespace: namespace, Name: name}, MetricName: metricName}
36+
func NewNamespaceNameMetric(pa *autoscalingv1alpha1.PodAutoscaler) NamespaceNameMetric {
37+
metricName := pa.Spec.TargetMetric
38+
if len(pa.Spec.MetricsSources) > 0 {
39+
metricName = pa.Spec.MetricsSources[0].Name
40+
}
41+
42+
return NamespaceNameMetric{
43+
NamespacedName: types.NamespacedName{
44+
Namespace: pa.Namespace,
45+
Name: pa.Spec.ScaleTargetRef.Name,
46+
},
47+
MetricName: metricName,
48+
}
3849
}
3950

4051
// PodMetric contains pod metric value (the metric values are expected to be the metric as a milli-value)

pkg/controller/podautoscaler/podautoscaler_controller.go

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ func (r *PodAutoscalerReconciler) reconcileCustomPA(ctx context.Context, pa auto
284284
paStatusOriginal := pa.Status.DeepCopy()
285285
paType := pa.Spec.ScalingStrategy
286286
scaleReference := fmt.Sprintf("%s/%s/%s", pa.Spec.ScaleTargetRef.Kind, pa.Namespace, pa.Spec.ScaleTargetRef.Name)
287+
metricKey := metrics.NewNamespaceNameMetric(&pa)
287288

288289
targetGV, err := schema.ParseGroupVersion(pa.Spec.ScaleTargetRef.APIVersion)
289290
if err != nil {
@@ -324,7 +325,7 @@ func (r *PodAutoscalerReconciler) reconcileCustomPA(ctx context.Context, pa auto
324325
setCondition(&pa, "AbleToScale", metav1.ConditionTrue, "SucceededGetScale", "the %s controller was able to get the target's current scale", paType)
325326

326327
// Update the scale required metrics periodically
327-
err = r.updateMetricsForScale(ctx, pa, scale)
328+
err = r.updateMetricsForScale(ctx, pa, scale, metricKey)
328329
if err != nil {
329330
r.EventRecorder.Event(&pa, corev1.EventTypeWarning, "FailedUpdateMetrics", err.Error())
330331
return ctrl.Result{}, fmt.Errorf("failed to update metrics for scale target reference: %v", err)
@@ -366,7 +367,7 @@ func (r *PodAutoscalerReconciler) reconcileCustomPA(ctx context.Context, pa auto
366367
// if the currentReplicas is within the range, we should
367368
// computeReplicasForMetrics gives
368369
// TODO: check why it return the metrics name here?
369-
metricDesiredReplicas, metricName, metricTimestamp, err := r.computeReplicasForMetrics(ctx, pa, scale)
370+
metricDesiredReplicas, metricName, metricTimestamp, err := r.computeReplicasForMetrics(ctx, pa, scale, metricKey)
370371
if err != nil && metricDesiredReplicas == -1 {
371372
r.setCurrentReplicasAndMetricsInStatus(&pa, currentReplicas)
372373
if err := r.updateStatusIfNeeded(ctx, paStatusOriginal, &pa); err != nil {
@@ -556,7 +557,7 @@ func (r *PodAutoscalerReconciler) updateStatus(ctx context.Context, pa *autoscal
556557
// It may return both valid metricDesiredReplicas and an error,
557558
// when some metrics still work and PA should perform scaling based on them.
558559
// If PodAutoscaler cannot do anything due to error, it returns -1 in metricDesiredReplicas as a failure signal.
559-
func (r *PodAutoscalerReconciler) computeReplicasForMetrics(ctx context.Context, pa autoscalingv1alpha1.PodAutoscaler, scale *unstructured.Unstructured) (replicas int32, relatedMetrics string, timestamp time.Time, err error) {
560+
func (r *PodAutoscalerReconciler) computeReplicasForMetrics(ctx context.Context, pa autoscalingv1alpha1.PodAutoscaler, scale *unstructured.Unstructured, metricKey metrics.NamespaceNameMetric) (replicas int32, relatedMetrics string, timestamp time.Time, err error) {
560561
logger := klog.FromContext(ctx)
561562
currentTimestamp := time.Now()
562563

@@ -574,19 +575,13 @@ func (r *PodAutoscalerReconciler) computeReplicasForMetrics(ctx context.Context,
574575
}
575576

576577
// TODO UpdateScalingContext (in updateScalerSpec) is duplicate invoked in computeReplicasForMetrics and updateMetricsForScale
577-
err = r.updateScalerSpec(ctx, pa)
578+
err = r.updateScalerSpec(ctx, pa, metricKey)
578579
if err != nil {
579580
klog.ErrorS(err, "Failed to update scaler spec from pa_types")
580581
return 0, "", currentTimestamp, fmt.Errorf("error update scaler spec: %w", err)
581582
}
582583

583584
logger.V(4).Info("Obtained selector and get ReadyPodsCount", "selector", labelsSelector, "originalReadyPodsCount", originalReadyPodsCount)
584-
var metricKey metrics.NamespaceNameMetric
585-
if len(pa.Spec.MetricsSources) > 0 {
586-
metricKey = metrics.NewNamespaceNameMetric(pa.Namespace, pa.Spec.ScaleTargetRef.Name, pa.Spec.MetricsSources[0].Name)
587-
} else {
588-
metricKey = metrics.NewNamespaceNameMetric(pa.Namespace, pa.Spec.ScaleTargetRef.Name, pa.Spec.TargetMetric)
589-
}
590585

591586
// Calculate the desired number of pods using the autoscaler logic.
592587
autoScaler, ok := r.AutoscalerMap[metricKey]
@@ -605,18 +600,16 @@ func (r *PodAutoscalerReconciler) computeReplicasForMetrics(ctx context.Context,
605600
// refer to knative-serving.
606601
// In pkg/reconciler/autoscaling/kpa/kpa.go:198, kpa maintains a list of deciders into multi-scaler, each of them corresponds to a pa (PodAutoscaler).
607602
// We create or update the scaler instance according to the pa passed in
608-
func (r *PodAutoscalerReconciler) updateScalerSpec(ctx context.Context, pa autoscalingv1alpha1.PodAutoscaler) error {
609-
metricKey := NewNamespaceNameMetricByPa(pa)
603+
func (r *PodAutoscalerReconciler) updateScalerSpec(ctx context.Context, pa autoscalingv1alpha1.PodAutoscaler, metricKey metrics.NamespaceNameMetric) error {
610604
autoScaler, ok := r.AutoscalerMap[metricKey]
611605
if !ok {
612606
return fmt.Errorf("unsupported scaling strategy: %s", pa.Spec.ScalingStrategy)
613607
}
614608
return autoScaler.UpdateScalingContext(pa)
615609
}
616610

617-
func (r *PodAutoscalerReconciler) updateMetricsForScale(ctx context.Context, pa autoscalingv1alpha1.PodAutoscaler, scale *unstructured.Unstructured) (err error) {
611+
func (r *PodAutoscalerReconciler) updateMetricsForScale(ctx context.Context, pa autoscalingv1alpha1.PodAutoscaler, scale *unstructured.Unstructured, metricKey metrics.NamespaceNameMetric) (err error) {
618612
currentTimestamp := time.Now()
619-
metricKey := NewNamespaceNameMetricByPa(pa)
620613
var autoScaler scaler.Scaler
621614
autoScaler, exists := r.AutoscalerMap[metricKey]
622615
if !exists {
@@ -649,7 +642,6 @@ func (r *PodAutoscalerReconciler) updateMetricsForScale(ctx context.Context, pa
649642

650643
// update metrics
651644
for _, source := range pa.Spec.MetricsSources {
652-
metricKey := metrics.NewNamespaceNameMetric(pa.Namespace, pa.Spec.ScaleTargetRef.Name, source.Name)
653645
return autoScaler.UpdateSourceMetrics(ctx, metricKey, source, currentTimestamp)
654646
}
655647

pkg/controller/podautoscaler/scaler/apa_test.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,20 @@ func TestAPAScale(t *testing.T) {
3939
metricsFetcher := &metrics.RestMetricsFetcher{}
4040
apaMetricsClient := metrics.NewAPAMetricsClient(metricsFetcher, spec.Window)
4141
now := time.Now()
42-
metricKey := metrics.NewNamespaceNameMetric("test_ns", "llama-70b", "ttot")
42+
43+
pa := autoscalingv1alpha1.PodAutoscaler{
44+
ObjectMeta: metav1.ObjectMeta{
45+
Namespace: "test_ns",
46+
},
47+
Spec: autoscalingv1alpha1.PodAutoscalerSpec{
48+
TargetMetric: "ttot", // Set TargetMetric to "ttot"
49+
ScaleTargetRef: corev1.ObjectReference{
50+
Name: "llama-70b",
51+
},
52+
},
53+
}
54+
55+
metricKey := metrics.NewNamespaceNameMetric(&pa)
4356
_ = apaMetricsClient.UpdateMetricIntoWindow(now.Add(-60*time.Second), 10.0)
4457
_ = apaMetricsClient.UpdateMetricIntoWindow(now.Add(-50*time.Second), 11.0)
4558
_ = apaMetricsClient.UpdateMetricIntoWindow(now.Add(-40*time.Second), 12.0)

pkg/controller/podautoscaler/scaler/kpa_test.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ func TestKpaScale(t *testing.T) {
5555
metricsFetcher := &metrics.RestMetricsFetcher{}
5656
kpaMetricsClient := metrics.NewKPAMetricsClient(metricsFetcher, spec.StableWindow, spec.PanicWindow)
5757
now := time.Now()
58-
metricKey := metrics.NewNamespaceNameMetric("test_ns", "llama-70b", spec.ScalingMetric)
5958
_ = kpaMetricsClient.UpdateMetricIntoWindow(now.Add(-60*time.Second), 10.0)
6059
_ = kpaMetricsClient.UpdateMetricIntoWindow(now.Add(-50*time.Second), 11.0)
6160
_ = kpaMetricsClient.UpdateMetricIntoWindow(now.Add(-40*time.Second), 12.0)
@@ -76,6 +75,25 @@ func TestKpaScale(t *testing.T) {
7675
ticker := time.NewTicker(10 * time.Second)
7776
defer ticker.Stop()
7877

78+
pa := autoscalingv1alpha1.PodAutoscaler{
79+
ObjectMeta: metav1.ObjectMeta{
80+
Namespace: "test_ns",
81+
},
82+
Spec: autoscalingv1alpha1.PodAutoscalerSpec{
83+
TargetMetric: spec.ScalingMetric,
84+
MetricsSources: []autoscalingv1alpha1.MetricSource{
85+
{
86+
Name: spec.ScalingMetric,
87+
},
88+
},
89+
ScaleTargetRef: corev1.ObjectReference{
90+
Name: "llama-70b",
91+
},
92+
},
93+
}
94+
95+
metricKey := metrics.NewNamespaceNameMetric(&pa)
96+
7997
result := kpaScaler.Scale(readyPodCount, metricKey, now)
8098
// recent rapid rising metric value make scaler adapt turn on panic mode
8199
if result.DesiredPodCount != 10 {

pkg/controller/podautoscaler/utils.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,5 @@ func extractLabelSelector(scale *unstructured.Unstructured) (labels.Selector, er
5454
}
5555

5656
func NewNamespaceNameMetricByPa(pa autoscalingv1alpha1.PodAutoscaler) metrics.NamespaceNameMetric {
57-
return metrics.NewNamespaceNameMetric(pa.Namespace, pa.Spec.ScaleTargetRef.Name, pa.Spec.TargetMetric)
57+
return metrics.NewNamespaceNameMetric(&pa)
5858
}

0 commit comments

Comments
 (0)