Unkey, 서버리스 포기하고 Go 서버로 전환하며 성능 6배 개선
API 플랫폼 Unkey가 Cloudflare Workers 서버리스 아키텍처에서 상태 유지형 Go 서버로 전환하며 성능을 6배 향상시켰습니다. 서버리스의 한계와 실무적 교훈을 살펴봅니다.
3줄 요약
- API 인증 플랫폼 Unkey가 Cloudflare Workers 서버리스에서 상태 유지형 Go 서버로 전환하며 성능 6배 향상
- 서버리스의 무상태 특성으로 인한 캐싱 지연(99th percentile 30ms 이상)이 주요 문제로 확인
- 복잡한 워크어라운드 제거, 비용 절감, 셀프 호스팅 가능 등 다양한 이점 확보
📌 주요 내용
Unkey의 서버리스 탈출 결정
API 인증 서비스를 제공하는 개발자 플랫폼 Unkey가 전체 서비스를 처음부터 재구축하며 Cloudflare Workers 기반 서버리스 아키텍처에서 상태 유지형 Go 서버로 전환했다고 발표했습니다. 이번 전환으로 성능이 6배 향상되었으며, 엔지니어링 노력의 상당 부분을 차지했던 복잡한 워크어라운드들을 제거할 수 있었습니다.
Unkey의 공동 창업자 Andreas Thomas는 수천 개의 애플리케이션 요청 경로에 위치한 서비스에서는 “모든 밀리초가 중요하다”며, 10밀리초 미만의 응답 시간 목표를 달성하기 위해서는 근본적인 아키텍처 변경이 필요했다고 설명했습니다.
서버리스의 근본적인 레이턴시 문제
가장 큰 문제는 캐싱이었습니다. Cloudflare의 캐시는 99th percentile 기준으로 30밀리초 이상의 레이턴시를 보였으며, 이는 전체 응답 시간 목표인 10밀리초를 초과하는 수치였습니다.
서버리스 함수는 설계상 무상태(stateless)로 동작합니다. 요청을 처리하고 사라지기 때문에 캐시된 데이터는 외부에 위치해야 하며 네트워크를 통해 조회해야 합니다. Unkey는 여러 Cloudflare 서비스를 활용한 다층 캐싱 시스템 구축, 캐시 키 최적화, 만료 시간 튜닝 등 다양한 시도를 했지만, 기본적인 물리적 제약을 극복할 수 없었습니다.
Thomas는 “네트워크 요청이 0번인 것이 1번보다 항상 빠르다”며, “어떤 영리한 캐싱 전략도 상태 유지형 서버가 기본적으로 제공하는 메모리 내 핫 데이터 유지를 따라갈 수 없다”고 강조했습니다.
서버리스가 만든 복잡성의 대가
서버리스 함수에서는 분석과 로깅을 위한 이벤트 데이터 추출도 문제였습니다. 일반적인 서버라면 이벤트를 메모리에 배치로 모아서 몇 초마다 플러시하면 되지만, 서버리스에서는 함수가 요청 처리 직후 사라질 수 있어 매 호출마다 플러시해야 합니다.
이로 인해 Unkey는 다음과 같은 복잡한 인프라를 구축해야 했습니다:
- 분석 이벤트를 버퍼링하는 커스텀 Go 프록시 chproxy 개발 (ClickHouse는 수천 개의 작은 삽입에서 성능이 저하됨)
- 메트릭과 로그를 위한 별도 파이프라인 구축
- 이벤트를 파싱하고 분할한 후 전달하는 중간 Cloudflare Workers 운영
- Durable Objects, Logstreams, Queues, Workflows 등 다양한 상태 유지 서비스 활용
Thomas는 팀이 기능 개발보다 새로운 SaaS 제품을 평가하고 통합하는 데 더 많은 시간을 소비했으며, 이는 고객의 문제가 아닌 서버리스 아키텍처가 만든 문제를 해결하는 것이었다고 지적했습니다.
새로운 아키텍처: AWS Fargate + Go
새 시스템은 AWS Fargate에서 실행되며 앞단에 Global Accelerator를 두었습니다. 여전히 전 세계적으로 트래픽을 분산하지만, 이제 장수명 Go 프로세스가 데이터를 메모리에 보관하고 이벤트를 자연스럽게 배치 처리합니다.
Thomas는 서버리스 아키텍처를 지원하던 모든 보조 서비스가 더 이상 필요하지 않게 되어 코드가 단순해지고 비용도 감소했다고 설명했습니다.
성능 개선과 새로운 기능 지원
전환 결과 레이턴시가 크게 감소했습니다. 무상태성을 우회하기 위해 구축했던 복잡성 부담이 사라졌으며, Cloudflare Workers 서비스 자체는 안정적이었지만 문제는 이를 사용하는 방식에 있었습니다.
또한 이전에는 거의 불가능했던 기능들도 구현 가능해졌습니다:
- 셀프 호스팅: Cloudflare Workers 런타임은 이론적으로 오픈소스이지만 로컬에서 실행하기 어려운 반면, 모놀리식 Go 애플리케이션은 단일 Docker 명령으로 실행 가능
- 데이터 레지던시: 엔터프라이즈의 엄격한 데이터 상주 요구사항 충족
- 로컬 개발: 엔지니어가 몇 초 만에 전체 스택을 노트북에서 실행 가능하며, Cloudflare 전용 API를 우회할 필요 없음
Unkey는 내년에 고객이 원하는 곳 어디서나 서비스를 실행할 수 있는 배포 플랫폼을 출시할 계획입니다.
업계의 서버리스 재평가 추세
Unkey의 전환은 고성능 프로덕션 워크로드에 대한 서버리스 컴퓨팅의 약속을 재검토하는 업계 추세의 일부입니다.
주목할 만한 사례로, Amazon Prime Video는 비디오 품질 모니터링 시스템을 분산 서버리스 시스템에서 단일 프로세스로 통합하여 인프라 비용을 90% 이상 절감했습니다. 이 사례는 AWS Lambda를 통해 마이크로서비스를 대중화한 Amazon에서 나왔다는 점에서 업계에 큰 반향을 일으켰습니다.
서버리스 컨설턴트 Yan Cui는 LinkedIn에서 서버리스가 언제 도움이 되지 않는지 질문하며, 초기 성장에 적합한 아키텍처가 나중에는 제약이 될 수 있다고 지적했습니다. 엔지니어 Luca Maraschi는 더 직설적으로 트래픽 패턴을 면밀히 검토하고 엣지나 서버리스 함수가 모든 워크로드에 최적이라고 가정하지 말라고 조언했습니다.
👨💻 개발자에게 미치는 영향
서버리스 선택 시 고려사항
Unkey와 Amazon Prime Video의 경험은 서버리스가 여전히 가치 있는 아키텍처 패턴이지만, 모든 상황에 적합하지는 않다는 것을 보여줍니다. 서버리스는 다음과 같은 워크로드에 적합합니다:
- 이벤트 드리븐 또는 실제로 간헐적인 워크로드
- 급격한 트래픽 변동이 있는 서비스
- 영구적인 상태 유지가 필요 없는 경우
하지만 높은 처리량과 엄격한 레이턴시 요구사항이 있는 서비스에서는 무상태 모델이 최선이 아닐 수 있습니다.
아키텍처 결정의 실용적 접근
개발자와 아키텍트는 다음 사항들을 고려해야 합니다:
- 성능 요구사항: 10ms 미만의 응답 시간이 필요한가? 네트워크 홉을 최소화할 수 있는가?
- 상태 관리: 메모리 내 캐싱으로 성능을 크게 개선할 수 있는가?
- 복잡성 대 이점: 서버리스의 제약을 우회하기 위해 구축하는 인프라가 얻는 이점을 초과하는가?
- 비용 모델: 트래픽 패턴에서 pay-per-invocation 모델이 경제적으로 합리적인가?
Unkey의 사례는 “복잡성 세금(complexity tax)”이라는 중요한 개념을 제시합니다. 무상태성을 우회하기 위해 구축하고 유지보수해야 하는 인프라는 상태 유지형 애플리케이션이 기본으로 제공하는 것을 복제하는 것입니다.
실용적 교훈
초기 아키텍처 선택이 향후 제약이 될 수 있다는 점을 인식하고, 트래픽이 증가하고 요구사항이 명확해지면서 재평가할 준비를 해야 합니다. 서버리스는 강력한 도구이지만, 만능 해결책은 아닙니다. 워크로드의 특성을 깊이 이해하고 적절한 도구를 선택하는 것이 중요합니다.
