본문

ECS Fargate Multi-Agent 환경에서 Auto Scaling 시 세션 유실 문제 해결기

ECS Fargate로 Multi-Agent 구조의 서비스를 운영하다 보면 예상치 못한 순간에 문제가 찾아옵니다.CPU 사용률이 80%를 넘으면서 Auto Scaling이 작동했는데, 정작 사용자들의 세션이 끊겨버리는 상황이 발생했습니다.

"분명 부하 분산을 위해 설정한 건데, 왜 세션이 날아가는 거지?" 원인을 파악하고 나니, 이건 단순히 설정 문제가 아니라 Stateful한 Multi-Agent 구조의 본질적인 한계였습니다. 문제를 어떻게 분석했고, 최종적으로 어떤 방향을 선택했는지 기록해 봅니다.


 

문제 상황: 스케일링이 되면 세션이 사라진다

실제로 일어난 일

  • 특정 Task의 CPU가 80%를 넘어가면서 알람 발생
  • Auto Scaling 정책이 정상 작동해 새 Task가 추가됨
  • 그런데 기존에 연결되어 있던 사용자 세션이 유실됨
  • Multi-Agent 특성상 대화 컨텍스트까지 같이 날아감

스케일링 자체는 제대로 동작했지만, 정작 사용자 경험은 좋지 않았습니다.

첫 번째 시도: 그냥 스펙을 올려보자

가장 먼저 떠오른 생각은 간단했습니다. "CPU가 부족하니까 Task 스펙을 올리면 되지 않을까?"

애초에 80% 임계치에 덜 도달하도록 만들면, 스케일링 자체를 줄일 수 있을 테니까요.

그런데 막상 스펙을 올리려고 하니 벽에 부딪혔습니다.

 

Fargate의 최대 제한

  • CPU: 최대 16 vCPU
  • Memory: 최대 120GB

제가 담당하던 서비스는 이미 이 한계에 가까운 스펙을 사용하고 있었습니다. 여러 AI Agent가 동시에 돌아가다 보니 리소스 소모가 상당했거든요. 더 이상 스펙 업그레이드로는 해결이 어렵다는 걸 알게 되었습니다.

두 번째 시도: ALB Sticky Session을 켜면 되지 않을까

그럼 세션을 특정 Task에 고정시키면 어떨까요? ALB에 Sticky Session 기능이 있으니, 이걸 활성화해 보기로 했습니다.

# ALB Target Group Stickiness 설정
stickiness {
  type            = "lb_cookie"
  cookie_duration = 86400  # 24시간
  enabled         = true
}

사용자가 한 번 연결된 Task에 계속 붙어있으면 세션도 유지될 거라고 생각했습니다.

그런데 Multi-Agent 환경에서는 예상치 못한 문제가 생겼습니다

  1. 부하가 한쪽으로 쏠림: 특정 Task에만 사용자가 몰리면서 로드밸런싱이 제대로 안 됨
  2. Agent 협업이 어려움: 여러 Agent가 협력해서 작업하는 구조인데, 특정 Task에만 고정되니 비효율적
  3. 장애가 전파됨: 고정된 Task에 문제가 생기면 그 Task의 모든 사용자가 영향받음
  4. Scale-in 할 때 문제: Task를 줄이려고 하면 해당 Task의 세션이 다 날아감

Sticky Session은 일반적인 웹 서비스에는 괜찮지만, 제가 맡은 서비스처럼 분산된 Agent 구조에서는 적합하지 않았습니다.

 

그래서 찾아본 근본적인 해결책

방안 1: 그냥 ECS EC2로 갈아타기

이렇게 하면 좋은 점

  • Fargate처럼 인스턴스 타입 제약이 적음 (r7i.24xlarge 같은 큰 인스턴스도 쓸 수 있음)
  • CPU/메모리를 훨씬 더 많이 쓸 수 있음
  • 인스턴스 단위로 관리하니 성능 예측이 더 쉬움

하지만 문제도 있음

  • AMI 관리, 패치, 보안 설정 등 신경 쓸 게 많아짐
  • Auto Scaling Group도 따로 관리해야 함
  • EC2가 뜨는 시간 때문에 스케일링이 좀 느림
  • 금융권이다 보니 EC2 보안 규정 맞추는 것도 일

고민되는 부분

Fargate를 쓰는 이유가 운영 편의성 때문인데, EC2로 가면 그걸 다 포기하는 셈입니다. 특히 금융권에서 EC2 직접 관리하려면 챙겨야 할 게 한두 가지가 아니거든요.

 

 

방안 2: Redis로 세션 관리하기 (최종 선택)

구조를 이렇게 바꾸면

사용자 → ALB → ECS Task (아무거나) → Redis (ElastiCache)
                                        ↓
                                  세션 데이터 저장소

실제로 구현할 내용

  1. ElastiCache Redis 셋업:
    • Multi-AZ로 구성해서 한쪽 죽어도 괜찮게
    • Cluster Mode 켜서 성능 확보
  2. 세션 데이터를 분리:
    • 사용자 세션 → Redis
    • Agent 컨텍스트 → Redis
    • 대화 히스토리 → Redis + DB(RDS/DynamoDB)
  3. Connection Pooling 적용:
    • Redis 연결 재사용해서 성능 올리기
    • Timeout 적절하게 설정

이렇게 하면 좋은 점

  • Stateless 구조: 어느 Task로 가든 세션 유지됨
  • 확장이 자유로움: Task 개수 제약 없이 Auto Scaling 가능
  • 장애가 격리됨: 한 Task 죽어도 다른 사용자한테 영향 없음
  • Multi-Agent 친화적: Agent끼리 상태 공유하기 쉬움
  • Fargate 장점 유지: 서버리스 편의성 그대로

코드로 보면 이런 느낌

import redis
import json

class SessionManager:
    def __init__(self):
        self.redis_client = redis.Redis(
            host='your-elasticache-endpoint',
            port=6379,
            decode_responses=True,
            socket_keepalive=True,
            socket_connect_timeout=5,
            max_connections=50
        )
    
    def save_session(self, session_id: str, data: dict):
        """세션 저장"""
        self.redis_client.setex(
            f"session:{session_id}",
            86400,  # 24시간 유지
            json.dumps(data)
        )
    
    def get_session(self, session_id: str):
        """세션 가져오기"""
        data = self.redis_client.get(f"session:{session_id}")
        return json.loads(data) if data else None
    
    def save_agent_context(self, session_id: str, agent_id: str, context: dict):
        """Agent 컨텍스트 저장"""
        key = f"agent:{session_id}:{agent_id}"
        self.redis_client.setex(key, 3600, json.dumps(context))

비용 측면에서도

  • ElastiCache r7g.large: 월 약 156달러
  • EC2 r7i.4xlarge로 전환: 월 약 730달러
  • Fargate + Redis 조합이 더 저렴함

 

결론: Redis 기반 세션 관리로 결정

여러 가지를 검토해 본 결과, Redis로 세션을 중앙에서 관리하는 방식이 제가 맡은 서비스 상황에 잘 맞았습니다.

이 방식을 선택한 이유

  1. Fargate의 운영 편의성을 그대로 가져갈 수 있음
  2. Stateless 아키텍처 구현 가능
  3. Multi-Agent 구조에 적합함
  4. 비용도 합리적
  5. 금융권 보안 규정 맞추기도 상대적으로 수월

앞으로 할 일

  • ElastiCache Redis Cluster 구성 (Multi-AZ)
  • Session Manager 구현하고 테스트
  • Connection Pool 튜닝
  • CloudWatch + Redis metrics로 모니터링 설정
  • Failover 상황 시뮬레이션

가끔은 단순히 스펙을 올리는 것보다, 구조를 바꾸는 게 더 나은 해결책일 때가 있습니다. 처음엔 "그냥 CPU 더 주면 되지 않나?" 싶었는데, 결과적으로는 아키텍처를 개선하는 방향으로 가게 되었네요.

공유

댓글