넷플릭스 마이크로서비스 아키텍처(MSA) 완전 가이드
개요
넷플릭스는 전 세계 2억 명 이상의 구독자를 보유한 글로벌 스트리밍 서비스로, 마이크로서비스 아키텍처(MSA)를 성공적으로 구현한 대표적인 기업 사례로 평가받고 있다. 2008년 데이터센터 장애를 겪으면서 모놀리식 아키텍처의 한계를 절감한 넷플릭스는, 2009년부터 본격적으로 클라우드 전환과 마이크로서비스 아키텍처로의 전환을 시작했다. 이러한 전환 과정은 약 7년에 걸쳐 진행되었으며, 2016년에 완전한 클라우드 네이티브 아키텍처로 이전을 완료했다.
넷플릭스의 MSA는 단순히 기술적 전환을 넘어서, 조직 문화와 개발 프로세스, 운영 철학 전반의 변화를 수반했다. 이들은 “자유와 책임(Freedom and Responsibility)”이라는 핵심 가치를 바탕으로, 개발자들에게 광범위한 자율성을 부여하면서도 서비스의 안정성과 성능을 보장하는 독특한 엔지니어링 문화를 구축했다. 현재 넷플릭스는 700개 이상의 마이크로서비스를 운영하고 있으며, 하루에도 수천 번의 배포가 이루어지는 고도로 자동화된 인프라를 갖추고 있다.
1. 설계 원칙
넷플릭스의 마이크로서비스 아키텍처는 몇 가지 핵심적인 설계 원칙 위에 구축되어 있다. 이러한 원칙들은 단순히 기술적 가이드라인을 넘어서, 넷플릭스의 엔지니어링 문화와 비즈니스 전략을 반영하는 철학적 기반이 되고 있다.
자유와 책임 (Freedom and Responsibility)
넷플릭스 엔지니어링 문화의 핵심은 “자유와 책임”이라는 원칙이다. 이는 개발자들에게 기술 스택 선택, 아키텍처 결정, 배포 시점 등에 대한 광범위한 자율성을 부여하되, 그에 따른 책임도 함께 지도록 하는 철학이다. 개발자는 자신이 작성한 코드의 전체 생명주기에 대해 책임을 지며, 이는 “빌드한 사람이 운영한다(You build it, you run it)”는 원칙으로 구체화된다.
이러한 접근은 전통적인 개발팀과 운영팀의 분리를 없애고, 풀사이클 개발자(Full Cycle Developer) 모델을 도입하는 기반이 되었다. 개발자는 단순히 기능을 구현하는 것을 넘어서, 모니터링, 알림 설정, 장애 대응, 성능 최적화까지 자신의 서비스에 대한 모든 측면을 책임진다. 이는 개발자가 운영 관점에서 코드를 작성하도록 유도하며, 결과적으로 더 안정적이고 운영 가능한 시스템을 만들어낸다.
고가용성과 장애 격리
넷플릭스는 “모든 것은 언젠가 실패한다”는 전제에서 출발한다. 이는 하드웨어 장애, 네트워크 문제, 소프트웨어 버그 등 다양한 형태의 실패가 불가피하다는 현실을 인정하고, 이를 시스템 설계의 핵심 고려사항으로 삼는다는 의미다. 따라서 넷플릭스의 마이크로서비스는 부분적인 장애가 전체 시스템으로 전파되지 않도록 설계되며, 이를 위해 다양한 장애 격리 메커니즘을 구현한다.
서킷 브레이커(Circuit Breaker) 패턴은 이러한 장애 격리의 핵심 메커니즘이다. 넷플릭스가 개발한 Hystrix 라이브러리는 서비스 간 호출에서 장애가 감지되면 자동으로 회로를 차단하여 연쇄적인 장애를 방지한다. 예를 들어, 추천 서비스가 응답하지 않을 때, 메인 서비스는 빠르게 폴백(fallback)하여 기본 추천 목록을 제공함으로써 사용자 경험을 유지한다. 이는 완벽한 서비스보다는 제한적이더라도 작동하는 서비스를 제공하는 것이 낫다는 철학을 반영한다.
벌크헤드(Bulkhead) 패턴 역시 중요한 설계 원칙이다. 배의 격벽처럼, 시스템의 한 부분에서 발생한 문제가 다른 부분으로 확산되지 않도록 리소스를 분리한다. 예를 들어, 각 마이크로서비스는 독립적인 쓰레드 풀과 커넥션 풀을 가지며, 한 서비스의 리소스 고갈이 다른 서비스에 영향을 미치지 않도록 한다.
확장성과 탄력성
넷플릭스의 트래픽은 시간대와 지역에 따라 극심한 변동을 보인다. 인기 콘텐츠가 공개되는 시점에는 평소 대비 수십 배의 트래픽이 발생할 수 있으며, 이러한 피크 트래픽을 처리하면서도 비용 효율성을 유지해야 한다. 이를 위해 넷플릭스는 수평적 확장(Horizontal Scaling)을 기본 전략으로 채택했다.
각 마이크로서비스는 상태를 가지지 않는(Stateless) 설계를 따르며, 이를 통해 필요에 따라 인스턴스를 쉽게 추가하거나 제거할 수 있다. 오토 스케일링(Auto Scaling) 정책은 CPU 사용률, 메모리 사용률, 요청 대기 시간 등 다양한 메트릭을 기반으로 자동으로 인스턴스 수를 조절한다. 이러한 자동화는 운영 부담을 줄이면서도 비용 최적화를 달성하는 핵심 메커니즘이다.
상태 정보가 필요한 경우, 이는 외부 데이터 저장소에 보관된다. 넷플릭스는 캐싱을 위해 EVCache를 사용하고, 영구 저장을 위해 Cassandra와 같은 분산 데이터베이스를 활용한다. 이러한 분리는 애플리케이션 계층의 확장성을 극대화하면서도, 데이터의 일관성과 내구성을 보장한다.
관찰 가능성 (Observability)
복잡한 분산 시스템에서는 무엇이 일어나고 있는지 이해하는 것이 매우 중요하다. 넷플릭스는 포괄적인 관찰 가능성을 구축하기 위해 로깅, 메트릭, 트레이싱이라는 세 가지 기둥을 활용한다.
모든 마이크로서비스는 표준화된 방식으로 로그를 생성하며, 이는 중앙 집중식 로그 수집 시스템으로 전송된다. Atlas라는 자체 개발한 메트릭 시스템은 초당 수백만 개의 메트릭을 수집하고 실시간으로 분석한다. 각 서비스는 요청 처리 시간, 에러율, CPU 사용률 등 핵심 지표를 지속적으로 보고하며, 이는 대시보드를 통해 시각화되고 알림 규칙의 기반이 된다.
분산 트레이싱은 단일 요청이 여러 마이크로서비스를 거치면서 처리되는 과정을 추적할 수 있게 한다. 사용자가 영화를 재생할 때, 이 요청은 인증 서비스, 추천 서비스, 메타데이터 서비스, 스트리밍 서비스 등을 거칠 수 있다. 분산 트레이싱은 이러한 호출 체인을 시각화하여, 어느 지점에서 지연이 발생하는지 파악할 수 있게 한다.
진화하는 아키텍처
넷플릭스는 아키텍처를 고정된 것이 아닌 지속적으로 진화하는 것으로 본다. 기술 스택, 설계 패턴, 인프라 구성은 비즈니스 요구사항과 기술 발전에 따라 계속 변화한다. 이를 가능하게 하는 것이 점진적 마이그레이션 전략이다.
새로운 패턴이나 기술을 도입할 때, 넷플릭스는 일부 서비스에서 먼저 검증한 후 점진적으로 확산시킨다. 예를 들어, 새로운 데이터베이스 기술을 도입할 때는 작은 규모의 비중요 서비스에서 먼저 시험하고, 성능과 안정성이 검증되면 더 중요한 서비스로 확대한다. 이러한 접근은 리스크를 최소화하면서도 지속적인 개선을 가능하게 한다.
API 버저닝도 진화를 지원하는 중요한 메커니즘이다. 기존 API를 변경할 때는 하위 호환성을 유지하거나, 새로운 버전의 API를 병렬로 제공하여 클라이언트가 점진적으로 마이그레이션할 수 있도록 한다. 이는 전체 시스템을 중단하지 않고도 개별 서비스를 독립적으로 발전시킬 수 있게 한다.
2. MSA 서비스 단위
넷플릭스의 마이크로서비스는 비즈니스 도메인을 중심으로 구성되며, 각 서비스는 명확한 책임과 경계를 가진다. 현재 넷플릭스는 700개 이상의 마이크로서비스를 운영하고 있으며, 이들은 크게 몇 가지 범주로 분류할 수 있다.
Edge 서비스
Edge 서비스는 클라이언트와 백엔드 시스템 사이의 진입점 역할을 한다. Zuul은 넷플릭스의 게이트웨이 서비스로, 모든 외부 요청의 첫 번째 접점이다. Zuul은 동적 라우팅, 모니터링, 보안, 복원력 등 다양한 기능을 제공한다.
Zuul을 통해 들어온 요청은 먼저 인증과 권한 검증을 거친다. 사용자의 토큰이 유효한지 확인하고, 요청된 리소스에 접근할 권한이 있는지 검사한다. 이후 요청은 적절한 백엔드 서비스로 라우팅된다. Zuul은 필터 체인을 통해 요청과 응답을 처리하며, 각 필터는 로깅, 요청 변환, 응답 캐싱 등 특정 기능을 담당한다.
API 게이트웨이 패턴을 통해, 넷플릭스는 클라이언트에게 일관된 인터페이스를 제공하면서도 백엔드 서비스의 복잡성을 숨길 수 있다. 모바일 클라이언트와 웹 클라이언트는 서로 다른 요구사항을 가질 수 있으며, Zuul은 이러한 차이를 흡수하여 각 클라이언트에 최적화된 응답을 제공한다.
중간 계층 서비스
중간 계층 서비스는 비즈니스 로직을 처리하고 여러 백엔드 서비스를 조합하여 클라이언트가 필요로 하는 데이터를 구성한다. 이들은 종종 Backend for Frontend(BFF) 패턴을 구현한다.
예를 들어, 홈 화면을 구성하는 서비스는 사용자의 시청 이력 서비스, 추천 서비스, 콘텐츠 메타데이터 서비스 등을 호출하여 개인화된 홈 화면을 구성한다. 이러한 조합 로직은 클라이언트에서 수행되지 않고 서버 측에서 처리되어, 네트워크 왕복 횟수를 줄이고 클라이언트의 복잡성을 낮춘다.
중간 계층 서비스는 또한 데이터 변환과 집계를 담당한다. 여러 서비스로부터 받은 원시 데이터를 클라이언트가 소비하기 쉬운 형태로 변환하고, 불필요한 정보는 필터링한다. GraphQL을 활용하는 경우, 이 계층에서 GraphQL 쿼리를 처리하고 여러 REST API 호출로 분해하여 실행한다.
도메인 서비스
도메인 서비스는 특정 비즈니스 도메인의 핵심 기능을 캡슐화한다. 각 서비스는 단일 책임 원칙을 따르며, 자신의 도메인에 대한 유일한 진실의 원천(Single Source of Truth)이 된다.
사용자 프로필 서비스는 사용자의 기본 정보, 선호도, 설정 등을 관리한다. 이 서비스는 사용자 데이터의 생성, 조회, 수정, 삭제(CRUD) 작업을 담당하며, 다른 서비스가 사용자 정보가 필요할 때 이 서비스를 호출한다. 데이터는 일반적으로 Cassandra와 같은 NoSQL 데이터베이스에 저장되며, 빠른 조회를 위해 EVCache에 캐싱된다.
추천 서비스는 넷플릭스의 핵심 경쟁력 중 하나로, 머신러닝 모델을 활용하여 개인화된 콘텐츠 추천을 제공한다. 이 서비스는 사용자의 시청 이력, 평가, 검색 행동 등을 분석하여 관심을 가질 만한 콘텐츠를 예측한다. 추천 모델은 지속적으로 학습하고 업데이트되며, A/B 테스트를 통해 성능이 검증된다.
콘텐츠 메타데이터 서비스는 영화와 TV 쇼에 대한 모든 정보를 관리한다. 제목, 설명, 장르, 출연진, 썸네일 이미지 등 다양한 메타데이터가 포함되며, 이는 다국어로 제공된다. 메타데이터는 여러 소스에서 수집되고 정규화되어 일관된 형태로 제공된다.
결제 및 구독 서비스는 사용자의 구독 상태, 결제 정보, 청구 이력 등을 관리한다. 이 서비스는 높은 수준의 보안과 컴플라이언스가 요구되며, 금융 트랜잭션의 무결성을 보장하기 위해 특별한 주의를 기울여 설계된다.
플랫폼 서비스
플랫폼 서비스는 다른 서비스들이 공통적으로 필요로 하는 기능을 제공한다. 이들은 횡단 관심사(Cross-cutting Concerns)를 처리하며, 각 도메인 서비스가 비즈니스 로직에 집중할 수 있게 한다.
인증 및 권한 부여 서비스는 사용자 신원 확인과 접근 제어를 중앙에서 관리한다. OAuth 2.0과 같은 표준 프로토콜을 사용하며, 토큰 기반 인증을 통해 상태 비저장성을 유지한다. 권한 부여는 역할 기반 접근 제어(RBAC)와 속성 기반 접근 제어(ABAC)를 조합하여 세밀한 제어를 가능하게 한다.
서비스 디스커버리를 위해 넷플릭스는 Eureka를 개발했다. Eureka는 각 서비스 인스턴스의 위치 정보를 등록하고 조회하는 레지스트리 역할을 한다. 서비스가 시작될 때 자신을 Eureka에 등록하고, 주기적으로 하트비트를 전송하여 건강 상태를 알린다. 다른 서비스는 Eureka를 통해 필요한 서비스의 인스턴스 목록을 조회하고, 클라이언트 측 로드 밸런싱을 수행한다.
구성 관리 서비스는 모든 서비스의 설정을 중앙에서 관리한다. Archaius라는 자체 개발한 구성 관리 라이브러리는 동적 속성을 지원하여, 애플리케이션을 재시작하지 않고도 설정을 변경할 수 있다. 이는 피처 플래그, A/B 테스트, 카나리 배포 등을 가능하게 하는 핵심 기능이다.
데이터 처리 서비스
넷플릭스는 매일 엄청난 양의 데이터를 생성하고 처리한다. 사용자 행동 데이터, 스트리밍 품질 메트릭, 시스템 로그 등 다양한 데이터 소스가 있으며, 이를 처리하기 위한 전문 서비스들이 존재한다.
이벤트 스트리밍을 위해 Apache Kafka와 자체 개발한 Keystone을 사용한다. 사용자가 비디오를 재생하거나, 평가를 남기거나, 검색을 수행할 때마다 이벤트가 생성되고, 이는 실시간으로 여러 소비자에게 전달된다. 이러한 이벤트는 실시간 추천, 이상 탐지, 비즈니스 분석 등에 활용된다.
배치 처리를 위해서는 Apache Spark와 Hadoop 생태계를 활용한다. 대규모 데이터 세트에 대한 복잡한 분석, 머신러닝 모델 학습, 리포트 생성 등이 이 계층에서 수행된다. 배치 작업은 보통 트래픽이 낮은 시간대에 스케줄되어, 실시간 서비스에 영향을 미치지 않도록 한다.
서비스 크기와 경계 설정
넷플릭스는 서비스의 크기를 정할 때 여러 요소를 고려한다. 너무 작은 서비스는 분산 시스템의 복잡성을 증가시키고 운영 오버헤드를 높인다. 반면 너무 큰 서비스는 모놀리식 시스템의 문제를 재현할 수 있다.
일반적으로 서비스는 단일 팀이 소유하고 관리할 수 있는 크기여야 한다. “two-pizza team” 규칙을 따라, 한 팀이 관리하는 서비스는 그 팀이 피자 두 판으로 점심을 해결할 수 있을 정도의 인원으로 운영 가능해야 한다. 이는 일반적으로 5-10명 정도의 엔지니어를 의미한다.
서비스 경계는 도메인 주도 설계(Domain-Driven Design)의 바운디드 컨텍스트(Bounded Context) 개념을 따른다. 각 서비스는 특정 비즈니스 컨텍스트 내에서 의미 있는 단위를 형성하며, 서비스 간 결합도를 낮추고 응집도를 높이는 방향으로 설계된다.
변경 빈도도 중요한 고려사항이다. 함께 자주 변경되는 기능들은 같은 서비스로 묶고, 독립적으로 변경되는 기능들은 분리한다. 이는 배포 빈도를 높이고 변경의 영향 범위를 제한하는 데 도움이 된다.
3. 테스트 방법
넷플릭스의 테스트 전략은 분산 시스템의 복잡성과 지속적 배포의 요구사항을 반영하여 설계되었다. 전통적인 테스트 피라미드를 따르면서도, 프로덕션 환경에서의 검증을 중요하게 여기는 독특한 접근을 취한다.
단위 테스트
단위 테스트는 테스트 피라미드의 기반을 형성한다. 각 서비스의 개별 컴포넌트와 함수는 격리된 환경에서 테스트되며, 외부 의존성은 모킹(mocking)이나 스터빙(stubbing)을 통해 제어된다. 넷플릭스는 JUnit, Mockito 등 표준 테스트 프레임워크를 사용하며, 코드 커버리지 목표를 설정하여 품질을 보장한다.
단위 테스트는 개발 과정에서 빠른 피드백을 제공한다. 개발자가 코드를 작성하거나 수정할 때, IDE 내에서 즉시 테스트를 실행하여 의도한 대로 동작하는지 확인할 수 있다. 이러한 빠른 피드백 루프는 버그를 조기에 발견하고 수정 비용을 낮춘다.
테스트 주도 개발(TDD)을 권장하지만 강제하지는 않는다. 각 팀은 자신들의 컨텍스트에서 가장 효과적인 개발 방법론을 선택할 자유가 있다. 하지만 코드 리뷰 과정에서 테스트의 품질과 커버리지는 중요한 검토 항목이다.
통합 테스트
통합 테스트는 서비스 간 상호작용을 검증한다. 마이크로서비스 아키텍처에서는 개별 서비스가 올바르게 작동하더라도, 서비스 간 통신에서 문제가 발생할 수 있다. 통합 테스트는 API 계약, 데이터 형식, 에러 처리 등을 검증한다.
계약 테스트(Contract Testing)는 특히 중요하다. 소비자 주도 계약 테스트(Consumer-Driven Contract Testing) 접근을 통해, 서비스 소비자가 기대하는 API 계약을 정의하고, 제공자는 이 계약을 만족하는지 검증한다. Pact와 같은 도구를 사용하여 이러한 계약을 명시하고 자동으로 검증한다.
통합 테스트 환경은 프로덕션과 유사하게 구성되지만, 규모는 축소된다. 모든 의존 서비스가 실제로 배포되거나, 필요에 따라 스터빙된 버전이 사용된다. 테스트 데이터는 신중하게 관리되어, 일관되고 재현 가능한 테스트 결과를 보장한다.
엔드투엔드 테스트
엔드투엔드 테스트는 사용자 시나리오를 전체 시스템 관점에서 검증한다. 사용자가 로그인하고, 콘텐츠를 검색하고, 재생하는 전체 플로우가 올바르게 작동하는지 확인한다. 이러한 테스트는 실행 시간이 오래 걸리고 유지보수 비용이 높기 때문에, 가장 중요한 사용자 경로에 집중한다.
Selenium과 같은 브라우저 자동화 도구를 사용하여 웹 클라이언트를 테스트하고, Appium을 통해 모바일 앱을 테스트한다. 테스트는 다양한 디바이스와 플랫폼에서 실행되어, 플랫폼 간 일관성을 보장한다.
엔드투엔드 테스트의 불안정성(flakiness)은 지속적인 과제다. 네트워크 지연, 타이밍 이슈, 외부 의존성 등으로 인해 테스트가 간헐적으로 실패할 수 있다. 넷플릭스는 재시도 로직, 명시적 대기, 안정적인 선택자 사용 등을 통해 테스트의 안정성을 개선한다.
카오스 엔지니어링
넷플릭스가 개척한 카오스 엔지니어링은 프로덕션 환경에서 의도적으로 장애를 주입하여 시스템의 복원력을 테스트하는 방법이다. 이는 “모든 것은 언젠가 실패한다”는 전제를 실천하는 구체적인 방법이며, 장애 상황에서 시스템이 어떻게 반응하는지 사전에 파악할 수 있게 한다.
Chaos Monkey는 이러한 접근의 시작점이었다. Chaos Monkey는 무작위로 프로덕션 서버 인스턴스를 종료하여, 시스템이 인스턴스 손실을 우아하게 처리하는지 검증한다. 처음에는 개발자들이 두려워했지만, 시간이 지나면서 이는 당연한 일상이 되었고, 엔지니어들은 이러한 장애를 견딜 수 있도록 시스템을 설계하게 되었다.
Simian Army는 Chaos Monkey를 확장한 도구 모음이다. Latency Monkey는 네트워크 지연을 주입하고, Conformity Monkey는 베스트 프랙티스를 준수하지 않는 인스턴스를 종료하며, Doctor Monkey는 건강하지 않은 인스턴스를 식별한다. Chaos Gorilla는 전체 가용 영역(Availability Zone)을 다운시켜 더 큰 규모의 장애를 시뮬레이션한다.
ChaoS Platform(이전 Chaos Kong)은 전체 AWS 리전을 시뮬레이션으로 중단시켜, 리전 수준의 장애 대응 능력을 테스트한다. 이는 극단적인 시나리오지만, 실제로 발생할 수 있는 상황에 대비하는 데 필수적이다.
카오스 엔지니어링 실험은 신중하게 계획되고 실행된다. 가설을 세우고, 영향 범위를 제한하며, 결과를 모니터링한다. 문제가 발견되면 실험을 중단하고, 근본 원인을 분석하여 시스템을 개선한다. 이러한 반복적인 과정을 통해, 넷플릭스는 예상치 못한 장애 상황에서도 서비스를 유지할 수 있는 능력을 키워왔다.
성능 및 부하 테스트
넷플릭스는 새로운 기능이나 변경사항이 성능에 미치는 영향을 사전에 파악하기 위해 철저한 성능 테스트를 수행한다. JMeter, Gatling 등의 도구를 사용하여 부하 테스트를 실행하며, 예상 트래픽보다 훨씬 높은 수준의 부하를 가하여 시스템의 한계를 파악한다.
부하 테스트는 단순히 처리량만 측정하는 것이 아니라, 응답 시간 분포, 에러율, 리소스 사용률 등 다양한 메트릭을 수집한다. 특히 백분위수(percentile) 지표를 중요하게 여긴다. 평균 응답 시간은 전체 그림을 보여주지 못하며, 99번째 백분위수 응답 시간이 사용자 경험에 더 직접적인 영향을 미친다.
카나리 배포와 결합된 성능 모니터링은 프로덕션 환경에서의 실제 성능을 검증한다. 새 버전이 작은 비율의 트래픽으로 먼저 배포되고, 핵심 메트릭을 비교하여 성능 저하가 없는지 확인한다. 문제가 감지되면 자동으로 롤백되어 영향을 최소화한다.
A/B 테스트
넷플릭스는 거의 모든 기능 변경에 대해 A/B 테스트를 수행한다. 사용자를 무작위로 그룹으로 나누고, 각 그룹에 다른 버전의 기능을 제공한 후, 핵심 지표(시청 시간, 참여도, 유지율 등)를 비교한다. 이는 기능의 비즈니스 가치를 객관적으로 측정하고, 데이터 기반 의사결정을 가능하게 한다.
A/B 테스트 플랫폼은 정교한 실험 설계와 통계적 분석을 지원한다. 다변량 테스트, 순차적 테스트, 계층화된 샘플링 등 다양한 실험 방법론을 활용한다. 실험 결과는 대시보드를 통해 실시간으로 모니터링되며, 통계적 유의성이 확보되면 결과를 바탕으로 배포 여부를 결정한다.
피처 플래그는 A/B 테스트의 핵심 인프라다. 코드 배포와 기능 활성화를 분리하여, 위험 없이 새로운 기능을 프로덕션에 배포하고 필요에 따라 켜거나 끌 수 있다. 이는 또한 점진적 롤아웃을 가능하게 하여, 새로운 기능을 처음에는 작은 비율의 사용자에게만 제공하고 점차 확대할 수 있다.
4. 서비스 배포 주기
넷플릭스의 배포 철학은 “빠르고 자주, 그리고 안전하게”로 요약될 수 있다. 지속적 배포(Continuous Deployment)를 통해 하루에 수천 번의 배포가 이루어지며, 이는 변경사항을 빠르게 사용자에게 전달하고 피드백을 신속하게 받을 수 있게 한다.
지속적 통합 (Continuous Integration)
모든 코드 변경은 버전 관리 시스템(Git)에 커밋되며, 이는 자동으로 빌드와 테스트 파이프라인을 트리거한다. Jenkins나 자체 개발한 CI 도구를 사용하여, 코드가 컴파일되고, 단위 테스트가 실행되며, 정적 분석이 수행된다.
빌드 파이프라인은 여러 단계로 구성된다. 첫 번째 단계에서는 빠른 피드백을 위해 컴파일과 단위 테스트만 실행한다. 이 단계가 성공하면, 더 시간이 오래 걸리는 통합 테스트와 정적 분석이 실행된다. 각 단계는 병렬로 실행되어 전체 파이프라인 시간을 최소화한다.
코드 품질 게이트는 배포 전에 충족되어야 하는 기준을 정의한다. 테스트 커버리지 임계값, 정적 분석 경고 수, 보안 취약점 등이 평가되며, 기준을 충족하지 못하면 배포가 차단된다. 하지만 이러한 규칙은 팀의 컨텍스트에 따라 유연하게 조정될 수 있다.
배포 자동화
Spinnaker는 넷플릭스가 개발하고 오픈소스로 공개한 지속적 배포 플랫폼이다. Spinnaker는 복잡한 배포 파이프라인을 정의하고 실행하며, 다양한 배포 전략을 지원한다.
배포 파이프라인은 일련의 단계로 구성된다. 아티팩트를 베이킹(baking)하여 머신 이미지를 생성하고, 테스트 환경에 배포하여 검증한 후, 프로덕션으로 점진적으로 롤아웃한다. 각 단계 사이에는 자동 또는 수동 승인 게이트가 있어, 문제가 있을 때 배포를 중단할 수 있다.
불변 인프라(Immutable Infrastructure) 원칙을 따라, 서버는 업데이트되지 않고 교체된다. 새로운 코드 버전이 배포될 때, 새로운 인스턴스가 생성되고 기존 인스턴스는 종료된다. 이는 “configuration drift”를 방지하고, 롤백을 단순화하며, 환경 간 일관성을 보장한다.
배포 전략
넷플릭스는 다양한 배포 전략을 활용하여 리스크를 관리한다. 가장 일반적인 것이 레드/블랙 배포(Red/Black Deployment, Blue/Green Deployment라고도 함)다. 새 버전(블랙)이 기존 버전(레드)과 병렬로 배포되고, 모든 트래픽이 새 버전으로 전환된 후 기존 버전이 종료된다. 문제가 발생하면 트래픽을 즉시 기존 버전으로 되돌릴 수 있다.
카나리 배포는 더 점진적인 접근이다. 새 버전이 먼저 작은 비율의 트래픽(예: 5%)으로 배포되고, 핵심 메트릭을 모니터링한다. 에러율, 응답 시간, CPU 사용률 등이 기준선과 비교되며, 이상이 없으면 트래픽 비율이 점진적으로 증가한다. 문제가 감지되면 자동으로 롤백된다.
피처 플래그를 활용한 다크 런칭(Dark Launching)은 코드 배포와 기능 활성화를 분리한다. 새 기능이 코드로는 배포되지만 비활성화 상태로 유지되며, 준비가 되면 플래그를 켜서 활성화한다. 이는 배포 리스크를 줄이고, 필요시 즉시 기능을 끌 수 있게 한다.
배포 빈도
넷플릭스에서는 하루에도 수천 번의 배포가 이루어진다. 각 팀은 자신들의 서비스를 독립적으로 배포하며, 다른 팀의 일정을 기다릴 필요가 없다. 이러한 높은 배포 빈도는 변경의 크기를 작게 유지하고, 문제 발생 시 원인을 쉽게 파악할 수 있게 한다.
배포는 자동화되어 있지만, 중요한 시간대에는 제한될 수 있다. 예를 들어, 새로운 인기 콘텐츠가 공개되는 시점이나 주말 저녁 피크 시간대에는 배포를 자제하여 안정성을 최우선으로 한다. 배포 동결 기간에는 긴급한 버그 수정만 허용된다.
롤백은 일상적인 작업으로 받아들여진다. 모든 배포는 쉽게 롤백할 수 있도록 설계되며, 문제가 발생하면 주저 없이 이전 버전으로 되돌린다. 롤백 후에는 근본 원인을 분석하고, 문제를 수정한 후 다시 배포한다.
배포 모니터링
배포 과정은 철저하게 모니터링된다. 실시간 대시보드는 배포 진행 상황, 헬스 체크 결과, 핵심 메트릭을 표시한다. 이상 징후 탐지 알고리즘은 기준선과 비교하여 이상한 패턴을 자동으로 감지한다.
배포 후에는 일정 기간 “bake time”을 가지며, 이 동안 시스템이 안정적으로 작동하는지 관찰한다. 에러 로그, 응답 시간, 리소스 사용률 등이 집중적으로 모니터링되며, 문제 징후가 보이면 자동으로 알림이 발생한다.
배포 이력은 추적되고 감사된다. 누가, 언제, 무엇을, 왜 배포했는지 기록되며, 이는 문제 발생 시 원인 분석에 활용된다. 배포 메트릭(배포 빈도, 성공률, 롤백률 등)은 팀의 성숙도를 평가하는 지표로 사용된다.
5. DevOps
넷플릭스의 DevOps 문화는 “You build it, you run it” 원칙을 중심으로 형성되어 있다. 개발팀과 운영팀의 전통적인 분리를 없애고, 풀사이클 개발자 모델을 채택했다.
풀사이클 개발자 (Full Cycle Developer)
풀사이클 개발자는 소프트웨어의 전체 생명주기에 대해 책임진다. 설계, 구현, 테스트뿐만 아니라 배포, 모니터링, 인시던트 대응, 성능 최적화까지 모두 포함된다. 이는 개발자가 자신의 코드가 프로덕션에서 어떻게 작동하는지 직접 경험하게 하며, 운영 관점에서 코드를 작성하도록 유도한다.
온콜(On-Call) 책임은 이러한 모델의 핵심이다. 각 팀은 자신들의 서비스에 대한 온콜 로테이션을 운영하며, 문제 발생 시 담당 개발자가 직접 대응한다. 이는 개발자가 안정적이고 모니터링 가능한 시스템을 구축하도록 강력한 동기를 제공한다. 새벽 3시에 알림으로 깨어나는 경험은 더 나은 에러 처리와 알림 정책을 만들게 한다.
이러한 책임은 광범위한 자율성과 함께 온다. 팀은 기술 스택을 선택하고, 아키텍처를 결정하며, 배포 시점을 정할 수 있다. 이러한 자율성은 혁신을 촉진하고, 팀의 주인의식을 강화한다.
자동화
넷플릭스의 DevOps 문화는 광범위한 자동화 위에 구축되어 있다. 반복적이고 수작업이 필요한 작업은 자동화의 대상이 되며, 이는 효율성을 높이고 인적 오류를 줄인다.
인프라 프로비저닝은 Terraform과 같은 Infrastructure as Code(IaC) 도구를 통해 자동화된다. 인프라 구성은 코드로 정의되고 버전 관리되며, 이는 재현 가능하고 일관된 환경을 보장한다. 새로운 환경이 필요할 때, 수동으로 서버를 설정하는 대신 코드를 실행하여 몇 분 안에 전체 인프라를 생성한다.
CI/CD 파이프라인은 완전히 자동화되어 있다. 코드가 커밋되면 자동으로 빌드되고, 테스트되며, 배포된다. 개발자는 배포 버튼을 누르는 것 외에 별다른 작업이 필요 없다. 파이프라인의 각 단계는 스크립트로 정의되고 버전 관리되어, 투명하고 재현 가능하다.
모니터링과 알림도 자동화된다. 이상 탐지 알고리즘은 비정상적인 패턴을 자동으로 식별하고, 미리 정의된 임계값을 초과하면 적절한 담당자에게 알림을 보낸다. 일부 간단한 문제는 자동 치유(Auto-remediation) 메커니즘을 통해 인간의 개입 없이 해결된다.
클라우드 네이티브 접근
넷플릭스는 AWS 클라우드를 전적으로 활용하는 클라우드 네이티브 아키텍처를 구축했다. 데이터센터를 운영하는 대신, AWS의 관리형 서비스를 최대한 활용하여 인프라 관리 부담을 줄이고 비즈니스 로직에 집중한다.
Auto Scaling은 트래픽 패턴에 따라 자동으로 인스턴스를 추가하거나 제거한다. 피크 시간대에는 더 많은 리소스가 프로비저닝되고, 한가한 시간대에는 축소하여 비용을 절감한다. 예측 스케일링(Predictive Scaling)은 과거 패턴을 학습하여 트래픽 증가를 예상하고 미리 대비한다.
다중 리전 배포는 고가용성과 글로벌 성능을 보장한다. 넷플릭스는 여러 AWS 리전에 서비스를 배포하여, 리전 장애에도 서비스를 지속할 수 있다. 지리적으로 분산된 사용자들은 가장 가까운 리전에서 서비스를 받아 낮은 지연 시간을 경험한다.
클라우드 비용 최적화는 지속적인 과제다. Reserved Instances와 Spot Instances를 조합하여 비용을 절감하고, 불필요한 리소스를 식별하여 제거한다. 비용 가시성 도구는 각 팀의 클라우드 지출을 추적하고, 비용 효율성을 개선할 기회를 파악한다.
협업과 지식 공유
넷플릭스는 협업과 지식 공유를 장려하는 문화를 가지고 있다. 팀 간 사일로를 없애고, 베스트 프랙티스와 학습 내용을 공유한다.
내부 기술 블로그와 위키는 지식을 문서화하고 공유하는 플랫폼이다. 엔지니어들은 자신이 해결한 문제, 배운 교훈, 개발한 도구 등을 문서화하여 다른 팀이 같은 문제를 반복하지 않도록 한다.
기술 토크와 학습 세션은 정기적으로 열린다. 팀이 새로운 기술이나 프로젝트를 다른 팀에 소개하고, 피드백을 받는다. 이는 조직 전체의 기술 수준을 높이고, 혁신을 촉진한다.
오픈소스 기여는 넷플릭스 엔지니어링 문화의 중요한 부분이다. Spinnaker, Eureka, Hystrix 등 많은 내부 도구를 오픈소스로 공개하여, 커뮤니티와 협력하고 생태계 발전에 기여한다. 오픈소스는 또한 인재 채용과 브랜드 구축에도 도움이 된다.
실패로부터 학습
넷플릭스는 실패를 학습의 기회로 본다. 인시던트가 발생하면, 비난하지 않는 사후 분석(Blameless Post-mortem)을 수행한다. 목표는 책임자를 찾는 것이 아니라, 무엇이 잘못되었는지 이해하고 재발을 방지하는 것이다.
사후 분석 문서는 타임라인, 근본 원인, 영향 범위, 완화 조치, 개선 계획 등을 포함한다. 이는 조직 전체와 공유되어, 다른 팀도 유사한 문제를 피할 수 있도록 한다. 실패에서 배우는 것은 성공에서 배우는 것만큼 중요하다.
카오스 엔지니어링은 이러한 학습 문화를 제도화한다. 의도적으로 장애를 유발하여 시스템의 약점을 발견하고, 이를 개선한다. 실패는 피할 수 없는 것이므로, 통제된 환경에서 미리 경험하고 대비하는 것이 낫다.
6. ALM (Application Lifecycle Management)
넷플릭스의 애플리케이션 생명주기 관리는 도구, 프로세스, 문화가 통합된 접근을 취한다. 소프트웨어가 아이디어에서 프로덕션까지, 그리고 최종적으로 폐기까지 거치는 전체 여정을 관리한다.
요구사항 관리
넷플릭스는 애자일(Agile) 방법론을 채택하고 있으며, 대부분의 팀이 스크럼(Scrum)이나 칸반(Kanban)을 사용한다. 요구사항은 사용자 스토리로 정의되고, 백로그에서 우선순위가 관리된다.
프로덕트 매니저, 엔지니어, 디자이너가 협력하여 기능을 정의한다. 요구사항은 구체적이고 측정 가능하며, 비즈니스 가치가 명확해야 한다. “왜”를 이해하는 것이 “무엇”을 구현하는 것만큼 중요하다.
사용자 연구와 데이터 분석은 요구사항을 검증한다. 가정에 기반한 기능을 구축하기보다는, 실제 사용자 행동과 피드백을 바탕으로 결정한다. A/B 테스트는 기능의 효과를 객관적으로 측정하여, 투자 대비 수익을 평가한다.
버전 관리
Git은 모든 코드의 버전 관리 시스템이다. 각 팀은 자신들의 리포지토리를 소유하며, 브랜치 전략은 팀의 필요에 따라 선택한다. 일반적으로는 Git Flow나 GitHub Flow와 같은 검증된 전략을 따른다.
메인 브랜치는 항상 배포 가능한 상태로 유지된다. 새로운 기능은 피처 브랜치에서 개발되고, 완료되면 메인 브랜치로 병합된다. 병합 전에는 코드 리뷰와 자동화된 테스트를 통과해야 한다.
태깅(Tagging)과 릴리스 노트는 버전을 추적한다. 각 프로덕션 배포는 Git 태그로 표시되며, 릴리스 노트는 변경 내용을 문서화한다. 이는 특정 시점의 코드 상태를 재현하고, 변경 이력을 추적하는 데 필수적이다.
빌드 및 아티팩트 관리
빌드 시스템은 소스 코드를 실행 가능한 아티팩트로 변환한다. Gradle이나 Maven 같은 빌드 도구를 사용하며, 빌드는 재현 가능하고 결정적이어야 한다. 같은 소스 코드는 언제, 어디서 빌드하더라도 같은 결과를 생성한다.
아티팩트 리포지토리는 빌드 결과물을 저장하고 관리한다. Nexus나 Artifactory 같은 도구를 사용하여, JAR 파일, Docker 이미지, AMI(Amazon Machine Images) 등을 보관한다. 아티팩트는 메타데이터와 함께 저장되어, 언제, 누가, 어떤 소스 코드에서 빌드했는지 추적할 수 있다.
의존성 관리는 빌드 프로세스의 중요한 부분이다. 각 서비스는 자신이 의존하는 라이브러리와 그 버전을 명시한다. 보안 취약점이 발견된 라이브러리는 자동으로 식별되고, 팀에게 업데이트하도록 알린다.
환경 관리
넷플릭스는 여러 환경을 운영한다. 개발 환경은 개인 개발자가 사용하며, 통합 환경은 여러 서비스가 함께 작동하는 것을 검증한다. 스테이징 환경은 프로덕션과 가능한 한 유사하게 구성되어, 최종 검증을 수행한다.
환경 간 일관성은 중요하다. Infrastructure as Code를 통해 모든 환경이 같은 방식으로 프로비저닝되며, 설정의 차이는 명시적으로 관리된다. “스테이징에서는 작동하는데 프로덕션에서는 안 됨” 같은 문제를 최소화한다.
환경별 구성은 외부화된다. 데이터베이스 연결 문자열, API 엔드포인트, 피처 플래그 설정 등은 코드에 하드코딩되지 않고, 환경 변수나 구성 서비스를 통해 제공된다. 이는 같은 아티팩트가 모든 환경에서 사용될 수 있게 한다.
릴리스 관리
릴리스 계획은 비즈니스 목표와 연계된다. 주요 기능 출시는 마케팅 캠페인과 조율되며, 적절한 타이밍에 사용자에게 전달된다. 하지만 대부분의 변경은 계획된 릴리스를 기다리지 않고 지속적으로 배포된다.
릴리스 승인은 자동화와 인간 판단이 조합된다. 대부분의 배포는 자동으로 승인되지만, 중요한 변경이나 위험한 시간대에는 수동 승인이 필요할 수 있다. 승인 권한은 명확하게 정의되고, 감사 추적이 유지된다.
릴리스 커뮤니케이션은 투명하게 이루어진다. 주요 변경사항은 내부 채널을 통해 조직 전체에 공유되며, 고객 대면 변경은 적절히 공지된다. 장애나 성능 저하가 예상되는 유지보수 작업은 사전에 계획되고 알려진다.
구성 및 변경 관리
구성 관리는 시스템의 상태를 추적하고 제어한다. 어떤 버전의 소프트웨어가 어디에 배포되어 있는지, 어떤 설정이 적용되어 있는지 파악할 수 있어야 한다.
변경 관리 프로세스는 통제와 민첩성의 균형을 맞춘다. 전통적인 변경 자문 위원회(CAB)는 없지만, 높은 위험의 변경은 더 많은 검토와 승인을 거친다. 피어 리뷰와 자동화된 검증이 주요 통제 메커니즘이다.
구성 드리프트를 방지하기 위해, Infrastructure as Code와 불변 인프라를 활용한다. 서버는 직접 수정되지 않고, 변경이 필요하면 새로운 인스턴스로 교체된다. 이는 예상치 못한 설정 변경으로 인한 문제를 제거한다.
7. VM 등 서버 (장비) 수
넷플릭스는 완전히 클라우드 기반 인프라를 운영하며, 물리적 서버를 소유하거나 데이터센터를 운영하지 않는다. 모든 컴퓨팅 리소스는 AWS(Amazon Web Services)에서 제공되며, 규모는 비즈니스 성장과 트래픽 패턴에 따라 동적으로 조절된다.
클라우드 인프라 규모
넷플릭스는 AWS에서 수십만 개의 EC2 인스턴스를 운영하는 것으로 알려져 있다. 정확한 수치는 공개되지 않지만, 업계 추정과 공개된 기술 블로그 포스트를 종합하면, 피크 시간대에는 100,000개 이상의 인스턴스가 실행될 수 있다.
이러한 인스턴스들은 전 세계 여러 AWS 리전에 분산되어 있다. 북미, 유럽, 아시아 태평양, 남미 등 주요 시장마다 리전이 배포되어, 글로벌 사용자에게 낮은 지연 시간을 제공한다. 각 리전 내에서도 여러 가용 영역(Availability Zone)을 활용하여 단일 데이터센터 장애에 대한 복원력을 확보한다.
인스턴스 타입은 워크로드에 따라 다양하다. 컴퓨팅 집약적인 인코딩 작업에는 C 시리즈 인스턴스를, 메모리 집약적인 캐싱 서비스에는 R 시리즈 인스턴스를 사용한다. 일반적인 애플리케이션 서버에는 M 시리즈와 같은 범용 인스턴스가 활용된다.
Auto Scaling과 탄력성
넷플릭스의 트래픽은 시간대에 따라 극심한 변동을 보인다. 저녁 시간대, 특히 새로운 인기 시리즈가 공개되는 날에는 평소 대비 수 배의 트래픽이 발생할 수 있다. 반면 새벽 시간대에는 트래픽이 크게 줄어든다.
Auto Scaling Group은 이러한 수요 변화에 자동으로 대응한다. CPU 사용률, 네트워크 트래픽, 요청 큐 길이 등 다양한 메트릭을 기반으로 인스턴스 수를 조절한다. 부하가 증가하면 새 인스턴스가 자동으로 추가되고, 감소하면 불필요한 인스턴스가 종료되어 비용을 절감한다.
예측 스케일링(Predictive Scaling)은 과거 패턴을 학습하여 트래픽 증가를 미리 예상한다. 매주 금요일 저녁 8시에 트래픽이 급증한다는 패턴을 학습하면, 해당 시간 전에 미리 인스턴스를 추가하여 준비한다. 이는 반응형 스케일링의 지연을 줄이고 더 안정적인 성능을 제공한다.
Spot 인스턴스는 비용 최적화의 핵심 전략이다. 배치 처리나 인코딩 같은 중단 가능한 워크로드에 Spot 인스턴스를 활용하여, On-Demand 가격 대비 최대 90%까지 비용을 절감한다. Spot 인스턴스가 회수될 위험에 대비하여, 작업은 체크포인트를 지원하고 다른 인스턴스로 쉽게 이동할 수 있도록 설계된다.
콘텐츠 전송 인프라
스트리밍 트래픽의 대부분은 Open Connect라는 넷플릭스 자체 CDN(Content Delivery Network)을 통해 제공된다. Open Connect는 ISP(인터넷 서비스 제공자) 내부나 인터넷 교환 지점에 위치한 전용 서버로 구성된다.
Open Connect Appliance(OCA)는 특수 제작된 서버로, 대용량 스토리지와 고속 네트워크 인터페이스를 갖추고 있다. 각 OCA는 수십 테라바이트의 콘텐츠를 저장하고, 초당 수십 기가비트의 트래픽을 처리할 수 있다. 전 세계적으로 수천 개의 OCA가 배포되어, 사용자와 가까운 곳에서 콘텐츠를 제공한다.
콘텐츠는 인기도와 지역별 시청 패턴에 따라 OCA에 사전 배치(Pre-positioning)된다. 머신러닝 알고리즘은 어떤 콘텐츠가 어느 지역에서 인기를 끌지 예측하여, 밤 시간대에 미리 다운로드한다. 이는 피크 시간대의 백본 네트워크 트래픽을 줄이고 스트리밍 품질을 개선한다.
데이터 저장 인프라
넷플릭스는 다양한 AWS 스토리지 서비스를 활용한다. S3는 콘텐츠 원본 파일, 인코딩된 비디오, 이미지 등 대용량 객체 저장에 사용된다. 수십 페타바이트의 데이터가 S3에 저장되어 있으며, 이는 내구성과 가용성이 높은 저장 솔루션을 제공한다.
데이터베이스 인프라는 NoSQL과 SQL의 조합이다. Cassandra 클러스터는 사용자 프로필, 시청 이력, 평가 등 대규모 분산 데이터를 저장한다. 수천 개의 Cassandra 노드가 여러 리전에 걸쳐 배포되어, 높은 쓰기 처리량과 읽기 확장성을 제공한다.
MySQL과 PostgreSQL 같은 관계형 데이터베이스는 트랜잭션 무결성이 중요한 데이터에 사용된다. 결제 정보, 구독 상태 등은 ACID 속성이 보장되는 관계형 데이터베이스에 저장된다. AWS RDS를 활용하여 백업, 패치, 복제 등의 관리 작업을 자동화한다.
캐싱 인프라
EVCache는 넷플릭스가 개발한 분산 인메모리 캐시 시스템이다. Memcached를 기반으로 하며, AWS의 여러 가용 영역에 걸쳐 복제되어 고가용성을 제공한다. 수천 개의 EVCache 노드가 수백 테라바이트의 데이터를 캐싱하며, 매초 수백만 개의 요청을 처리한다.
캐싱은 데이터베이스 부하를 크게 줄이고 응답 시간을 개선한다. 사용자 프로필, 콘텐츠 메타데이터, 추천 결과 등 자주 조회되는 데이터는 EVCache에 저장되어, 밀리초 이내에 반환된다. 캐시 히트율은 면밀히 모니터링되며, 높은 히트율을 유지하기 위해 캐시 전략이 지속적으로 최적화된다.
네트워크 아키텍처
넷플릭스는 AWS의 VPC(Virtual Private Cloud)를 활용하여 격리된 네트워크 환경을 구성한다. 각 서비스는 별도의 서브넷에 배포되며, 보안 그룹과 네트워크 ACL을 통해 트래픽이 제어된다.
로드 밸런싱은 여러 계층에서 수행된다. ELB(Elastic Load Balancer)는 들어오는 트래픽을 여러 인스턴스에 분산하고, 클라이언트 측 로드 밸런싱은 Ribbon을 통해 구현된다. 이러한 다층 로드 밸런싱은 단일 장애 지점을 제거하고 유연성을 제공한다.
Direct Connect는 넷플릭스 오피스와 AWS 리전 간 전용 네트워크 연결을 제공한다. 이는 더 안정적이고 예측 가능한 네트워크 성능을 제공하며, 대규모 데이터 전송에 유용하다.
8. Container 등 애플리케이션 환경
넷플릭스의 애플리케이션 환경은 클라우드 네이티브 설계 원칙을 따르며, 컨테이너 기술을 광범위하게 활용한다. 전통적인 VM 기반 배포와 현대적인 컨테이너 오케스트레이션을 조합하여, 각 워크로드에 최적화된 환경을 제공한다.
Titus - 넷플릭스 컨테이너 플랫폼
Titus는 넷플릭스가 개발한 컨테이너 관리 플랫폼으로, Apache Mesos 위에 구축되어 있다. Titus는 수만 개의 컨테이너를 관리하며, 배치 처리, 서비스 작업, GPU 워크로드 등 다양한 유형의 작업을 지원한다.
Titus는 AWS EC2 인스턴스를 클러스터로 묶고, 그 위에서 Docker 컨테이너를 실행한다. 각 컨테이너는 격리된 환경에서 실행되며, CPU, 메모리, 네트워크, 디스크 I/O 리소스가 제한된다. 이는 멀티테넌시를 가능하게 하고, 한 컨테이너의 리소스 사용이 다른 컨테이너에 영향을 미치지 않도록 한다.
컨테이너 이미지는 Docker Hub 또는 내부 레지스트리에 저장된다. 이미지는 레이어로 구성되어, 공통 레이어는 재사용되고 변경된 부분만 다운로드된다. 이는 배포 시간을 단축하고 네트워크 대역폭을 절약한다.
Titus는 다양한 스케줄링 정책을 지원한다. 비용 효율성을 위해 Spot 인스턴스를 우선적으로 사용하고, Spot이 부족하거나 회수될 위험이 있을 때 On-Demand 인스턴스로 전환한다. GPU가 필요한 머신러닝 워크로드는 GPU 인스턴스에 스케줄되며, 리소스 사용률을 최적화하기 위해 bin packing 알고리즘이 적용된다.
마이크로서비스 런타임
대부분의 넷플릭스 마이크로서비스는 JVM(Java Virtual Machine) 기반이다. Java와 Groovy가 주요 프로그래밍 언어이며, Spring Boot가 널리 사용되는 프레임워크다. Spring Boot는 독립 실행 가능한 JAR 파일을 생성하고, 임베디드 서버를 포함하여 배포를 단순화한다.
Node.js는 UI 레이어와 API 게이트웨이에서 많이 사용된다. JavaScript의 비동기 특성은 I/O 집약적인 작업에 적합하며, 프론트엔드와 백엔드 간 코드 공유를 가능하게 한다. Next.js와 React는 서버 사이드 렌더링을 구현하는 데 활용된다.
Python은 데이터 분석, 머신러닝, 인프라 자동화에 광범위하게 사용된다. Jupyter Notebook은 데이터 과학자들이 탐색적 분석을 수행하는 주요 도구며, TensorFlow와 PyTorch는 머신러닝 모델을 훈련하고 배포하는 데 사용된다.
런타임 환경은 표준화되어 있다. 각 서비스는 정의된 JVM 옵션, 환경 변수, 시스템 속성을 가지며, 이는 일관된 성능과 동작을 보장한다. 가비지 컬렉션 튜닝, 스레드 풀 크기, 커넥션 풀 설정 등은 워크로드 특성에 맞게 조정된다.
서비스 메시와 네트워킹
넷플릭스는 초기에 클라이언트 측 로드 밸런싱과 서비스 디스커버리를 구현했으며, 이는 Ribbon과 Eureka를 통해 제공된다. 각 마이크로서비스는 Eureka 클라이언트를 포함하여, 서비스 레지스트리에서 의존 서비스의 인스턴스 목록을 조회하고 로드 밸런싱을 수행한다.
Zuul은 API 게이트웨이이자 엣지 서비스로, 모든 외부 트래픽의 진입점이다. Zuul은 동적 라우팅, 인증, 속도 제한, 모니터링 등 다양한 기능을 필터 체인을 통해 제공한다. Zuul 2는 비동기 논블로킹 아키텍처를 채택하여, 더 높은 처리량과 낮은 지연 시간을 달성한다.
서비스 간 통신은 주로 HTTP/REST를 통해 이루어진다. gRPC는 고성능이 요구되는 내부 서비스 간 통신에 점차 도입되고 있다. gRPC는 프로토콜 버퍼를 사용하여 직렬화 오버헤드를 줄이고, HTTP/2를 활용하여 멀티플렉싱과 스트리밍을 지원한다.
회로 차단과 폴백은 Hystrix를 통해 구현된다. Hystrix는 서비스 호출을 래핑하여, 실패율이 임계값을 초과하면 회로를 차단하고 폴백 로직을 실행한다. 이는 연쇄 장애를 방지하고, 부분적인 기능 저하 상태에서도 서비스를 계속 제공할 수 있게 한다.
데이터 처리 환경
Apache Spark는 대규모 배치 데이터 처리의 핵심이다. Titus 위에서 Spark 클러스터가 실행되며, 수백 테라바이트의 데이터를 처리한다. Spark는 사용자 행동 분석, 추천 모델 학습, 비즈니스 리포트 생성 등에 활용된다.
Flink는 실시간 스트림 처리에 사용되며, 복잡한 이벤트 처리(CEP)와 상태 관리를 지원한다. 사용자 활동 스트림을 실시간으로 분석하여, 이상 탐지, 실시간 추천 업데이트, 운영 메트릭 계산 등을 수행한다.
Presto는 대화형 쿼리 엔진으로, 데이터 과학자와 분석가가 페타바이트 규모의 데이터를 SQL로 쉽게 탐색할 수 있게 한다. Presto는 S3, Cassandra, MySQL 등 다양한 데이터 소스에 접속하여, 통합된 쿼리 인터페이스를 제공한다.
모니터링과 관찰성 스택
Atlas는 넷플릭스의 시계열 메트릭 플랫폼으로, 초당 수백만 개의 메트릭을 수집하고 저장한다. 각 마이크로서비스는 Spectator 라이브러리를 사용하여 메트릭을 생성하고, 이는 Atlas로 전송된다. Atlas는 차원 기반 메트릭을 지원하여, 서비스, 리전, 인스턴스 등 다양한 차원으로 데이터를 집계하고 쿼리할 수 있다.
로그 수집은 중앙 집중식으로 이루어진다. 각 인스턴스의 로그는 로그 에이전트에 의해 수집되고, Elasticsearch 클러스터로 전송된다. Kibana를 통해 로그를 검색하고 분석하며, 패턴을 파악하고 문제를 진단한다.
분산 트레이싱은 요청이 여러 서비스를 거치면서 처리되는 과정을 추적한다. 각 요청에는 고유한 추적 ID가 할당되고, 서비스 간 호출마다 스팬(span)이 생성된다. Zipkin과 유사한 내부 트레이싱 시스템은 이러한 스팬을 수집하고 시각화하여, 지연의 원인을 파악할 수 있게 한다.
보안 환경
보안은 모든 계층에 내장되어 있다. 네트워크 수준에서는 VPC, 보안 그룹, 네트워크 ACL을 통해 트래픽이 제어된다. 애플리케이션 수준에서는 인증, 권한 부여, 암호화가 구현된다.
서비스 간 통신은 mTLS(mutual TLS)를 통해 암호화되고 인증된다. 각 서비스는 인증서를 가지며, 통신할 때 서로의 신원을 검증한다. 인증서는 자동으로 발급되고 갱신되며, 짧은 유효 기간을 가져 손상된 인증서의 영향을 제한한다.
비밀 정보(암호, API 키 등)는 코드나 설정 파일에 하드코딩되지 않는다. AWS Secrets Manager나 Vault 같은 비밀 관리 시스템에 저장되고, 런타임에 주입된다. 접근은 엄격하게 제어되며, 감사 로그가 유지된다.
취약점 스캔은 지속적으로 수행된다. 컨테이너 이미지는 배포 전에 스캔되어 알려진 취약점이 있는지 확인한다. 실행 중인 시스템도 정기적으로 스캔되며, 새로운 취약점이 발견되면 패치가 우선순위에 따라 적용된다.
9. 추가 핵심 요소
넷플릭스 MSA의 성공을 이해하기 위해서는 몇 가지 추가적인 핵심 요소들을 살펴볼 필요가 있다.
데이터 아키텍처와 일관성
마이크로서비스 아키텍처에서 데이터 관리는 복잡한 과제다. 각 서비스가 자신의 데이터베이스를 소유하는 “database per service” 패턴은 서비스 간 독립성을 높이지만, 데이터 일관성과 트랜잭션 관리를 어렵게 한다.
넷플릭스는 최종 일관성(Eventual Consistency)을 받아들인다. 강한 일관성이 필요한 경우는 제한적이며, 대부분의 경우 최종적으로 일관된 상태에 도달하는 것으로 충분하다. 예를 들어, 사용자가 영화를 평가하면 즉시 추천 시스템에 반영되지 않을 수 있지만, 몇 초 또는 몇 분 안에는 반영된다.
이벤트 소싱과 CQRS(Command Query Responsibility Segregation) 패턴은 데이터 일관성을 관리하는 주요 메커니즘이다. 상태 변경은 이벤트로 표현되고, 이벤트 스트림을 통해 전파된다. 각 서비스는 자신에게 관련된 이벤트를 구독하고, 로컬 데이터를 업데이트한다.
Saga 패턴은 분산 트랜잭션을 구현한다. 긴 트랜잭션은 일련의 로컬 트랜잭션으로 분해되고, 각 단계는 보상 트랜잭션(compensating transaction)을 가진다. 중간에 실패하면 이미 완료된 단계를 보상 트랜잭션을 통해 되돌린다.
조직 구조와 콘웨이의 법칙
콘웨이의 법칙에 따르면, 시스템의 아키텍처는 그것을 설계하는 조직의 커뮤니케이션 구조를 반영한다. 넷플릭스는 이를 역으로 활용하여, 원하는 아키텍처를 지원하는 조직 구조를 설계한다.
팀은 비즈니스 도메인을 중심으로 구성되며, 각 팀은 엔드투엔드 책임을 진다. 프로덕트 매니저, 엔지니어, 디자이너가 같은 팀에 속하여, 기능의 전체 생명주기를 함께 관리한다. 이는 의사소통을 단순화하고, 의사결정을 빠르게 한다.
팀 크기는 “two-pizza team” 규칙을 따라 작게 유지된다. 작은 팀은 커뮤니케이션 오버헤드가 낮고, 빠르게 움직일 수 있다. 각 팀은 몇 개의 마이크로서비스를 소유하며, 이들 서비스는 팀의 도메인 경계를 반영한다.
팀 간 의존성은 최소화되지만, 협력은 장려된다. API 계약, 공유 라이브러리, 플랫폼 서비스 등은 팀 간 조율이 필요하며, 이는 길드(Guild)나 챕터(Chapter) 같은 횡단 조직을 통해 이루어진다.
기술 부채 관리
빠르게 변화하는 환경에서 기술 부채는 불가피하다. 넷플릭스는 기술 부채를 받아들이되, 의도적으로 관리한다.
기술 부채는 투명하게 추적된다. 팀은 자신들의 기술 부채 목록을 유지하고, 정기적으로 검토한다. 각 항목은 우선순위가 매겨지며, 비즈니스 영향과 해결 비용이 평가된다.
기술 부채 상환은 일상적인 개발의 일부다. 각 스프린트에서 일정 비율의 시간을 기술 부채 해결에 할애한다. 큰 규모의 리팩토링은 별도의 프로젝트로 계획되고 실행된다.
레거시 시스템 마이그레이션은 점진적으로 이루어진다. 큰 규모의 일회성 마이그레이션 대신, 스트랭글러 패턴(Strangler Pattern)을 사용하여 새로운 시스템이 점차 기존 시스템을 대체한다. 이는 리스크를 줄이고, 지속적인 가치 전달을 가능하게 한다.
성능 최적화
글로벌 규모에서 성능 최적화는 지속적인 과제다. 밀리초 수준의 응답 시간 개선도 사용자 경험에 큰 영향을 미칠 수 있다.
캐싱은 성능 최적화의 핵심 전략이다. EVCache는 데이터베이스 조회를 줄이고, CDN은 콘텐츠 전송을 가속화한다. 캐시 무효화 전략은 신선도와 성능 사이의 균형을 맞춘다.
데이터베이스 쿼리 최적화는 지속적으로 수행된다. 느린 쿼리는 식별되고 분석되며, 인덱스가 추가되거나 쿼리가 재작성된다. Cassandra의 경우, 데이터 모델은 쿼리 패턴에 맞게 비정규화된다.
네트워크 대역폭 최적화는 특히 모바일 환경에서 중요하다. 이미지는 WebP 같은 효율적인 포맷으로 인코딩되고, API 응답은 압축된다. GraphQL은 클라이언트가 필요한 데이터만 요청할 수 있게 하여, 오버페칭을 줄인다.
글로벌 확장과 지역화
넷플릭스는 190개 이상의 국가에서 서비스를 제공하며, 각 시장의 고유한 요구사항을 충족해야 한다.
콘텐츠 지역화는 단순한 번역을 넘어선다. 자막과 더빙은 여러 언어로 제공되며, 문화적 맥락을 고려하여 조정된다. 메타데이터, UI 텍스트, 마케팅 메시지도 모두 현지화된다.
규제 준수는 각 시장마다 다르다. 데이터 프라이버시(GDPR, CCPA 등), 콘텐츠 등급, 결제 규정 등은 지역별로 구현되어야 한다. 이러한 복잡성은 설정 기반 접근으로 관리되며, 각 시장의 규칙은 코드가 아닌 설정으로 정의된다.
성능은 지역별로 최적화된다. 콘텐츠는 사용자와 가까운 CDN 노드에서 제공되고, API 게이트웨이는 가장 가까운 리전으로 라우팅한다. 네트워크 지연은 지속적으로 모니터링되며, 문제가 있는 경로는 식별되고 개선된다.
머신러닝과 개인화
머신러닝은 넷플릭스 경험의 핵심이다. 추천 시스템, 썸네일 선택, 비디오 인코딩, 품질 적응 등 다양한 영역에서 활용된다.
추천 시스템은 여러 모델의 앙상블이다. 협업 필터링, 콘텐츠 기반 필터링, 딥러닝 모델 등이 조합되어, 개인화된 추천을 제공한다. 모델은 지속적으로 학습하고 A/B 테스트를 통해 개선된다.
썸네일 개인화는 사용자마다 다른 이미지를 보여준다. 같은 영화라도, 로맨스를 좋아하는 사용자에게는 로맨틱한 장면의 썸네일을, 액션을 좋아하는 사용자에게는 액션 장면의 썸네일을 제공한다. 이는 클릭률을 크게 향상시킨다.
품질 적응(Adaptive Bitrate Streaming)은 네트워크 조건에 따라 비디오 품질을 조절한다. 머신러닝 모델은 사용자의 네트워크 상태를 예측하고, 버퍼링 없이 최고 품질을 제공하는 비트레이트를 선택한다.
머신러닝 인프라는 모델 훈련과 서빙을 지원한다. 훈련은 Spark와 TensorFlow를 사용하여 대규모 클러스터에서 수행되며, 훈련된 모델은 서빙 인프라로 배포된다. 모델 버전 관리, A/B 테스트, 모니터링은 전체 ML 생명주기를 지원한다.
결론
넷플릭스의 마이크로서비스 아키텍처는 단순한 기술적 선택이 아니라, 비즈니스 목표를 달성하기 위한 전략적 접근이다. 빠른 혁신, 글로벌 확장, 높은 가용성이라는 요구사항을 충족하기 위해, 넷플릭스는 조직 문화, 개발 프로세스, 기술 스택 전반에 걸친 포괄적인 변화를 추진했다.
자유와 책임의 문화는 엔지니어들이 최선의 결정을 내릴 수 있도록 권한을 부여하면서도, 그 결정에 대한 책임을 지게 한다. 카오스 엔지니어링은 장애를 일상으로 받아들이고, 시스템을 지속적으로 강화한다. 지속적 배포는 변경을 빠르게 전달하고, A/B 테스트는 데이터 기반 의사결정을 가능하게 한다.
이러한 성공 뒤에는 끊임없는 실험과 학습이 있다. 넷플릭스는 실패를 두려워하지 않으며, 각 실패를 개선의 기회로 삼는다. 오픈소스 기여를 통해 커뮤니티와 학습을 공유하고, 업계 전체의 발전에 기여한다.
넷플릭스의 MSA 여정은 여전히 진행 중이다. 새로운 기술이 등장하고, 비즈니스 요구사항이 변화하며, 규모가 계속 성장함에 따라, 아키텍처도 함께 진화한다. 하지만 핵심 원칙인 자율성, 복원력, 지속적 개선은 변하지 않는다.
다른 조직들이 넷플릭스의 접근을 그대로 복사할 필요는 없다. 각 조직은 자신의 컨텍스트, 규모, 문화에 맞는 아키텍처를 찾아야 한다. 하지만 넷플릭스의 경험에서 배울 수 있는 원칙들은 보편적이다. 작게 시작하고, 자주 배포하며, 실패를 빨리 발견하고, 지속적으로 개선하는 것. 이것이 현대 소프트웨어 엔지니어링의 핵심이며, 넷플릭스가 보여준 길이다.
제(Claude) 지식 베이스(2025년 1월까지의 정보)를 바탕으로 넷플릭스의 마이크로서비스 아키텍처를 다음 주제들로 구성하여 상세하게 다뤘습니다:
요청하신 모든 항목을 서술형으로 작성했으며, 각 섹션에서는 넷플릭스의 실제 사례와 구체적인 구현 방식, 기술적 의사결정의 배경과 철학까지 포함했습니다. 특히 넷플릭스가 개발한 오픈소스 도구들(Spinnaker, Eureka, Hystrix, Zuul, Chaos Monkey 등)과 그들의 DevOps 문화, 카오스 엔지니어링 접근법도 자세히 다뤘습니다.
작성 일자: 2026-01-11