본문 바로가기
AWS

[AWS] SageMaker Async Endpoint AutoScaling

by parkjp 2023. 7. 17.

 

Aws SageMaker 비동기(async) 엔드포인트 autoscaling에 대한 방법에 대해 간단하게 정리해보자.

 

 

일단 비동기 엔드포인트는 실시간 엔드포인트와 달리 인스턴스 수를 0개까지 줄일 수 있다.

비동기 엔드포인트 내부적으로 Queue가 있어 요청이 오면 Queue에 쌓이고 인스턴스 수를 scale-out 시킨다.

때문에 일반적인 scale-out, scale-in 정책 말고도 인스턴스 수가 0개 일 때 요청이 온 경우 scale-out시켜주는 정책이 따로 필요하다.

 

SageMaker 콘솔에서 만들 수 있는 부분에는 한계가 있다. CLI를 사용하여 만들면 더욱 세세하게 설정할 수 있어서

처음에는 CLI로 작업을 하였는데, 엔드포인트가 여러 개 늘어나면 일일이 하기 귀찮을 것 같아서 AWS SDK('@aws-sdk/client-application-auto-scaling')를 써서 Lambda 함수로 만들었다.

 

 

AutoScaling을 하기 위해서는 ApproximateBacklogSizePerInstanceHasBacklogWithoutCapacity 지표를 이용하면 된다.

ApproximateBacklogSizePerInstance는 인스턴스 당 적절한 요청 수를 나타내고,

HasBacklogWithoutCapacity는 인스턴스가 0일 때 요청이 있는지를 나타낸다.

 

const registerParams = {
    ServiceNamespace: 'sagemaker',
    ScalableDimension: 'sagemaker:variant:DesiredInstanceCount',
    ResourceId: `endpoint/${endpoint}/variant/AllTraffic`,
    MinCapacity: 0,
    MaxCapacity: maxCapacity
 };

 await applicationAutoscalingClient.send(new RegisterScalableTargetCommand(registerParams));

 

 

위 소스는 endpoint에 최소, 최대 인스턴스 수를 설정한다.

AutoScaling에 따라 늘어나고 줄어들 수 있는 최소, 최대 인스턴스 수 이다.

 

 

 

 

  const ScalingPoliyParams = {
      ServiceNamespace: 'sagemaker',
      ScalableDimension: 'sagemaker:variant:DesiredInstanceCount',
      ResourceId: `endpoint/${endpoint}/variant/AllTraffic`,
      PolicyName: `${endpoint}-scaling-policy`,
      PolicyType: 'TargetTrackingScaling',
      TargetTrackingScalingPolicyConfiguration: {
        TargetValue: targetValue,
        CustomizedMetricSpecification: {
          MetricName: 'ApproximateBacklogSizePerInstance',
          Namespace: 'AWS/SageMaker',
          Dimensions: [
            {
              Name: 'EndpointName',
              Value: ${endpoint}
            }
          ],
          Statistic: 'Average'
        },
        ScaleInCooldown: 300, // 축소 활동이 완료된 후 다른 축소 활동이 시작될 수 있는 시간(초)입니다.
        ScaleOutCooldown: 600 // 확장 활동이 완료된 후 다른 확장 활동이 시작될 수 있는 시간(초)입니다.
      }
};
  
  const command = new PutScalingPolicyCommand(ScaliingPoliyParams);
  await applicationAutoscalingClient.send(command);

 

위 소스는 ApproximateBacklogSizePerInstance에 따른 autoscaling 정책을 만든다. 분당 임계값이 targetValue을 넘어서서 유지가 되면 SageMaker endpoint 인스턴스 수가 늘어나게 된다. 마찬가지로 분당 임계값이 targetValue의 90%값 미만이 유지가 되면 인스턴스 수는 줄어들게 된다.

 

 

endpointtargetValue, maxCapacity값은 Lambda 함수 body로 받고 있다.

 

endpoint : AutoScaling을 적용할 엔드포인트 이름.

targetValue: ApproximateBacklogSizePerInstance 경보 생성을 위한 임계값.

maxCapacity: AutoScaling 최대 인스턴스 수.

 

 

const StepScalingPolicyParams = {
      PolicyName: `${endpoint}-StepScaling-ScalingPolicy`,
      ServiceNamespace: 'sagemaker',
      ScalableDimension: 'sagemaker:variant:DesiredInstanceCount',
      ResourceId: `endpoint/${endpoint}/variant/AllTraffic`,
      PolicyType: 'StepScaling',
      StepScalingPolicyConfiguration: {
        AdjustmentType: 'ChangeInCapacity',
        MetricAggregationType: 'Average',
        Cooldown: 600, //이전 조정 활동이 적용될 때까지 기다리는 시간(초)입니다. 
        StepAdjustments: [
          {
            MetricIntervalLowerBound: 0,
            ScalingAdjustment: 1
          }
        ]
      }
    };
    
 const putStepPolicyResponse = await applicationAutoscalingClient.send(new PutScalingPolicyCommand(StepScalingPolicyParams));
 const scalingPolicyArn = putStepPolicyResponse.PolicyARN;

 

단계 조정 정책으로 인스턴스가 0일 때 요청이 들어오면 scale-out 시키기 위해 설정한다.

scalingAdjustment값이 1이므로 인스턴스가 1개 띄워지게 된다.

 

 

const putAlarmParams = {
  AlarmName: `${endpoint}-scaling-alarm`,
  MetricName: 'HasBacklogWithoutCapacity',
  Namespace: 'AWS/SageMaker',
  Statistic: 'Average',
  TreatMissingData: 'missing',
  Period: 60,
  EvaluationPeriods: 1,
  DatapointsToAlarm: 1,
  Threshold: 1,
  ComparisonOperator: 'GreaterThanOrEqualToThreshold',
  Dimensions: [
    {
      Name: 'EndpointName',
      Value: endpoint
    }
  ],
  AlarmActions: [
    scalingPolicyArn
  ]
};

await cloudwatch.send(new PutMetricAlarmCommand(putAlarmParams));

 

마지막으로 HasBackLogWithoutCapacity지표를 이용해 경보를 설정한다.

AlarmActions에는 위에서 설정한 단계조정정책 Arn을 넣으면 된다.

HasBackLogWithoutCapacity지표가 경보가 울리면 단계조정정책이 실행되고 SageMaker endpoint 인스턴스가 띄워지게 된다.

 

여기까지해서 람다에 만들어 놓으면 간단하게 endpoint에 autoscaling을 걸 수 있다. 테스트 코드로 돌려보고 잘 설정이 되었는지 확인하면 된다.

 

 

**

대부분의 autoscaling은 잘 되지만, 한 가지 걸리는 부분이 있는데,

인스턴스가 0일 때 ApproximateBacklogSizePerInstance의 임계값을 넘어선 요청이 들어오면 두 가지 정책이 실행되서 한번에 2개 또는 그 이상이 띄워질 수 있다.

 

ApproximateBacklogSizePerInstance 정책 설정 시 코드에서

TargetTrackingScalingPolicyConfiguration의 CustomizedMetricSpecification에서 여러 metric을 넣어서 수학적 수식으로 만들 수 있긴한데 아직까지 SageMaker에서 지원을 하지 않는건지 콘솔로 직접 만들던 수정을 하던 하면 SageMaker에 연결된 경보가 사라지게 되어 autoscaling이 안되게 된다.

 

다른 하나의 방법은 직접 콘솔에서 수학적 수식으로 경보를 만들고 cloudwatch eventBus로 Lambda에 보내서 직접 컨트롤 하는 것인데, eventBus로 Lambda에 보내면 엔드포인트 이름과, 이전 지표 값, 현재 지표값이 들어오게 된다.

해당 값들과 임계값으로 계산해서 SageMaker SDK로 처리하면 된다. 물론 이 경우엔 조금이라도 잘못 설정하면 autoscaling이 잘못되서 서비스 시 문제가 될 수 있다.

 

 

 

반응형