Serverless는 “서버를 신경 쓰지 않아도 되는” 실행 모델로 알려져 있습니다. 요청이 없을 때는 컴퓨팅 자원을 줄이거나 제거해 비용을 아낄 수 있고, 요청이 들어오면 필요한 만큼 빠르게 실행 환경을 늘립니다. 개발자는 인프라보다 코드와 비즈니스 로직에 집중할 수 있습니다.
하지만 이 효율적인 구조에는 역설이 있습니다.
요청이 없을 때는 비용이 줄어들지만, 다시 요청이 들어오는 순간 사용자는 기다려야 할 수 있습니다.
그 원인은 cold start입니다.
Serverless에서 cold start가 발생하는 순간
함수가 오랫동안 호출되지 않으면 플랫폼은 비용 절감을 위해 해당 함수의 실행 환경을 메모리에서 제거합니다. 이후 새로운 요청이 들어오면 단순히 코드를 실행하는 것이 아니라, 실행에 필요한 환경 전체를 다시 준비해야 합니다.
일반적으로 다음 과정이 포함됩니다.
- 함수 실행 인스턴스 또는 컨테이너 생성
- 런타임 초기화
- 코드와 의존성 로드
- 환경 변수·네트워크·권한 설정
- 함수 코드 실행
이미 준비된 warm 인스턴스가 있다면 요청은 바로 실행될 수 있습니다. 반면 실행 환경이 제거된 상태라면 초기 준비 비용이 추가되며, 이것이 cold start 지연으로 이어집니다.
특히 다음과 같은 워크로드에서 체감 문제가 커집니다.
- 간헐적으로 호출되는 API 함수
- 주기적으로 실행되는 스케줄러 함수
- 이벤트 기반 데이터 처리
- 갑작스러운 트래픽 급증이 발생하는 서비스
- 여러 함수가 순차적으로 연결된 주문·결제·알림 워크플로우
사용자 입장에서는 첫 화면이 늦게 열리거나, 결제 요청이 평소보다 오래 걸리거나, 알림 처리가 늦어지는 경험으로 나타날 수 있습니다.
함수를 계속 켜두면 해결될까?
가장 직관적인 해결책은 간단합니다. 함수 인스턴스를 메모리에 오래 유지하면 됩니다. 이를 보통 warm 유지 또는 keep-alive 전략이라고 합니다.
예를 들어 모든 함수를 마지막 호출 후 10분 동안 유지하면, 그 시간 안에 다시 호출되는 함수는 cold start 없이 실행할 가능성이 높아집니다. 그러나 이 방식은 또 다른 문제를 만듭니다.
호출되지 않는 함수까지 메모리를 점유하게 됩니다.
함수가 수십 개라면 큰 문제가 아닐 수 있습니다. 하지만 수천 개 이상의 함수가 실행되는 Serverless 플랫폼에서는 상황이 달라집니다. 낮은 우선순위의 유휴 함수가 메모리를 계속 차지하면, 실제로 곧 호출될 중요한 함수가 배치될 공간이 부족해질 수 있습니다.
고정 keep-alive 정책은 함수별 특성을 구분하지 못한다는 한계도 있습니다.
| 함수 상황 | 고정 warm 유지의 문제 |
|---|---|
| 1분마다 호출되는 함수 | 유지 시간이 짧으면 반복적으로 cold start 발생 |
| 30분마다 호출되는 함수 | 유지 시간이 길면 대부분의 시간이 메모리 낭비 |
| 짧은 burst 후 조용해지는 함수 | burst 종료 후에도 불필요하게 계속 유지 |
| 불규칙한 이벤트 함수 | 단순 시간 기준만으로 다음 호출을 판단하기 어려움 |
결국 cold start를 줄이기 위해 인스턴스를 오래 유지하면 메모리 낭비가 늘고, 메모리를 아끼기 위해 빠르게 제거하면 cold start가 늘어납니다.
Serverless의 핵심 과제는 “얼마나 오래”가 아니라 “언제”다
이 문제를 제대로 풀려면 모든 함수를 동일하게 관리해서는 안 됩니다. 중요한 질문은 다음과 같습니다.
- 이 함수는 다음에 언제 호출될 가능성이 높은가?
- 지금 미리 실행 환경을 준비할 가치가 있는가?
- 메모리가 부족하다면 어떤 함수를 먼저 제거해야 하는가?
- 여러 worker 중 어느 곳에 함수를 배치해야 균형이 맞는가?
즉, Serverless 운영의 핵심은 단순히 함수를 오래 켜두는 일이 아닙니다. 필요한 함수만, 필요한 시점에, 필요한 위치에 유지하는 일에 가깝습니다.
이 지점에서 예측 기반 스케줄링이 중요해집니다. 함수의 과거 호출 기록을 분석해 규칙적인 호출, 짧은 시간의 연속 호출, 특정 함수 뒤에 이어지는 호출 등을 구분할 수 있다면, 무작정 메모리를 늘리지 않고도 cold start를 줄일 수 있기 때문입니다.
다음 섹션에서는 이러한 균형 문제를 해결하기 위해 등장한 SPES-Ext가 함수 호출 패턴을 어떻게 이해하고, prewarming·eviction·worker 배치를 하나의 정책으로 결합하는지 살펴보겠습니다.
Serverless 함수의 호출 리듬을 읽다: 다음 요청은 언제 올까?
함수 호출 횟수가 많다는 사실만으로는 다음 요청 시점을 알 수 없습니다. 같은 100건의 호출이라도, 1분 안에 몰려 발생한 100건과 하루 동안 일정하게 분산된 100건은 완전히 다른 대응이 필요합니다.
Serverless 환경에서 중요한 것은 단순한 호출 빈도가 아니라 호출과 호출 사이에 나타나는 리듬입니다. 짧은 공백 뒤에 다시 이어지는 요청은 하나의 burst가 계속되는 신호일 수 있습니다. 반면, 긴 침묵 뒤의 호출은 새로운 burst의 시작일 가능성이 큽니다.
SPES-Ext는 바로 이 ‘빈 구간’을 분석합니다.
Serverless 호출 간격보다 중요한 Waiting Time
일반적인 분석은 두 호출 사이의 시간 차이, 즉 inter-arrival time에 집중합니다. 하지만 이 방식만으로는 연속 호출과 긴 휴지 구간을 충분히 구분하기 어렵습니다.
예를 들어 함수 호출이 다음처럼 발생한다고 가정해 보겠습니다.
호출 → 짧은 공백 → 호출 → 호출 → 긴 공백 → 호출
여기서 두 번째와 세 번째 호출 사이의 짧은 공백은 함수가 아직 활성 작업 흐름 안에 있다는 뜻일 수 있습니다. 이때 실행 환경을 제거하면 바로 다음 요청이 cold start를 겪을 가능성이 높습니다.
반대로 연속 호출이 끝난 뒤 오랫동안 아무 요청도 없다면 상황은 달라집니다. 이 구간에서는 warm 상태를 계속 유지하는 것이 메모리 낭비가 될 수 있습니다.
SPES-Ext는 이를 구분하기 위해 Waiting Time(WT) 을 사용합니다. Waiting Time은 단순히 “마지막 호출 이후 얼마나 지났는가”를 재는 값이 아닙니다. 호출이 없는 연속 구간을 기록해, 현재의 공백이 다음 중 어디에 가까운지 판단합니다.
- 아직 끝나지 않은 burst 사이의 짧은 숨 고르기
- 반복 패턴에서 나타나는 예측 가능한 대기 시간
- 이전 작업이 끝난 뒤의 긴 유휴 구간
- 다음 호출 시점을 판단하기 어려운 불규칙한 공백
이 차이는 Serverless 스케줄러가 함수를 계속 warm 상태로 유지할지, 미리 다시 로드할지, 메모리에서 제거할지 결정하는 핵심 근거가 됩니다.
Serverless burst의 끝과 시작을 구분하는 방법
SPES-Ext의 관점에서 함수 호출은 하나의 점들이 아니라, 시간축 위에 만들어지는 여러 개의 묶음입니다. 짧은 시간에 호출이 집중되는 묶음을 burst 또는 wave로 볼 수 있습니다.
이 관점이 중요한 이유는 명확합니다.
| 호출 상황 | 단순 keep-alive 정책 | SPES-Ext의 해석 |
|---|---|---|
| 짧은 공백 뒤 재호출 | 타이머가 끝나면 제거될 수 있음 | 같은 burst일 가능성을 고려해 warm 유지 |
| 일정 주기의 반복 호출 | 고정 시간 설정에 의존 | 과거 waiting time으로 다음 호출 시점 예측 |
| 긴 유휴 시간 | 불필요하게 메모리에 남을 수 있음 | burst 종료 신호로 보고 eviction 우선순위 상승 |
| 갑작스러운 호출 집중 | 미리 준비하지 못하면 cold start 발생 | 유사한 패턴과 상관관계를 활용해 prewarming 검토 |
예를 들어 매일 특정 시간대에 배치 작업이 실행되는 함수가 있다고 해보겠습니다. 호출 사이의 간격이 대체로 일정하다면 SPES-Ext는 과거 waiting time의 중앙값이나 자주 나타나는 값을 바탕으로 다음 호출 시점을 추정할 수 있습니다.
반면, 주문 처리처럼 짧은 시간 동안 요청이 연달아 들어오는 함수는 다른 접근이 필요합니다. 첫 호출 이후 짧은 공백이 보인다고 해서 즉시 실행 환경을 제거하면 안 됩니다. 후속 요청이 이어질 가능성이 높기 때문입니다.
Serverless 예측은 “언제 꺼야 하는가”까지 포함한다
예측형 스케줄링을 이야기하면 흔히 prewarming만 떠올립니다. 하지만 Serverless 운영에서 더 어려운 문제는 “언제 미리 켤까?”만이 아닙니다. 제한된 메모리 안에서 “무엇을 먼저 꺼야 할까?”도 함께 결정해야 합니다.
SPES-Ext는 함수의 waiting time, 다음 호출 예측값, 예측 신뢰도, 메모리 사용량을 함께 고려합니다. 다음 호출이 임박했고 패턴도 안정적인 함수는 보호합니다. 반대로 호출 시점이 멀고 예측 신뢰도까지 낮은 함수는 eviction 후보가 됩니다.
즉, 빈 구간은 단순한 무활동 시간이 아닙니다. SPES-Ext에게 빈 구간은 다음 요청을 준비할지, 현재 메모리를 회수할지 판단하게 만드는 중요한 운영 신호입니다.
Serverless 환경에서 좋은 스케줄러는 호출이 발생한 순간만 보는 것이 아니라, 호출과 호출 사이의 침묵까지 읽어야 합니다.
Serverless 미리 깨울까, 지금 내릴까: 우선순위가 만드는 함수의 생명주기
메모리가 부족한 순간, 가장 오래된 함수를 무조건 내리는 것이 최선일까요?
전통적인 FIFO 방식이라면 답은 “그렇다”에 가깝습니다. 먼저 올라온 함수, 오래 사용되지 않은 함수를 순서대로 제거하면 구현이 단순하기 때문입니다. 하지만 Serverless 환경에서는 오래 메모리에 있었다는 사실만으로 제거 대상이라고 판단하기 어렵습니다.
예를 들어 1시간 동안 대기 중이던 결제 함수가 30초 뒤 주문 처리 함수의 호출에 이어 실행될 가능성이 높다면, 이를 지금 제거하는 선택은 곧 cold start로 이어질 수 있습니다. 반대로 방금 로드됐더라도 호출 패턴이 불명확하고 예측 신뢰도가 낮은 함수라면, 제한된 메모리를 차지하게 둘 이유가 적습니다.
SPES-Ext는 바로 이 문제를 우선순위 기반 함수 생명주기 관리로 풀어냅니다.
Serverless에서 “오래된 함수”보다 중요한 판단 기준
SPES-Ext의 핵심은 함수 인스턴스를 단순히 warm 또는 cold 상태로만 보지 않는 데 있습니다. 각 함수에 대해 다음 정보를 지속적으로 추적합니다.
- 현재 메모리에 로드되어 있는지
- 마지막 호출 이후 얼마나 시간이 지났는지
- 다음 호출이 언제 일어날 것으로 예상되는지
- 예측의 신뢰도가 얼마나 높은지
- 함수가 소비하는 메모리 크기
- 다른 함수 호출과 연관성이 있는지
- 현재 실행 중인지, 아니면 대기 상태인지
이 정보가 쌓이면 스케줄러는 “오래된 함수”가 아니라 지금 메모리를 유지할 가치가 낮은 함수를 찾아낼 수 있습니다.
가령 두 함수가 있다고 가정해 보겠습니다.
| 함수 | 마지막 호출 | 다음 호출 예측 | 예측 신뢰도 | 메모리 | 판단 |
|---|---|---|---|---|---|
| 결제 함수 | 20분 전 | 1분 뒤 | 높음 | 256MB | 유지 |
| 테스트 알림 함수 | 2분 전 | 예측 불가 | 낮음 | 512MB | 우선 제거 |
FIFO만 적용하면 20분 전에 호출된 결제 함수가 먼저 제거될 수 있습니다. 그러나 SPES-Ext는 1분 뒤 호출될 가능성이 높은 결제 함수를 살려두고, 더 큰 메모리를 사용하면서도 미래 호출 가능성이 불확실한 테스트 알림 함수를 먼저 정리합니다.
이 차이가 Serverless cold start와 메모리 낭비를 동시에 줄이는 핵심입니다.
Serverless prewarming: 호출 직전에만 미리 깨운다
SPES-Ext는 모든 함수를 계속 warm 상태로 유지하지 않습니다. 대신 다음 호출 시점을 예측하고, 호출이 가까워졌을 때만 실행 환경을 미리 준비합니다.
논문 실험에서는 θprewarm = 2분이라는 prewarming window를 사용했습니다. 즉, 특정 함수의 다음 호출이 약 2분 안에 일어날 것으로 예측되면, 그 전에 함수 인스턴스를 메모리에 올리는 방식입니다.
현재 시각 ──────────────── 예상 호출 시각
← 2분 →
prewarming 시작
이 전략은 단순 keep-alive 방식과 다릅니다.
- 고정 keep-alive: 마지막 호출 후 10분 동안 모든 함수를 유지
- SPES-Ext: 다음 호출 가능성이 높은 시점에만 필요한 함수를 준비
고정 keep-alive는 예측이 필요 없다는 장점이 있지만, 호출되지 않을 함수까지 오랫동안 메모리를 점유합니다. 반면 SPES-Ext는 함수별 호출 간격, burst 패턴, 반복 주기, workflow 상관관계를 활용해 prewarming 대상을 좁힙니다.
예를 들어 매일 오전 9시 전후로 실행되는 정산 함수는 8시 58분부터 준비할 수 있습니다. 주문 함수 호출 후 수 초 내 결제 함수가 뒤따르는 workflow라면, 주문 함수의 실행 자체가 결제 함수를 미리 깨우는 신호가 될 수 있습니다.
Serverless eviction: 무엇을 먼저 내려야 하는가
메모리가 부족해지면 스케줄러는 새로운 함수를 위한 공간을 만들어야 합니다. 이때 SPES-Ext는 모든 함수를 동등하게 취급하지 않고, 우선순위를 계산해 eviction 대상을 선택합니다.
일반적으로 먼저 제거될 가능성이 높은 대상은 다음과 같습니다.
- 다음 호출까지 시간이 많이 남은 함수
- 호출 예측의 신뢰도가 낮은 함수
- 호출 간격의 변동성이 큰 함수
- 많은 메모리를 점유하는 함수
- 현재 실행 중이 아닌 대기 함수
반대로 제거를 최대한 피해야 하는 대상도 명확합니다.
- 현재 요청을 처리 중인 함수
- 곧 호출될 것으로 예측된 함수
- 규칙적인 호출 이력이 있어 예측 신뢰도가 높은 함수
- 다른 함수 호출로 인해 후속 실행이 예상되는 함수
이 정책은 “먼저 들어온 함수를 먼저 내보낸다”는 단순한 규칙을 넘어섭니다. Serverless 플랫폼 입장에서는 메모리 공간 자체보다, 다음 요청에서 cold start가 발생할 확률이 더 중요한 의사결정 기준이 되는 셈입니다.
오래된 함수라고 해서 가치가 낮은 것은 아닙니다.
SPES-Ext는 미래 요청에 가장 덜 도움이 될 함수를 먼저 제거합니다.
호출 패턴이 우선순위를 바꾸는 이유
SPES-Ext는 함수별 호출 기록을 단순한 횟수가 아니라 호출 사이의 시간 구조로 해석합니다. 특히 호출이 없는 구간을 waiting time으로 분석해, 단일 요청 사이의 짧은 공백과 burst 종료 후의 긴 유휴 시간을 구분합니다.
이 구분은 eviction 판단에 직접 영향을 줍니다.
- 짧은 공백 뒤 반복 호출이 이어지는 함수는 계속 warm 상태를 유지할 가치가 큽니다.
- 특정 시간에 집중 호출된 뒤 장시간 조용한 함수는 burst 종료 후 빠르게 제거할 수 있습니다.
- 주기적으로 호출되는 함수는 다음 실행 직전에만 prewarming하면 됩니다.
- 호출 이력이 부족한 함수는 보수적으로 다루되, 메모리 압박 상황에서는 우선순위를 낮출 수 있습니다.
결국 SPES-Ext의 함수 생명주기는 하나의 고정 타이머로 결정되지 않습니다. 함수마다 서로 다른 호출 특성과 예측 신뢰도를 반영해, 언제 깨우고 언제 내릴지를 다르게 결정합니다.
메모리 부족은 단순한 삭제 문제가 아니다
Serverless 운영에서 메모리 부족은 단순히 “무언가를 삭제해야 하는 상황”이 아닙니다. 어떤 함수를 내리느냐에 따라 다음 요청의 지연시간, 전체 메모리 효율, worker 간 부하 균형이 달라집니다.
SPES-Ext는 이 선택을 우선순위 문제로 바꿉니다.
- 호출이 임박한 함수는 보호하고
- 예측 신뢰도가 낮은 함수는 정리하며
- 필요한 함수만 적절한 시점에 미리 로드하고
- 남은 메모리가 많은 worker에 우선 배치합니다
이 접근의 핵심은 명확합니다. Serverless의 효율은 얼마나 많은 함수를 오래 켜두느냐가 아니라, 어떤 함수를 언제까지 살려둘지 정확히 판단하는 능력에서 나온다는 것입니다.
Serverless 여섯 개 worker의 메모리 전쟁: 좋은 예측만으로는 부족하다
함수를 미리 준비했다고 해서 Serverless 시스템이 곧바로 빨라지는 것은 아닙니다. prewarming된 실행 환경이 특정 worker에 몰리면, 그 worker는 먼저 메모리가 고갈되고 다른 worker는 상대적으로 여유가 남는 문제가 생깁니다. 결국 새 요청은 실행 가능한 여유 자원이 없는 worker 앞에서 대기하거나, 이미 준비해 둔 함수를 제거해야 합니다.
SPES-Ext가 주목할 만한 이유는 함수의 다음 호출 시점만 예측하는 데서 멈추지 않기 때문입니다. 이 스케줄러는 어떤 함수를 warm 상태로 유지할지뿐 아니라, 어느 worker에 배치할지, 그리고 메모리가 부족할 때 무엇을 포기할지까지 함께 결정합니다.
여유 메모리가 가장 큰 worker를 우선 선택한다
SPES-Ext는 새로운 함수 실행 환경을 로드해야 할 때, 기본적으로 남은 메모리가 가장 많은 worker를 우선 선택합니다.
예를 들어 여섯 개 worker가 있고, 각 worker의 남은 메모리 상태가 다음과 같다고 가정해 보겠습니다.
| Worker | 남은 메모리 | 상태 |
|---|---|---|
| Worker A | 15% | 거의 포화 |
| Worker B | 28% | 사용량 높음 |
| Worker C | 46% | 보통 |
| Worker D | 71% | 여유 있음 |
| Worker E | 39% | 보통 |
| Worker F | 63% | 여유 있음 |
새로운 함수 인스턴스를 prewarming해야 한다면, SPES-Ext는 Worker D를 우선 선택합니다. 단순한 규칙처럼 보이지만, 이 선택은 여러 함수의 warm 인스턴스가 한 곳에 쌓이는 현상을 줄이는 데 중요합니다.
기존의 hash 기반 배치는 같은 함수가 특정 worker로 계속 향하도록 만들 수 있습니다. Round-robin도 요청 순서만 고려할 뿐, 각 worker의 실제 메모리 상황을 충분히 반영하지 못합니다. 반면 SPES-Ext는 매 배치 시점에 메모리 여유를 확인하기 때문에, 현재 자원 상태에 맞춰 함수 인스턴스를 분산할 수 있습니다.
메모리가 부족하면 모든 warm 함수를 동등하게 보호하지 않는다
가장 어려운 상황은 모든 worker의 메모리가 빠듯한 경우입니다. 이때 Serverless 플랫폼은 새 함수 실행 환경을 만들기 위해 기존 인스턴스 일부를 제거해야 합니다.
SPES-Ext는 단순히 “가장 오래된 함수”를 제거하지 않습니다. 대신 함수마다 앞으로의 가치가 다르다고 판단합니다.
우선 보호 대상은 다음과 같습니다.
- 현재 요청을 처리 중인 함수
- 곧 호출될 가능성이 높은 함수
- 예측 신뢰도가 높은 주기적 함수
- workflow의 다음 단계에서 곧 실행될 가능성이 큰 상관관계 함수
- 이미 cold start 비용이 큰 실행 환경
반대로 제거 우선순위가 높아지는 대상은 다음과 같습니다.
- 다음 호출까지 긴 시간이 남은 함수
- 호출 패턴이 불규칙하고 예측 신뢰도가 낮은 함수
- 미리 로드됐지만 실제 호출로 이어질 가능성이 낮은 함수
- 메모리를 많이 차지하면서 유휴 상태인 함수
- 현재 실행 중이지 않은 pending 인스턴스
즉, SPES-Ext가 포기하는 것은 단순히 오래된 함수가 아니라 가까운 미래에 사용할 가능성이 낮은 메모리 점유입니다.
FIFO eviction이 놓치는 중요한 맥락
FIFO 방식은 먼저 메모리에 들어온 함수를 먼저 제거합니다. 구현은 쉽지만, Serverless 호출 패턴의 맥락을 이해하지 못한다는 한계가 있습니다.
가령 어떤 결제 함수가 매일 특정 시간대에 반복 호출되고 있으며, 다음 호출이 몇 초 또는 몇 분 뒤로 예측된다고 가정해 보겠습니다. 이 함수가 오래 warm 상태였다는 이유만으로 제거하면, 곧 도착할 요청은 다시 cold start를 겪습니다.
반대로 방금 prewarming된 함수라도 호출 예측이 빗나갔고, 다음 호출 가능성이 낮아졌다면 계속 메모리에 둘 이유가 없습니다. SPES-Ext는 이런 차이를 반영합니다.
중요한 질문은 “얼마나 오래 메모리에 있었는가”가 아니라, “이 메모리를 앞으로 얼마나 빨리 다시 사용할 것인가”입니다.
이 관점은 warm 인스턴스를 캐시처럼 다루는 기존 정책보다 더 적극적인 자원 관리 방식입니다.
prewarming과 즉시 요청이 충돌할 때의 우선순위
메모리가 제한된 환경에서는 미래를 준비하는 작업과 현재 요청을 처리하는 작업이 충돌할 수 있습니다. 예를 들어, 어떤 함수는 곧 호출될 것으로 예측돼 prewarming 대상이지만, 다른 함수에서는 실제 요청이 지금 막 들어왔을 수 있습니다.
SPES-Ext는 이 상황에서 즉시 실행해야 하는 요청을 prewarming보다 우선합니다. 미래의 cold start를 줄이는 것도 중요하지만, 현재 사용자 요청의 지연을 늘리면서까지 사전 준비를 강행하는 것은 적절하지 않기 때문입니다.
이 우선순위는 다음처럼 정리할 수 있습니다.
현재 실행 중인 요청 보호
↓
즉시 호출된 함수 배치
↓
호출이 임박한 함수 prewarming
↓
낮은 신뢰도의 warm 인스턴스 유지
따라서 SPES-Ext의 prewarming은 무조건적인 선점이 아닙니다. 현재 시스템이 감당할 수 있는 메모리 범위 안에서만 미래 요청을 준비하는 조건부 투자에 가깝습니다.
여섯 개 worker 실험이 보여준 의미
논문은 여섯 개 worker 환경에서 SPES-Ext의 배치 정책을 평가했습니다. 이때 핵심 지표 중 하나는 worker별 남은 메모리 차이를 나타내는 Normalized Worker Variance입니다.
특정 worker만 계속 바쁘고 다른 worker가 놀고 있다면 분산값은 커집니다. 반대로 각 worker의 메모리 사용량이 비교적 고르게 유지되면 분산값은 낮아집니다.
SPES-Ext는 비교 대상 대비 worker 부하 분산 지표를 평균 52.49%~96.14% 낮췄다고 보고했습니다. 이는 단지 빈 worker를 찾는 수준의 개선이 아닙니다. 함수별 호출 가능성, eviction 우선순위, 남은 메모리 상태를 결합해 배치를 결정한 결과입니다.
다만 이 수치는 Azure Functions 호출 추적을 활용한 시뮬레이션 결과입니다. 실제 운영 환경에서는 컨테이너 이미지 크기, 런타임 초기화 시간, CPU 사용량, 동시성 제한, 네트워크 상태까지 함께 고려해야 합니다.
결국 핵심은 메모리를 위한 ‘선택과 포기’다
Serverless 환경에서 모든 함수를 항상 warm 상태로 유지할 수 있다면 cold start는 줄일 수 있습니다. 하지만 메모리는 무한하지 않고, worker마다 감당할 수 있는 용량도 제한돼 있습니다.
SPES-Ext는 이 현실적인 제약을 정면으로 다룹니다. 호출 가능성이 높은 함수에는 메모리를 투자하고, 가능성이 낮은 함수는 과감하게 제거하며, 새 인스턴스는 가장 여유 있는 worker에 배치합니다.
좋은 예측은 출발점일 뿐입니다. 실제 Serverless 플랫폼의 성능은 그 예측을 어디에 배치하고, 어떤 인스턴스를 지키며, 무엇을 포기할지 결정하는 스케줄링 전략에서 갈립니다.
Serverless 성능 수치 너머: 서버리스 운영의 다음 단계
SPES-Ext의 실험 결과는 분명 인상적입니다. 75th-percentile cold-start rate를 80% 낮추고, 유휴 인스턴스가 만드는 메모리 낭비를 크게 줄였으며, 여러 worker의 부하 편차까지 완화했습니다.
하지만 이 수치를 곧바로 모든 production 환경의 성능 보장으로 받아들여서는 안 됩니다. 결과는 Azure Functions 호출 trace를 활용한 시뮬레이션에서 도출됐고, 실제 운영 환경에는 훨씬 더 많은 변수가 존재하기 때문입니다.
- 컨테이너 이미지 pull 시간
- 언어 런타임별 초기화 비용
- 네트워크 및 스토리지 지연
- 동시성 제한과 CPU 경합
- 함수별 메모리·실행시간 차이
- 갑작스러운 트래픽 변화와 예측 실패
특히 Java, .NET, Python처럼 초기화 비용이 큰 런타임과 경량 JavaScript 함수는 cold start의 체감 영향이 다를 수 있습니다. GPU 작업, 대용량 파일 변환, 장시간 실행되는 workflow처럼 “모든 함수가 1분 이내에 끝난다”는 가정과 거리가 있는 워크로드도 별도 검증이 필요합니다.
그럼에도 SPES-Ext가 제시한 방향은 중요합니다. Serverless 운영의 핵심이 더 이상 함수를 오래 warm 상태로 유지하는 것에만 있지 않다는 점입니다. 앞으로는 다음 질문에 답할 수 있어야 합니다.
이 함수는 언제 다시 호출될 가능성이 높은가?
지금 메모리를 차지할 가치가 있는가?
어느 worker에 배치해야 전체 플랫폼이 안정적인가?
SPES-Ext는 이 질문을 호출 빈도 하나가 아니라, waiting time, 호출 burst, 예측 신뢰도, 함수 간 상관관계, worker별 여유 메모리까지 함께 고려해 답하려 합니다.
운영 관점에서 달라지는 기준
기존의 Serverless 운영은 비교적 단순했습니다. 함수가 호출되면 실행 환경을 만들고, 일정 시간이 지나면 제거하는 방식입니다. keep-alive 시간을 길게 잡으면 cold start는 줄어들지만 메모리 비용이 증가합니다. 반대로 짧게 잡으면 메모리는 절약되지만 첫 요청의 지연이 늘어납니다.
SPES-Ext가 제안하는 방식은 이 고정된 선택지를 함수별로 세분화합니다.
| 기존 운영 방식 | 예측형 Serverless 운영 방식 |
|---|---|
| 모든 함수에 같은 keep-alive 적용 | 함수별 호출 패턴에 따라 유지 시간 조정 |
| 오래된 인스턴스부터 제거 | 다음 호출 가능성이 낮은 인스턴스 우선 제거 |
| 호출 후에만 실행 환경 생성 | 예상 호출 직전에 prewarming |
| 단순 분산 배치 | worker별 여유 메모리와 우선순위를 반영한 배치 |
| 함수 단위의 독립적 판단 | workflow 내 함수 간 호출 관계 활용 |
즉, 목표는 “더 많은 함수를 항상 켜두는 것”이 아닙니다. 정말 필요한 함수만, 필요한 순간에, 가장 적절한 worker에 준비하는 것입니다.
도입 전 확인해야 할 현실적 조건
이런 스케줄러가 모든 환경에 반드시 필요한 것은 아닙니다. 함수 수가 적고 트래픽이 단순하며 메모리 여유가 충분하다면, 고정 keep-alive 정책이 더 쉽고 안정적인 선택일 수 있습니다.
반면 다음과 같은 환경에서는 SPES-Ext의 접근이 특히 가치 있습니다.
- 제한된 메모리에서 많은 함수를 운영하는 private FaaS 환경
- 여러 edge node에 함수를 분산해야 하는 Edge Serverless 환경
- 주문, 결제, 알림처럼 함수 간 호출 흐름이 뚜렷한 workflow
- IoT처럼 주기성과 burst 트래픽이 함께 나타나는 이벤트 처리 플랫폼
- 멀티테넌트 환경에서 특정 worker로 메모리 사용량이 쏠리는 경우
실무 도입은 한 번에 전체 플랫폼 정책을 바꾸기보다 단계적으로 진행하는 편이 안전합니다. 먼저 호출 로그와 cold-start 비율, 메모리 점유 시간, worker별 메모리 편차를 측정해야 합니다. 이후 예측 정확도가 높은 정기 호출 함수부터 제한적으로 prewarming을 적용하고, 예측 실패로 인한 메모리 낭비와 지연 개선 효과를 함께 비교하는 방식이 바람직합니다.
핵심은 예측이 아니라 통제 가능한 균형
예측은 틀릴 수 있습니다. 호출되지 않을 함수를 미리 올리면 메모리가 낭비되고, 호출될 함수를 놓치면 cold start가 발생합니다. 따라서 좋은 Serverless 스케줄러는 예측 정확도만 높이는 도구가 아니라, 예측 실패의 비용을 통제하는 정책이어야 합니다.
SPES-Ext는 예측 신뢰도가 낮거나 다음 호출이 먼 함수부터 제거하고, 즉시 실행이 필요한 요청을 prewarming보다 우선합니다. 이 우선순위 설계는 현실적인 운영 원칙을 담고 있습니다. 모든 요청을 완벽히 맞히려 하기보다, 제한된 자원에서 가장 중요한 요청을 보호하는 것입니다.
결국 Serverless의 다음 단계는 scale-to-zero 자체가 아닙니다. 함수의 호출 패턴과 애플리케이션 workflow를 이해하고, 메모리·지연시간·worker 균형 사이에서 지속적으로 최적점을 찾는 예측형 실행환경 관리에 가깝습니다. SPES-Ext는 아직 검증이 더 필요한 연구 단계의 기술이지만, 서버리스 플랫폼이 향할 방향을 선명하게 보여주는 사례입니다.
