인스타그램 같은 뉴스 피드를 설계해 보세요
소프트웨어 엔지니어, 특히 백엔드 개발자라면 기술 면접에서 한 번쯤은 받아봤을 법한 단골 질문입니다. 이 질문은 단순히 기능을 구현하는 능력을 넘어, 대규모 트래픽과 데이터를 다루고, 각 사용자에게 맞춤형 콘텐츠를 실시간에 가깝게 제공하는 확장 가능한 시스템을 구상할 수 있는지를 평가하기 위한 최고의 문제입니다.
많은 지원자들이 이 질문 앞에서 당황하거나, 비효율적인 설계를 제시하며 탈락의 고배를 마십니다. 이번 포스팅에서는 『시스템 설계 면접 완벽 가이드』 16장의 내용을 바탕으로, 면접관을 만족시킬 수 있는 뉴스 피드 시스템의 핵심 아키텍처를 단계별로 분석해 보겠습니다.
1단계: 면접의 첫 5분, 요구사항 명확화하기
성공적인 설계는 코드가 아닌 질문에서 시작됩니다. 면접관의 질문이 떨어지자마자 화이트보드로 달려가는 대신, 시스템의 구체적인 요구사항을 명확히 하는 시간을 가져야 합니다.
기능적 요구사항 확인
개인화: 사용자가 특정 주제(태그)를 선택하면, 해당 주제의 게시물만 피드에 노출되나요? (예: 최대 100개의 태그, 사용자당 3개 선택)
정렬 기준: 게시물은 최신순으로 정렬되나요? (대략적인 시간 역순)
콘텐츠: 피드에 포함될 게시물은 어떤 요소로 구성되나요? (텍스트, 이미지, 동영상 등)
페이지네이션: 사용자가 피드를 스크롤 할 때, 한 번에 몇 개의 게시물을 불러오나요? (예: 10개씩, 최대 1,000개까지)
비기능적 요구사항 확인
확장성 (Scalability): 예상되는 일일 활성 사용자(DAU)와 하루에 생성되는 게시물의 양은 어느 정도인가요? (예: DAU 10만 명, 일일 게시물 100만 개)
성능 (Performance): 사용자가 피드를 요청했을 때, 응답은 얼마나 빨라야 하나요? (예: 읽기 작업의 P99 지연 시간 1초 이내)
일관성 (Consistency): 새 게시물이 모든 사용자에게 즉시 보여야 하나요, 아니면 약간의 지연(최종 일관성)이 허용되나요? (예: 최대 몇 시간의 지연 허용)
가용성 (Availability): 시스템은 어느 정도의 안정성을 보장해야 하나요? (예: 쓰기 작업은 고가용성, 읽기는 상대적으로 덜 중요)
이러한 질문들을 통해 우리는 설계의 목표와 제약 조건을 명확히 설정할 수 있습니다.
2단계: 시스템의 뼈대 그리기 - 상위 수준 아키텍처
요구사항이 명확해졌다면, 이제 시스템의 전체적인 구조를 그려볼 차례입니다. 뉴스 피드 시스템은 크게 두 가지 흐름으로 나눌 수 있습니다.
(1) 게시물을 수집하고 저장하는 흐름과 (2) 사용자에게 피드를 제공하는 흐름입니다.
이 아키텍처의 핵심 구성 요소는 다음과 같습니다.
수집기 (Ingestor): 외부(사용자, 다른 서비스 등)로부터 새로운 게시물을 받아들이는 진입점입니다.
카프카 (Kafka) 큐: 수집된 게시물을 임시로 저장하는 버퍼 역할을 합니다. 예측 불가능한 트래픽 폭증에도 시스템이 안정적으로 게시물을 처리할 수 있게 해줍니다.
소비자 (Consumer) & HDFS: 카프카 큐의 게시물을 꺼내어 HDFS와 같은 영구 저장소에 보관합니다. 이는 모든 게시물을 보관하고 추후 분석에 활용하기 위함입니다.
ETL 작업: HDFS에 저장된 원본 데이터를 가공하여 사용자에게 제공할 피드를 생성하는 배치(Batch) 또는 스트리밍(Streaming) 작업입니다.
레디스 (Redis) 캐시: ETL 작업으로 미리 생성된 사용자별 피드를 저장하는 인메모리 저장소입니다. 빠른 읽기 속도를 보장합니다.
뉴스 피드 서비스 (API): 사용자의 요청을 받아 레디스에서 피드를 조회하여 반환하는 사용자 접점 API입니다.
3단계: 핵심 전략 - '사전에 피드 준비하기'
면접에서 합격과 불합격을 가르는 가장 중요한 포인트입니다. 사용자가 피드를 요청할 때마다 데이터베이스에서 모든 친구의 게시물을 가져와 정렬하는 방식은 사용자가 수십 명만 되어도 엄청나게 느려집니다. 수백만 사용자를 대상으로는 절대 불가능한 방식입니다.
따라서 우리는 '사전에 피드를 준비하는(Preparing Feeds in Advance)' 전략을 사용해야 합니다.
작동 방식
피드 생성: ETL 작업이 주기적으로 실행됩니다. 이 작업은 새로 추가된 게시물들을 확인하고, 각 활성 사용자에게 보여줄 피드를 미리 계산합니다.
피드 저장: 계산된 피드(사용자 ID와 해당 사용자에게 보여줄 게시물 ID 목록)를 레디스와 같은 빠른 조회용 캐시에 저장합니다.
피드 제공: 사용자가 앱을 켜면, 뉴스 피드 서비스는 복잡한 계산 없이 단순히 레디스에서 해당 사용자의 ID로 미리 준비된 게시물 ID 목록을 가져와 제공합니다.
이 방식의 가장 큰 문제는 사용자별 피드 목록({user ID, [post ID]})의 크기가 엄청나게 커질 수 있다는 점입니다. 책에서는 10억 명의 사용자를 가정할 경우 이 데이터가 800TB에 달할 수 있다고 계산합니다.
확장성 문제 해결: 사용자 ID 기반 샤딩(Sharding)
이 문제를 해결하기 위해, 사용자 피드 목록을 저장하는 데이터베이스를 사용자 ID를 기준으로 샤딩(Sharding)합니다. 즉, 사용자 ID를 해싱한 값을 기준으로 여러 데이터베이스 서버(샤드)에 데이터를 분산 저장하는 것입니다.
사용자가 피드를 요청하면, 시스템은 사용자 ID를 해싱하여 어떤 샤드에 데이터가 있는지 찾은 다음, 해당 샤드에서 게시물 ID 목록을 가져옵니다. 이후 모든 샤드에 복제되어 있는 게시물 콘텐츠 테이블에서 실제 내용을 조회하여 최종 피드를 완성합니다.
4. 추가 고려사항: 이미지와 미디어 처리
뉴스 피드에 이미지가 포함된다면 어떻게 해야 할까요? 텍스트와 이미지를 함께 처리하는 것은 비효율적입니다.
별도의 미디어 서비스와 CDN 도입: 이미지나 동영상 같은 미디어 파일은 별도의 미디어 서비스를 통해 업로드되고, CDN(콘텐츠 전송 네트워크)을 통해 사용자에게 제공되어야 합니다.
데이터 저장: 뉴스 피드 게시물 데이터에는 실제 이미지 파일이 아닌, CDN에 저장된 이미지의 URL만 포함합니다. 클라이언트는 이 URL을 받아 CDN에서 직접 이미지를 다운로드합니다.
결론: 성공적인 뉴스 피드 설계의 핵심
"인스타그램 같은 뉴스 피드를 설계해 보세요"라는 질문에 성공적으로 답변하기 위한 핵심은 다음과 같습니다.
요구사항 명확화: 성급한 설계 대신 질문을 통해 문제의 범위와 제약 조건을 정의합니다.
쓰기/읽기 경로 분리: 게시물 수집 경로와 피드 제공 경로를 분리하여 각 경로의 요구사항(고가용성 vs 낮은 지연 시간)에 맞게 최적화합니다.
비동기 처리: 카프카와 같은 메시지 큐를 활용하여 트래픽 폭증에 유연하게 대처합니다.
사전 피드 생성: 사용자 요청 시점이 아닌, 백그라운드에서 미리 피드를 계산하여 레디스 같은 빠른 저장소에 보관하는 것이 핵심 전략입니다.
샤딩: 대규모 사용자 데이터를 관리하기 위해 사용자 ID 기반의 샤딩 전략을 적용합니다.
이러한 체계적인 접근 방식은 당신이 단순히 기능을 나열하는 것을 넘어, 확장성과 성능이라는 시스템 설계의 근본적인 과제를 깊이 있게 이해하고 있음을 면접관에게 증명해 줄 것입니다.
시스템 설계 면접 인터뷰는 소프트웨어 엔지니어링 채용 과정에서 마주하게 될 가장 어려운 도전 중 하나이다. 《시스템 설계 면접 완벽 가이드》는 자신 있게 인터뷰를 성공적으로 이끌어 나가는 방법을 배울 수 있는 좋은 참고서입니. 쉽게 기억할 수 있는 인터뷰 기법들을 따라가며, 질문을 신속하게 평가하고 유리한 접근법을 파악한 후, 인터뷰어에게 명확하게 아이디어를 전달하는 방법을 배울 수 있습니다.