AWS 기술 블로그

애플리케이션 오토 스케일링의 사용자 정의 지표 기반으로 Amazon ECS 오토 스케일링 하기

이 글은 AWS Containers 블로그의 Autoscaling Amazon ECS services based on custom metrics with Application Auto Scaling by Viji Sarathy and Anoop Singh의 한국어 번역입니다.

소개

애플리케이션 오토 스케일링은 확장 가능한 리소스를 자동으로 확장할 수 있는 솔루션이 필요한 개발자 및 시스템 관리자를 위한 웹 서비스입니다. Amazon Elastic Container Service (Amazon ECS) 서비스, Amazon DynamoDB 테이블, AWS Lambda Provisioned Concurrency 등과 같은 AWS 서비스를 위한 리소스를 자동으로 스케일링할 수 있습니다. 이제 애플리케이션 오토 스케일링은 Amazon CloudWatch 사용자 정의 지표를 기반으로 하는 스케일링 정책을 사용하여 이러한 리소스를 스케일링하는 기능을 제공합니다. 이 글에서는 이 기능을 활용해서 Amazon ECS 서비스에서 HTTP 요청의 평균 처리 속도를 기반으로 오토 스케일링하는 예시를 통해 어떻게 작동하는지 보여드리겠습니다.

배경설명

수평 확장성은 클라우드 네이티브 애플리케이션에서 매우 중요한 부분입니다. 애플리케이션 오토 스케일링은 여러 AWS 서비스와 통합되어 애플리케이션의 요구에 맞게 스케일링 기능을 추가할 수 있습니다. Amazon CloudWatch에서 사용 가능한 관련 사전 정의된 지표 중 하나 이상을 대상 추적(target tracking) 또는 단계별(step) 스케일링 정책과 함께 사용하여 주어진 서비스의 리소스를 비례적으로 확장할 수 있습니다. 하지만 사전 정의된 지표만으로는 스케일링 작업을 언제 실행하고 얼마나 실행할지에 대해 신뢰성 측면에서 다소 부족한 경우가 있습니다. 특정 시나리오에서는 HTTP 요청 수, 큐/토픽에서 검색된 메시지 수, 실행된 데이터베이스 트랜잭션 수 등의 애플리케이션 측면을 추적하는 사용자 지정 지표가 스케일링 작업을 작동시키는 데 더 적합할 수 있습니다.

애플리케이션 오토 스케일링과 함께 대상 추적 정책을 사용할 때 중요한 고려 사항은 지정된 지표가 확장 가능한 대상이 얼마나 바쁜지를 설명할 수 있게 평균 사용률을 나타내야 한다는 것입니다. 애플리케이션이 수신한 HTTP 요청 수, 메시지 브로커의 큐/토픽에서 검색된 메시지 수와 같은 지표는 본질적으로 누적되어 단조롭게 증가하기 때문에 이런 고려 사항을 충족하지 못합니다. 따라서 확장 가능한 대상의 용량에 비례하여 증가하거나 감소하는 사용률 지표로 변환해야 합니다. 이전에는 고객이 이 변환을 수행하는 전용 코드를 작성해야 했습니다. 이런 사례의 대표적인 예는 이 게시글에서 제시되고, Amazon Managed Streaming for Apache Kafka(Amazon MSK)의 토픽에 게시된 메시지 속도를 기반으로 Amazon ECS 서비스의 작업(Task) 수를 확장하는 방법을 자세히 설명합니다. 이 방법은 AWS Lambda 함수를 사용하여 주기적으로 Amazon CloudWatch에서 사용자 지정 지표 데이터를 가져온 다음 평균 사용률 지표를 계산하고 이를 Amazon CloudWatch에 새로운 사용자 지정 지표로 게시합니다. 그런 다음 미리 계산된 이 새로운 사용률 지표를 참조하는 사용자 지정 지표 사양을 사용하여 대상 추적 정책을 정의합니다.

새로운 기능은 고객이 사용자 지정 지표 명세 내에서 지표 수학 표현식을 사용하여 평균 이용률 지표가 하나 이상의 Amazon CloudWatch 지표를 사용하여 어떻게 계산되는지 정의할 수 있도록 합니다. 그 외의 모든 것은 애플리케이션 오토 스케일링이 처리합니다. 따라서 고객은 이 작업을 수행하는 코드를 작성하거나 이 코드를 실행하기 위한 컴퓨팅 인프라를 추가로 배포할 필요가 없습니다. 이러한 작업은 운영 부하와 유지 관리 비용만 증가시킬 뿐 애플리케이션에 차별성을 부여하지 않았습니다. 그럼 새로운 기능이 어떻게 작동하는지 자세히 살펴보겠습니다.

솔루션 개요

Amazon ECS 클러스터에 배포된 샘플 워크로드를 사용해서 새 기능이 어떻게 작동하는지 보여드리겠습니다. 다음 그림(Figure 1)은 이번 솔루션의 구성 상태를 나타냅니다. 이 구성은 Amazon Aurora PostgreSQL 데이터베이스 인스턴스와 직접 통신하는 백엔드 데이터 저장소 서비스가 있는 마이크로서비스 아키텍처를 대표합니다. 이 서비스는 데이터베이스에서 생성, 읽기, 수정, 삭제(CRUD) 작업을 수행할 수 있도록 다른 마이크로서비스에 REST API 세트를 제공합니다.

Sample workload

이 애플리케이션은 Prometheus 클라이언트 라이브러리로 계측되며, http_requests_total이라는 이름의 Prometheus 카운터를 사용하여 서비스에 전송된 HTTP 요청 수를 추적합니다. Amazon ECS 클러스터에서 프로메테우스 지표를 수집하려면 CloudWatch 에이전트와 프로메테우스 모니터링을 사용하거나 AWS Distro for OpenTelemetry Collector를 사용할 수 있습니다. 이 시연에서는 CloudWatch 에이전트를 사용합니다. 사용자 지정 지표는 에이전트에 의해 CloudWatch 네임스페이스인 ECS/ContainerInsights/Prometheus로 게시됩니다. 목표는 실행 중인 작업(Task)에서 처리된 HTTP 요청의 평균 처리 속도에 비례하여 Datastore 백엔드 서비스를 자동으로 확장하는 것입니다. 백엔드 서비스가 로드 밸런서에 등록되지 않았으므로 CloudWatch에 게시된 Elastic Load Balancing 지표는 서비스 부하에 대한 신뢰할 수 있는 지표로 사용할 수 없습니다.

Walkthrough

첫 번째 설정 단계는 스케일링 작업이 실행되는 대상 리소스의 확장 가능한 측정기준(dimension)을 등록하는 것입니다. 이 경우에는 서비스 내 작업(Task)의 DesiredCount 입니다.

CLUSTER_NAME=ecs-ec2-cluster
SERVICE_NAME=BackendService
aws application-autoscaling register-scalable-target \
--service-namespace ecs \
--scalable-dimension ecs:service:DesiredCount \
--resource-id service/$CLUSTER_NAME/$SERVICE_NAME \
--min-capacity 2 \
--max-capacity 10

다음으로 애플리케이션 오토 스케일링 API를 사용하여 대상 추적 정책을 설정하겠습니다. 대상 추적 정책과 함께 사용할 사용자 지정 지표는 다음 코드와 같이 정책 구성 JSON 파일의 CustomizedMetricSpecification 필드를 사용하여 정의합니다.

{
    "TargetValue":5.0,
    "ScaleOutCooldown":120,
    "ScaleInCooldown":120,
    "CustomizedMetricSpecification":{
        "MetricName":"http_request_rate_average_1m",
        "Namespace":"ECS/CloudWatch/Custom",
        "Dimensions":[
            {"Name":"ClusterName",
                "Value":"ecs-ec2-cluster"
            },
            {
                "Name":"TaskGroup",
                "Value":"service:BackendService"
            }
        ],
        "Statistic":"Average"
    }
}

이전에는 JSON 파일의 MetricName 필드에 지정된 사용자 지정 지표는 Amazon CloudWatch에서 미리 계산되고 사용 가능한 사용량 지표여애 했습니다. 그러나 새로운 기능에서는 CustomizedMetricSpecification 필드의 스키마가 확장되어 Metrics 필드를 사용하여 지표 수식을 포함할 수 있게 되었습니다. 지표 수식을 사용하면 여러 Amazon CloudWatch 지표를 쿼리하고 여러 함수와 연산자를 사용한 지표를 기반으로 새로운 시계열을 생성할 수 있습니다. 이를 통해 고객은 정책 구성 JSON 파일에서 수학 표현식을 지정하기만 하면 동적으로 사용자 지정 사용률 메트릭을 생성할 수 있습니다. Period 필드를 제외하고, 이 스키마는 GetMetricData CloudWatch API의 MetricDataQuery 매개변수에서 사용되는 것과 정확히 동일합니다. 애플리케이션 오토 스케일링은 이를 미리 정의된 60초 값으로 설정하며 사용자 정의 지표 사양에서 명시적으로 정의할 수 없습니다.
다음 예제에서 수학 표현식은 두 개의 다른 Amazon CloudWatch 지표를 기반으로 하는 http_request_rate_average_1m이라는 메트릭을 계산합니다. 첫 번째 지표인 http_requests_total은 위에서 설명한 사용자 지정 프로메테우스 지표입니다. 두 번째 지표인 RunningTaskCount는 Amazon ECS의 컨테이너 인사이트에 의해 자동으로 수집되고 네임스페이스 ECS/ContainerInsights에 게시됩니다. 다만 해당 지표를 사용하기 위해서 Amazon ECS 클러스터에 대해 컨테이너 인사이트를 활성화했는지 확인해야 합니다. 관련되어 이 문서 설명을 참고합니다. 계산된 지표는 실행 중인 작업에 의해 처리된 지난 1분 동안의 HTTP 요청의 평균 초당 처리 속도입니다. 이 사용률 지표는 이제 TargetValue 필드를 사용하여 초당 5개의 요청을 목표로 하는 서비스를 자동으로 스케일하는 데 사용됩니다.

{
   "TargetValue":5.0,
   "ScaleOutCooldown":120,
   "ScaleInCooldown":120,
   "CustomizedMetricSpecification":{
      "Metrics":[
         {
            "Id":"m1",
            "Label":"sum_http_requests_total_1m",
            "ReturnData":false,
            "MetricStat":{
               "Metric":{
                  "Namespace":"ECS/ContainerInsights/Prometheus",
                  "MetricName":"http_requests_total",
                  "Dimensions":[
                     {
                        "Name":"ClusterName",
                        "Value":"ecs-ec2-cluster"
                     },
                     {
                        "Name":"TaskGroup",
                        "Value":"service:BackendService"
                     }
                  ]
               },
               "Stat":"Sum"
            }
         },
         {
            "Id":"m2",
            "Label":"running_task_count_average_1m",
            "ReturnData":false,
            "MetricStat":{
               "Metric":{
                  "Namespace":"ECS/ContainerInsights",
                  "MetricName":"RunningTaskCount",
                  "Dimensions":[
                     {
                        "Name":"ClusterName",
                        "Value":"ecs-ec2-cluster"
                     },
                     {
                        "Name":"ServiceName",
                        "Value":"BackendService"
                     }
                  ]
               },
               "Stat":"Average"
            }
         },
         {
            "Id":"m3",
            "Expression":"m1/(m2*60)",
            "Label":"http_request_rate_average_1m",
            "ReturnData":true
         }
      ]
   }
}

대상 추적 확장 정책은 위의 정책 구성 JSON 파일과 아래의 CLI 명령을 사용하여 생성됩니다. 대상 추적 스케일링 정책을 생성하면 애플리케이션 오토 스케일링이 스케일-아웃 동작(높음 알람)을 트리거하는 알람과 스케일-인 동작(낮음 알람)을 트리거하는 알람 등 두 개의 지표 알람(Figure 2)을 생성합니다.

CLUSTER_NAME=ecs-ec2-cluster
SERVICE_NAME=BackendService
POLICY_NAME=HTTP-Request-Rate-Policy
aws application-autoscaling put-scaling-policy \
--policy-name $POLICY_NAME \
--service-namespace ecs \
--resource-id service/$CLUSTER_NAME/$SERVICE_NAME \
--scalable-dimension ecs:service:DesiredCount \
--policy-type TargetTrackingScaling \
--target-tracking-scaling-policy-configuration file://policy.json

High and low alarm

Autoscaling in action with Amazon ECS

부하 테스트 도구인 Locust를 사용하여 이 워크로드에 지속적인 요청 스트림을 전송합니다. 이 백엔드 서비스는 로드 밸런서에 등록되지 않았기 때문에 테스트를 쉽게 하기 위해서 AWS Cloud Map의 서비스 레지스트리에 서비스를 등록합니다. 이를 통해 부하 테스트 도구가 서비스 DNS 호스트 이름을 사용하여 워크로드 작업(Task)으로 트래픽을 전달할 수 있습니다. 테스트 기간 동안의 로드 프로파일은 아래 그림(Figure 3)에 나와 있습니다. 초기 부하로 약 초당 9개 요청 수준으로 시작합니다. 부하는 일정 기간 후 두 배로 증가하여 스케일-아웃 작업을 트리거하고, 약 초당 4개 요청 수준으로 감소하여 최종적으로 스케일-인 작업을 트리거합니다.


아래의 그림(Figure 4)은 오토 스케일링 작업이 수행되는 대상 사용률 지표인 http_request_rate_average_1m 프로파일을 나타냅니다. 이어지는 그림(Figure 5)은 스케일-아웃 전, 스케일-아웃 후, 스케일-인 이후 서비스에서 실행 중인 작업(Task)의 수를 보여줍니다. 실행 중인 작업(Task)이 2개로 시작하면 서비스의 초기 부하로 인해 목표 지표가 작업당 초당 약 4건의 요청으로 유지되며, 이는 구성된 상한 임계값인 5건보다 훨씬 낮은 수준입니다. 부하가 두 배로 증가하면 지표값이 상한 임계값을 초과하고 약 3분(높음 경보의 평가 기간) 후에 높음 경보에 의해 스케일-아웃 조치가 트리거됩니다. 대상 추적을 통해 작업(Task) 수가 4개로 비례적으로 증가하여 목표 지표값이 상한 임계값 아래로 내려가면, 그 후 4개의 작업(Task)이 실행 중인 상태에서 부하가 초당 요청 4건으로 감소하면서 목표 지표가 작업당 초당 1건 요청 수준으로 떨어지고 하한 임계값을 밑돌게 됩니다. 그리고 약 15분(즉, 낮음 경보의 평가 기간)이 경과하면 스케일-인 작업이 발생하여 낮음 경보가 트리거되고 작업(Task) 수가 2개로 다시 감소합니다.


결론

본 게시물에서는 애플리케이션 오토 스케일링의 대상 추적에 대한 지표 수학 표현식 지원 기능을 사용하여 Amazon ECS 서비스를 자동으로 스케일하는 방법에 대해서 이야기했습니다. 이 기능은 현재 바로 사용 가능하며 AWS CLI 또는 AWS SDK를 통해 사용할 수 있습니다. 이전에는 고객이 애플리케이션 오토 스케일링을 사용하여 특정 AWS 서비스의 리소스를 자동으로 스케일할 때, CloudWatch에서 사용 가능한 사전 정의된 지표 세트를 사용하는 것으로 제한 되었습니다. 만약 별도의 사용자 지정 애플리케이션 지표를 사용하려면 고객은 사용률 지표를 미리 계산하고 Amazon CloudWatch에서 사용 가능하게 하는 작업을 수행하는 전용 코드를 작성해야 했습니다. 새로운 기능을 사용하면, 대상 애플리케이션에 차별화가 추가되지 않는 이러한 전용 코드를 유지 관리할 필요가 없습니다. 이 기능은 Amazon ECS 서비스, AWS Lambda 등의 AWS 서비스에서 확장 가능한 리소스를 사용자 지정 지표를 기반으로 오토 스케일링하는 작업을 매우 간단하게 합니다. Amazon에서는 고객의 피드백을 매우 중요하게 생각합니다. 새로운 기능을 사용하신 후 피드백을 부탁드립니다.

Jungseob Shin

Jungseob Shin

신정섭 Solutions Architect는 다양한 분야의 Backend 서버 개발 경험을 바탕으로 Startup 고객이 비즈니스 목표를 달성하도록 AWS 서비스의 효율적인 사용을 위한 아키텍처 설계 가이드와 기술을 지원하는 역할을 수행하고 있습니다. 컨테이너와 서버리스 기술에 관심이 많습니다.