grep

DevOps

옵저버빌리티 Right-Sizing: 여기어때에서 기준을 만드는 법

양현진Cople(코플)/공통플랫폼개발팀여기어때

2026년 4월 24일

원문에서 보기 ↗

안녕하세요. 여기어때컴퍼니 공통플랫폼개발팀 플랫폼엔지니어 코플 입니다. 이번 글은 Right-Sizing라는 업무를 진행하면서 기준을 정하고 활용해 얻은 경험을 공유하는 글을 작성했습니다.

Right-Sizing 란 무엇일까?

Right-Sizing이란 Kubernetes 환경에서 각 Pod에 설정된 resources.requests와 limits를 실제 사용 패턴에 맞게 조정하는 작업입니다. 너무 높게 설정된 Request는 클러스터 자원을 불필요하게 점유하고, 너무 낮게 설정된 Request는 OOMKill이나 CPU Throttling으로 이어집니다. 적정한 수준을 찾는 것이 Right-Sizing의 목적입니다.

여기어때컴퍼니는 시스템 복잡도를 파악하고 모니터링하기 위해 Observability를 Self-hosted로 운영하고 있습니다. 수백 개 서비스의 다양한 지표를 계측하기 위해 OpenTelemetry와 Grafana LGTM 스택을 주력으로 활용합니다. LGTM 스택은 로그(Loki), 메트릭(Mimir), 트레이스(Tempo)를 각각 담당하며, 각 역할에 맞는 다수의 컴포넌트가 연계되어 구성됩니다. 그만큼 많은 인프라 리소스를 Observability에 활용 중이기에 각각의 컨퍼넌트 또한 모니터링을 진행하게 됩니다. 옵저버빌리티 인프라의 노드 사용률을 점검하던 중 이런 의문이 들었습니다.

“노드는 꽉 찬 것처럼 보이는데, 실제로 Pod들이 그만큼 쓰고 있는 건가?”

Kubernetes에서 resources.requests는 단순한 설정값이 아닙니다. 스케줄러가 Pod을 노드에 배치할 때 이 값을 기준으로 노드의 가용 용량을 판단합니다. 즉 Pod가 실제로 얼마를 쓰든, requests에 선언된 만큼은 이미 예약된 것으로 처리됩니다.

이 구조에서 over-provisioning은 단순한 낭비를 넘어 클러스터 운영 전반에 영향을 줍니다. 실제 사용률은 낮음에도 requests 합산이 노드 용량에 근접하면 새로운 Pod이 스케줄되지 못하고, 이를 해소하기 위해 노드를 추가해도 실제 활용도는 여전히 낮은 상태가 지속됩니다. 반대로 under-provisioning은 Memory의 경우 OOMKill로, CPU의 경우 Throttling으로 직결됩니다.

초기 구성 당시에는 성능 테스트를 기반으로 Observability의 다양한 컴포넌트의 리소스를 산정했지만, 서비스가 성장하고 트래픽 패턴이 변화하면서 당시 기준이 현재에도 유효한지 검증이 필요한 시점이 되어 있었습니다. 문제는 단순히 “Request가 높다 또는 낮다”는 것이 아니었습니다. 현재 설정값이 적정한지 판단할 수 있는 명확한 정책과 기준이 수립하는 것이 였습니다.

먼저 부딪힌 세 가지 문제

가장 직관적인 접근은 현재 사용량 지표를 기반으로 Request를 조정하는 것입니다. 하지만 이를 실제로 적용하려고 하자 기술적으로 몇가지를 정의해야 했습니다.

첫 번째 문제는 측정 방식에 따라 결론이 달라진다는 것이었습니다. 같은 컴포넌트를 평균(avg)으로 보면 넉넉해 보이고, 최대값(max)으로 보면 위험해 보이는 경우가 있었습니다. 기간을 3개월로 잡으면 안정적으로 보이던 것이 최근 2주로 좁히면 다른 패턴이 나오기도 했습니다. 측정 방식과 기간이 정해지지 않은 상태에서는 같은 데이터를 보고도 전혀 다른 판단을 내릴 수 있었습니다.

두 번째 문제는 컴포넌트마다 리소스 사용 패턴이 전혀 다르다는 것이었습니다. 여기어때에서 운영하고 있는 옵저버빌리티 스택은 역할에 따라 여러 컴포넌트로 구성됩니다. 로그나 메트릭 데이터를 수신하고 저장하는 컴포넌트(Ingester)는 데이터를 일정량 메모리에 쌓았다가 주기적으로 디스크에 내려쓰는 방식으로 동작합니다. 때문에 메모리 사용량이 주기적으로 증가했다가 감소하는 파형 패턴을 보입니다. 오래된 데이터를 정리하고 압축하는 컴포넌트(Compactor)는 대부분의 시간에는 대기 상태이다가 작업이 시작되면 순간적으로 대용량 메모리를 소비하는 버스트 패턴을 보입니다. 반면 데이터를 분산하거나 쿼리 요청을 라우팅하는 경량 컴포넌트(Distributor, Query-frontend)는 이러한 주기적 변동 없이 사용량이 비교적 일정합니다. 이 모든 컴포넌트에 동일한 기준을 적용하면 한쪽은 여전히 낭비, 다른 쪽은 위험한 상황이 됩니다.

세 번째 문제는 Over-provisioning과 Under-provisioning을 동시에 탐지해야 한다는 것이었습니다. 줄이는 것만이 목적이 아닙니다. CPU의 경우, 과다할당으로 보이는 Pod가 실제로는 Throttling 중일 수 있습니다. 이 경우 Request를 내리면 오히려 상황이 악화됩니다.

결국 데이터를 먼저 보는 것이 아니라, 기준을 먼저 정의하는 것이 순서였습니다.

숫자로 기준을 세운다는 것

기준을 세우기 전에 리소스 설정의 대부분을 차지하는 두 가지 리소스의 특성 차이부터 정리했습니다.

너무나도 당연하지만 한 번쯤 정리해봐야 하는 부분입니다.

Memory가 부족하면 OOMKill이 발생해 Pod이 즉시 종료되고 복구 전까지 서비스가 중단됩니다. OOMKill은 Kubernetes가 메모리 부족 상황에서 컨테이너를 강제 종료시키는 메커니즘으로, 종료 전 graceful shutdown 과정 없이 프로세스가 즉시 kill됩니다. 특히 데이터를 메모리에 임시 보관하는 컴포넌트는 종료 시점에 아직 저장되지 않은 데이터가 유실될 수 있습니다. Memory는 한번 부족해지면 자동으로 회복되지 않기 때문에, 버퍼를 충분히 확보하는 것이 필수입니다. 재기동 하면서 다양한 문제를 발생시킬수 있으므로 안정적으로 운영해야 하는 서비스라면 유념해야 하는 부분입니다.

CPU가 부족하면 Linux CFS(Completely Fair Scheduler)의 quota 메커니즘에 의해 Throttling이 발생합니다. 컨테이너에 설정된 CPU Limit을 초과하면 스케줄러가 해당 컨테이너의 CPU 사용을 일시적으로 제한하고, 이로 인해 처리 속도가 느려집니다. 부하가 줄어들면 CPU 사용량이 Limit 이하로 내려가면서 자연스럽게 회복되는 특성이 있습니다. 다만 Throttling이 지속되면 응답 지연이 누적되어 서비스 품질에 영향을 줄 수 있기 때문에, CPU는 낮은 버퍼로 운영하더라도 Throttling 비율을 별도 지표로 반드시 모니터링해야 합니다.

이 차이가 버퍼 전략을 다르게 가져가는 근거입니다. Memory는 부족 시 즉각적이고 비가역적인 영향을 미치므로 안전 마진을 충분히 확보해야 하고, CPU는 자동 회복 특성을 활용해 상대적으로 낮은 버퍼로 운영하면서 Throttling 지표를 통해 실시간으로 상태를 감시하는 전략이 적합하다는 결론에 이르렀습니다.

어떤 숫자를 기준으로 삼을 것인가

Right-Sizing을 시작할 수 있었던 전제 중 하나는, 필요한 데이터가 이미 쌓여 있었다는 점입니다. 여기어때는 서비스 옵저버빌리티를 위해 Grafana Alloy로 Kubernetes 리소스 메트릭을 수집하고 Mimir에 저장하는 파이프라인을 운영 중입니다.

container_memory_working_set_bytes, container_cpu_usage_seconds_total, kube_pod_container_resource_requests 의 지표가 이 구조 위에서 지속적으로 적재되고 있습니다. Right-Sizing을 위해 별도의 에이전트를 추가하거나 새로운 수집 체계를 구성할 필요가 없었습니다. 서비스를 관측하기 위해 구축한 인프라가 인프라 자체를 효율화하는 데 그대로 활용될 수 있었습니다. 이미 수집된 데이터를 어떤 방식으로 집계하느냐, 그 선택이 곧 판단의 출발점이었습니다. 리소스 사용량을 어떤 방식으로 집계하느냐는 결론에 직접적인 영향을 줍니다.

avg_over_time(평균)은 전체 시간대의 사용량을 고르게 반영하지만, 트래픽이 집중되는 피크 구간의 사용량을 과소평가하는 경향이 있습니다. 평소에는 적게 쓰다가 특정 시간대에 급증하는 패턴이 있는 경우 평균만 보면 리소스가 충분해 보이지만 실제로는 부족한 상황이 발생할 수 있습니다.

max_over_time(최대값)은 측정 기간 중 단 한 번이라도 발생한 최고값을 기준으로 삼습니다. JVM의 GC(Garbage Collection) 수행 순간, 컨테이너 초기화 직후의 일시적 스파이크, 메트릭 수집 오류로 인한 이상값 등이 모두 기준에 반영됩니다. 실제 운영에서는 좀처럼 재현되지 않는 순간을 기준으로 리소스를 잡게 되어 과다할당으로 이어질 수 있습니다.

quantile_over_time(0.95), 즉 P95는 전체 측정 데이터 중 상위 5%의 극단값을 제외한 95번째 백분위수를 기준으로 합니다. 예를 들어 1주일간 2,016개의 데이터 포인트가 있다면, 그 중 약 100개의 극단적인 스파이크를 제외한 나머지 최대값이 P95입니다. 일시적 이상값은 걸러내면서도 실제 운영에서 반복적으로 마주치는 최대 부하를 반영할 수 있습니다.

다만 P95가 항상 충분한 것은 아닙니다. 데이터를 디스크에 내려쓰는 flush 작업이나 데이터를 정리·압축하는 compaction처럼 간헐적으로 발생하는 고부하 작업을 수행하는 컴포넌트는 P95가 실제 피크를 과소 추정할 수 있습니다. 이러한 컴포넌트는 max_over_time을 보조 수단으로 병행하여 절대 피크가 설정된 버퍼 범위 안에 드는지 반드시 확인해야 합니다.

Request 를 얼마나 채워야 하는가

측정 방식이 P95로 정해졌다면, 다음 질문은 자연스럽게 이어집니다. “그래서 P95 사용량을 기준으로 메모리 Request를 얼마로 설정해야 하는가?”

이 질문의 방향성은 중요합니다. “현재 Request 대비 사용률이 낮으면 잘라낸다”가 아니라, “P95 사용량이 Request에서 적정 비율을 차지하도록 역산한다”는 방향입니다. 목표 사용률을 먼저 정하고, 그에 맞는 Request를 계산하는 구조입니다.

적정 Request = P95 사용량 / 목표 사용률

예를 들어 P95 사용량이 250Mi이고 목표 사용률을 80%로 잡으면, 적정 Request는 약 312Mi입니다. 현재 1,000Mi로 설정되어 있다면 약 3.2배 과할당 상태이며, 312Mi 수준으로 조정할 수 있다는 판단 근거가 생깁니다.

그렇다면 목표 사용률을 왜 100%가 아닌 70~80% 수준으로 잡아야 하는가. 여기에는 두 가지 이유가 있습니다. 첫째, P95는 이미 상위 5%의 극단값을 제외한 수치이므로, Request가 P95에 정확히 맞춰져 있으면 나머지 5% 피크 상황에서 실제로 Request를 초과할 수 있습니다. 둘째, 배포나 트래픽 변화 등 예측하지 못한 상황에 대응할 안전 마진이 필요합니다. 그리고 이 목표 사용률은 컴포넌트 특성에 따라 달리 적용해야 합니다.

기간을 정하는 것도 판단이다

Right-Sizing을 진행하면서 두 가지 기간을 정해야 했습니다. 먼저 데이터 계측의 기간, 즉 측정 기간, 그리고 샘플링 간격 두 가지였습니다. 측정 기간은 처음부터 1주일로 정해진 것이 아니었습니다. 3개월, 1개월, 2주, 1주 등 다양한 기간의 데이터를 직접 비교하며 확인했습니다.

3개월 데이터를 놓고 보면 사용량이 전반적으로 안정적으로 보이는 컴포넌트들이 있었습니다. 그런데 같은 컴포넌트를 최근 2주로 좁혀 보면 특정 배포 이후 메모리 사용 패턴이 바뀐 것이 눈에 띄었습니다. 3개월 평균이 현재 상태를 희석하고 있었던 것입니다. 반대로 2주 데이터만 기준으로 삼으면 프로모션 기간이나 트래픽 집중 이벤트가 포함될 경우 비정상적으로 높은 값이 기준에 반영될 위험이 있었습니다.

여러 기간을 비교한 결과, 1주일을 기본 측정 기간으로 결정했습니다. 평일/주말 트래픽 패턴 차이를 모두 포함하면서도 최근 운영 상태를 충분히 반영할 수 있는 기간이기 때문입니다. 단, 1주일 스냅샷이 특정 이벤트 기간과 겹칠 수 있으므로 1개월 단위 데이터와 교차 검토하여 이상치를 걸러내는 방식으로 보완했습니다.

데이터를 집계하는 샘플링 간격은 5분을 선택했습니다. 간격이 좁을수록 정밀도는 높아지지만 쿼리 부하가 증가하고, 넓을수록 쿼리는 가벼워지지만 단기 패턴을 놓칠 수 있습니다. 1분 간격은 1주일 기준 약 10,080개의 데이터 포인트를 생성하지만 P95를 사용하는 이상 극단값은 자연스럽게 필터링되므로 과도한 정밀도입니다. 15분 간격은 1주일 기준 약 672개로 줄어들어 10~15분 내에 완료되는 짧은 flush 사이클이나 burst 패턴을 놓칠 수 있습니다. 5분 간격은 1주일 기준 약 2,016개의 데이터 포인트를 확보하면서 쿼리 성능에 부담이 없는 균형점입니다.

컨퍼넌트별로 같은 버퍼를 쓰면 안 되는 이유

앞서 목표 사용률을 기준으로 Request를 역산하는 방식을 정리했습니다. 그렇다면 목표 사용률, 즉 버퍼를 얼마로 잡을 것인가. 전체 컴포넌트에 단일 버퍼율을 적용하는 것이 가장 단순한 접근이지만, 컴포넌트마다 OOM 발생 시 영향도와 리소스 사용 패턴이 전혀 다르기 때문에 그 방식은 적합하지 않았습니다. 중요한 것은 버퍼 수치 자체가 아니라 각 컴포넌트의 동작 특성을 파악하고 그에 맞는 기준을 반영하는 것입니다.

여기서 버퍼는 P95 사용량을 기준으로 적정 Request를 역산할 때 적용하는 안전 마진입니다. 예를 들어 Ingester의 Memory 버퍼 +50%는 목표 사용률을 약 67%(1 / 1.5)로 설정하는 것과 동일합니다. 즉 P95 사용량이 Request의 67% 수준이 되도록 Request를 잡는다는 의미입니다.

데이터를 수신해 메모리에 임시 보관하다가 주기적으로 저장소에 flush하는 컴포넌트(Ingester)는 flush 전에 OOMKill이 발생하면 아직 저장되지 않은 데이터가 유실될 수 있습니다. 데이터를 압축·정리하는 컴포넌트(Compactor)는 작업 특성상 간헐적으로 대용량 메모리를 사용하기 때문에 P95 기준만으로는 실제 피크를 과소 추정할 가능성이 있습니다. 이처럼 상태를 유지하고 쓰기 경로에 위치한 컴포넌트는 OOM의 결과가 단순한 재시작 이상의 영향을 미치기 때문에 가장 높은 버퍼를 적용했습니다.

반면 요청을 분산하거나 라우팅하는 컴포넌트(Distributor, Query-frontend)는 상태를 유지하지 않고 수평 확장이 용이하며 재시작 영향도 낮습니다. 리소스 사용 패턴도 비교적 일정하여 낮은 버퍼로도 안정적인 운영이 가능합니다.

이 버퍼 수치가 근거 없이 정해진 것은 아닙니다. Grafana 공식 문서는 Mimir 컴포넌트 sizing 권장치를 p90 활용률 기준으로 제시하는데, Ingester처럼 데이터 유실 위험이 있는 쓰기 경로 컴포넌트에 대해 +50% 버퍼를 권장합니다. AWS Compute Optimizer의 Balanced 프로필은 P95 기준 약 57% 목표 사용률을 적용하고, GKE VPA는 최대값 기준 +25% 버퍼를 두어 Stateless 컴포넌트 수준의 여유를 권장합니다. 접근 방식은 다르지만 세 곳 모두 “피크에 100%를 채우지 않는다”는 전제로 수렴합니다.

다만 벤더 권장치는 특정 컴포넌트 유형에 맞춰진 값이거나 일괄 적용을 전제로 한 수치입니다. Mimir의 +50%를 Stateless 컴포넌트에 그대로 적용하면 불필요한 과할당이 남고, GKE VPA의 +25%를 Ingester에 적용하면 버스트 피크를 버퍼가 흡수하지 못할 수 있습니다. 결국 각 컴포넌트의 동작 방식과 장애 발생 시 영향도를 직접 분석하여 분류별로 차등 적용하는 방식을 선택했습니다.

기준을 확인하다

기준이 정의되면 이를 실제로 측정할 쿼리가 필요합니다. Memory와 CPU 사용률 쿼리, 그리고 CPU Throttling 탐지 쿼리 세 가지를 작성했으며, CPU는 두 쿼리를 반드시 함께 해석해야 합니다.

Memory 사용률 측정

100 *
quantile_over_time(0.95,
  (
    sum by (namespace, pod) (
      container_memory_working_set_bytes{
        namespace=~"<네임스페이스>",
        container!=""
      }
    )
  )[$__range:5m]
)
/
avg_over_time(
  (
    sum by (namespace, pod) (
      kube_pod_container_resource_requests{
        namespace=~"<네임스페이스>",
        resource="memory",
        container!=""
      }
    )
  )[$__range:5m]
)

container_memory_working_set_bytes는 OOM 판단 기준과 완전히 동일하지는 않지만,실제 메모리 압박을 비교적 잘 반영하는 지표이기 때문에 Right-Sizing 기준으로 활용했습니다. RSS와 달리 커널이 회수 불가능한 메모리를 포함하여 실제 메모리 압박을 정확히 반영합니다.

쿼리 결과는 P95 사용량이 현재 Request에서 차지하는 비율(%)입니다. 이 값을 목표 사용률로 나누면 적정 Request를 역산할 수 있습니다.

쿼리 결과 = 25% (P95 사용량이 Request의 25% 수준)

→ P95 실제 사용량 = Request × 0.25
→ 적정 Request (Stateless 기준, 목표 사용률 80%) = P95 사용량 / 0.8
→ 현재 Request 대비 약 3.2배 과할당 → 조정 대상

컴포넌트 분류에 따라 목표 사용률이 다르므로, 쿼리 결과를 해석할 때 해당 컴포넌트가 어느 분류에 속하는지 먼저 확인해야 합니다.

CPU 사용률 측정

CPU 사용률 쿼리는 단독으로 판단하면 안 됩니다. 사용률이 낮게 나오더라도 동시에 Throttling 중이라면 오히려 Request 상향이 필요한 상황일 수 있기 때문입니다.

100 *
quantile_over_time(0.95,
  (
    sum by (namespace, pod) (
      rate(container_cpu_usage_seconds_total{
        namespace=~"<네임스페이스>",
        container!=""
      }[2m])
    )
  )[$__range:5m]
)
/
avg_over_time(
  (
    sum by (namespace, pod) (
      kube_pod_container_resource_requests{
        namespace=~"<네임스페이스>",
        resource="cpu",
        container!=""
      }
    )
  )[$__range:5m]
)

CPU Throttling 탐지

전체 CFS 스케줄링 주기 중 CPU quota 초과로 Throttling이 발생한 비율을 계산합니다. 두 쿼리를 조합하면 조치 방향이 명확해집니다.

100 *
sum by (namespace, pod) (
  rate(container_cpu_cfs_throttled_periods_total{
    namespace=~"<네임스페이스>"
  }[$__range])
)
/
sum by (namespace, pod) (
  rate(container_cpu_cfs_periods_total{
    namespace=~"<네임스페이스>"
  }[$__range])
)

$__range는 Grafana Dashboard 변수로, Grafana Panel 내에서만 동작합니다. Recording Rule이나 API 직접 호출 등 Grafana 외부에서 사용할 경우 $__range 대신 측정 기간을 명시적으로 지정해야 합니다. 결과는 Throttling 발생 비율(%)이며, 아래 기준표를 참고하여 해석합니다.

기준을 되돌릴 조건(롤백의 기준)

기준과 쿼리가 준비되었다고 해서 한꺼번에 적용하는 것은 바람직하지 않습니다. 문제가 생겼을 때 원인을 특정하기 어렵기 때문입니다. 적용 우선순위는 장애 발생 시 영향도와 복구 난이도를 기준으로 결정했으며, 각 단계마다 되돌아갈 조건을 사전에 정의해두는 것이 핵심입니다.

상태를 유지하지 않는 컴포넌트(Stateless)는 재시작 시 데이터 유실 위험이 없고 수평 확장이 용이하므로 가장 먼저 적용합니다. 상태를 유지하지만 읽기 경로에 위치한 컴포넌트(Stateful 읽기)는 장애 시 서비스 중단보다 Latency 영향에 그치는 경우가 많아 두 번째로 적용합니다. 상태를 유지하며 쓰기 경로에 위치한 컴포넌트(Stateful 쓰기)는 OOM 발생 시 데이터 유실 가능성이 있어 충분한 검증 후 마지막으로 적용합니다.

1순위: Stateless 컴포넌트 (Distributor, Query-frontend 등)
2순위: Stateful 읽기 컴포넌트 (Store-gateway, Querier 등)
3순위: Stateful 쓰기 컴포넌트 (Ingester 등, 충분한 검증 후)
4순위: 버스트 패턴 컴포넌트 (Compactor 등, 마지막 적용)

각 단계마다 개발 환경에서 최소 3~7일 검증 후 운영에 반영했습니다.

롤백 기준은 적용 전에 명확하게 정의해두는 것이 중요합니다.

이 과정을 분기별 정기 점검 항목으로 편입했습니다. 기준이 수립된 이후에는 쿼리를 돌리고 기준에 따라 판단하는 것으로 충분하기 때문입니다. 서비스가 성장하고 트래픽 패턴이 변화하면 적정값도 달라지므로, 주기적인 재검토가 필요합니다.

결과

이 기준을 실제로 적용한 결과 옵저버빌리티에 활용되고 있는 다양한 컨퍼넌트의 인프라의 리소스를 절감할 수 있었습니다. 또한 단순히 Request 수치를 낮춘 것이 아니라, 컴포넌트 특성에 맞는 기준을 수립하고 그에 따라 기준을 확정할 수 있었습니다. Right-Sizing 적용으로 인해서 발생을 우려했던 OOMKill이나 Throttling 증가 없이 안정적으로 운영되고 있다는 점에서, 줄이는 동시에 가용성을 확보했다는 부분에서 리소스 절감과 가용성 두가지 결과를 얻을수 있었습니다.

마치며

단순하게 Right-Sizing은 리소스를 줄이는 최적화 작업처럼 보이지만, 실제로 접근해보면 그 본질은 여러 층위에 걸쳐 있습니다. 현재 설정의 적정성을 판단할 수 있는 기준을 수립하는 일이기도 하고, 컴포넌트의 동작 특성을 이해하는 일이기도 하며, Over-provisioning과 Under-provisioning 양방향의 위험을 동시에 관리하는 일이기도 합니다.

여기어때에서 플랫폼엔지니어의 업무는 여행이라는 서비스 생태계속에서 다양한 기준을 제시하고 설정해나가는 일이기도 합니다. 단순히 상황에 그때 그때 대처하는 것은 지속적으로 변화하는 서비스와 기술환경에서 매번 해법을 찾는 걸림돌로 작용합니다. 명확하고 잘 정의된 기준이 정해지면 다음의 업무를 단순화하고 빠른 결정과 실행력을 얻게 됩니다. 앞에서 말씀드린 Right-Sizing를 진행하면서 만든 기준으로 다음 리소스 점검부터는 단순히 쿼리를 돌리고 판단하는 것으로 충분해집니다.

지금까지 여기어때에서 Right-Sizing 라는 주제로 기준을 정의해보는 방식에 대해서 공유 드렸습니다. 기준과 정책을 정의하기 위해서 고심하시는 분들에게 작게나마 도움이 되셨으면 합니다. 긴글 읽어주셔서 감사합니다.