시스템 설계 면접의 취지:
- 한 사람이 복잡한 시스템 (e.g 구글의 검색엔진) 과 같은 걸 한번에 설계하는 걸 기대하는게 아님.
- 모호한 설계 질문에 대해 명확히 경계를 설정해서 디자인하는 걸 목표로 함.
- 설계에서 내린 결정들에 대해 방어 능력을 보이는 자리이기도 함.
- 면접에서 보고자하는 면은 설계에 대한 기술적인 능력, 협력에 적합한 사람인지, 압박이 심한 상황에서도 잘 헤쳐나갈 수 있는지, 모호한 문제를 건설적으로 해결하는 능력이 있는지, 자신의 결정에 대해 충분한 이유를 설명할 수 있는지 를 보는 것.
- 안좋은 시그널은 다음과 같다. 트레이드 오프를 계산하지 않는 것 (세상에는 정답만 있지 않고, 타협도 해야하는 경우가 있음), 과도한 오버 엔지니어링을 하는 것, 완고하고, 편협한 것
- (실제로 다양한 설계를 해보는 경험이 중요하고, 명확히 범위를 산정하는 것, X 일 때 Y1, Y2, Y3 같은 선택지가 있고, 각각의 트레이드 오프에 대해 명확히 정리되어 있어야할듯.)
효과적인 면접을 위한 팁:
1단계: 문제 이해 및 설계 범위 선정
곧바로 정답을 내는 것만큼 무지한 행위를 하면 안됨.
질문을 통해 요구사항과 가정을 분명히하라.
면접관이 답변을 해주는 경우도 있지만, 스스로 가정을 하는 경우도 생긴다. 가정을 할 경우에는 노트를 해라. 까먹으면 안됨.
꼭 해야하는 필수 질문에 대해서도 생각해보자.
(제한사항과 요구사항은 노트에 적어라)
그리고 가정이 바뀌면 어떻게 설계가 바뀔지도 생각해보자.
- 구체적으로 할만한 질문은 다음과 같다:
- 구체적으로 어떤 기능을 만들어야하는가?
- 제품 사용자 수는 얼마나 될까?
- 회사의 규모가 얼마나 빨리 커지리라 예상되는가? (이 질문의 목적은 확장성 고려임. 초기부터 확장성을 고려해야하는지, 초기에는 고려하지 않아도 되는지)
- 회사가 주로 사용하는 기술 스택은 무엇인가? (진짜 회사 입장에서 생각해보는 것이네)
- 설계를 단순화하기 위해 활용할 수 있는 기존 서비스로는 어떤 거슬이 있는가?
뉴스 피드 (news feed) 시스템 설계 예제를 통해 해야하는 질문을 배워보자:
- 지원자: 모바일 앱과 웹 앱 가운데 어느 쪽을 지원해야하나요? 아니면 둘 다 일까요?
- 모바일 앱 환경과 웹 앱 환경의 차이는 다음과 같다:
- 화면 크기로 인한 UX 차이, 제한된 데이터 사용량 (요금제 때문) 데이터 대역폭 (셀룰러 네트워크는 와이파이보다 제한적임), 네트워크 신뢰도 문제 (지하철과 같은 환경에서는 신호가 약해질 수 있음), 배터리 문제와 전력 문제가 있어서 데이터 사용을 효율적으로 해야함.
- 데이터 대역폭과 네트워크 신뢰도 문제로 모바일 앱은 이미지, 비디오 멀티 미디어 콘텐츠들은 더 작은 사이즈를 이용해야함. 아니면 콘텐츠를 압축해서 전송하거나, 더 적은 데이터를 보내주거나.
- 그리고 모바일에서는 대역폭이 낮아서 다시 다운로드 하는데 시간이 많이 걸리므로, 캐싱을 적극적으로 이용해서 데이터에 빠른 접근을 하도록 해줘야함.
- 모바일 앱 환경과 웹 앱 환경의 차이는 다음과 같다:
- 면접관: 둘 다 지원해야한다.
- 지원자: 가장 중요한 기능은 무엇일까요?
- 핵심 요구사항을 파악하기 위해서임. 이를 통해서 집중해야할 기능을 파악해보는 것.
- 비기능적인 요구사항의 중요성도 파악해야함. 빠른 피드 로딩이 중요한건지, 실시간 업데이트가 중요한건지,
- 면접관 새로운 포스트(Post) 를 올리고, 다른 친구의 뉴스 피드를 볼 수 있도록 하는 기능이다.
- 기본적으로 Perforamnce (응답 시간과 처리량), 확장성, 가용성, 일관성, 보안과 유지보수성 등은 중요하다.
- 여기서는 좀 더 구체적으로 말하면 다음과 같을 것:
- 저지연 응답 시간 (Low Latency):
- 사용자가 포스트를 작성하고 난 이후, 해당 포스트가 완료되는 시간
- 포스트가 친구들한테까지 나타나는 시간
- Edge 서버나 CDN 활용이 중요, 자주 사용되는 컨텐츠 캐싱, 실시간 스트리밍 처리가 필요
- 높은 동시성 처리 능력:
- 수천, 수만명이 있더라도 이것들을 처리할 수 있어야함.
- 포스트 작성 시 동시성 문제를 해결하기 위해, 데이터베이스 업데이트를 비동기로 처리
- 메시지 큐를 활용해서 확장성을 늘리기
- 네트워크 효율성:
- 포스트나 피드 데이터를 전송할 때, JSON 대신 Protocol Buffers와 같은 더 가벼운 데이터 형식을 사용
- 대량의 텍스트나 이미지 데이터를 전송할 때 Gzip과 같은 압축 방식을 적용해 전송 속도를 향상시키기
- 데이터베이스 성능 최적화:
- 포스트와 피드 데이터를 효율적으로 검색하고 조회하기 위해 데이터베이스의 인덱스를 최적화하고, 쿼리를 정교하게 설계
- 데이터 파티셔닝을 실시해 쿼리 성능을 향상
- 저지연 응답 시간 (Low Latency):
- 지원자: 이 뉴스 피드는 시간 역순으로 정렬되어 있나요? 아니면 다른 특별한 정렬 기준이 있는가? 제가 특별한 기준이 있느냐라고 물어본 이유는 피드에 올라간 포스트마다 다른 가중치가 부여되어야 하는지 알고 싶어서. 가령 가까운 친구의 포스트가 사용자 그룹 (user-group) 에 올라가는 포스트보다 더 중요하다거나
- (집짜 아는만큼 질문이 달라진다. 나는 기본적으로 당연히 시간순이라 생각. 이런것도 이 서비스를 알면 이 기능에 고려해야하는 부분이 있구나)
- 기능 명확하를 위해서 질문하는ㄷ 듯.
- 면접자: 문제를 단순화하기 위해서 일단 시간 역순으로 정렬된다고 가정하자.
- 지원자: 한 사용자는 최대 몇 명의 사용자와 친구를 맺을 수 있나요?
- 면접자: 5000명입니다.
- 지원자: 사이트로 오는 트래픽 규모는 어느정도인가요?
- 면접자: DAU (일간 사용자수는 천만명)
- 지원자: 피드에 이미지나 비디오도 올라올 수 있나요? 아니면 포스트는 그저 텍스트인가요?
- 면접자: 이미지나 비디오 같은 미디어 파일도 포스트할수 있어야한다.
예상되는 트래픽에 맞게 대비해야하는 수준 정리:
- 동시 사용자 100명:
- 서버 인프라: 단일 애플리케이션 서버와 단일 데이터베이스 서버로 충분
- 성능 최적화: 기본적인 캐싱 전략(예: Redis)과 간단한 로드 밸런서 사용을 고려
- 동시 사용자 1,000명:
- 서버 인프라: 두세 대의 애플리케이션 서버와 한두 대의 데이터베이스 서버(주/복제)를 사용하며, 로드 밸런서를 통해 트래픽을 분산
- 성능 최적화: HTTP 캐싱, 정적 자산(이미지, CSS, JS) 최적화, CDN(Content Delivery Network)을 도입
- HTTP 캐싱은 브라우저 캐싱 (Browser Caching)을 말함. HTTP 헤더에서 Cache-Control 및 Expires 헤더를 설정하여, 브라우저가 자원을 일정 기간 동안 캐싱하도록
- Nginx, Varnish와 같은 역방향 프록시 서버를 사용해, 동적 콘텐츠나 정적 콘텐츠를 캐싱도 가능함.
- API 응답도 캐시가 가능.
- 데이터베이스: 기본적인 읽기/쓰기 분리를 고려해 데이터베이스 성능을 최적화
- 서버 인프라: 두세 대의 애플리케이션 서버와 한두 대의 데이터베이스 서버(주/복제)를 사용하며, 로드 밸런서를 통해 트래픽을 분산
- 동시 사용자 10,000명:
- 서버 인프라: 여러 대의 애플리케이션 서버와 분산된 데이터베이스 클러스터가 필요, 로드 밸런서 및 오토스케일링을 설정해 트래픽 급증에 대비
- Redis나 Memcached와 같은 메모리 캐싱을 적극 활용하고, 비동기 작업 처리를 위한 메시지 큐(Kafka, RabbitMQ 등)를 도입
- 데이터베이스: 데이터 파티셔닝, 복제본 증가
- 동시 사용자 100,000명:
- 서버 인프라: 수십 대의 애플리케이션 서버와 분산된 데이터베이스 및 캐시 서버 클러스터가 필요
- 완전한 CDN 배포와 더불어, 고성능 인프라(AWS EC2, Azure 등)의 고사양 인스턴스를 사용
- 데이터 전송을 위한 압축 기술과 지연 시간 감소 기술(예: HTTP/2, gRPC)을 도입
- 데이터베이스: 고가용성을 위해 지리적 분산 데이터베이스 시스템을 사용
- 동시 사요자 1,000,000명:
- 서버 인프라: 수백 대의 서버를 사용하는 대규모 분산 시스템으로, 클라우드 기반의 글로벌 로드 밸런싱과 오토스케일링이 필수
- 글로벌 로드 밸런서는 전 세계에 분산된 여러 서버 간에 트래픽을 효율적으로 분배하여 사용자에게 가장 가까운 서버에서 응답을 제공하고, 전체 시스템의 안정성과 성능을 보장하는 역할을 함.
- 주로 애니캐스트 DNS (Anycast DNS) 방법을 사용해서 라우팅을 하기도 함. 애니캐스트 DNS는 사용자의 DNS 요청을 가장 가까운 위치에 있는 DNS 서버로 라우팅하여, 사용자가 연결할 최적의 서버를 선택해줌.
- 모든 계층에서 캐싱 전략을 강화
- 데이터 동기화를 위한 고성능 메시지 브로커 사용
- 데이터베이스 샤딩과 함께 글로벌 분산 데이터베이스를 운영. 데이터 일관성을 유지하기 위한 고도화된 트랜잭션 관리 시스템을 사용.
- Google Cloud Spanner는 글로벌 분산 데이터베이스 시스템이면서도, 강한 일관성(Strong Consistency)을 보장하는 트랜잭션 관리 시스템을 제공함.
- 서버 인프라: 수백 대의 서버를 사용하는 대규모 분산 시스템으로, 클라우드 기반의 글로벌 로드 밸런싱과 오토스케일링이 필수
- 동시 사용자 10,000,000명:
- 서버 인프라: 수천 대의 서버와 전 세계적으로 분산된 데이터센터가 필요
- 성능 최적화: 모든 트래픽을 분산시키기 위해 Anycast DNS 및 글로벌 트래픽 매니지먼트를 사용
- 사용자 근처에서 데이터를 처리하는 엣지 서버를 통해 레이턴시를 최소화
- 완전한 글로벌 분산 데이터베이스와 고성능 NoSQL 데이터베이스(예: Cassandra, DynamoDB) 사용
예상되는 트래픽에 맞게 대비해야하는 수준 요약:
- 대부분의 경우 서버와 데이터베이스 인스턴스 수 증가 + 데이터베이스 성능 최적화 + 데이터베이스 파티셔닝 + 캐싱 계층 강화 + gRPC 와 같은 대역폭 효율화 등으로 감당이 됨.
- 어느 시점부터 RDBMS 를 파티셔닝 해서 사용하는 것보다 분산 NoSQL 을 써야하는 시점이 옴.
- 글로벌 로드밸런서아 Anycast DNS 라우팅 방법으로 사용자와 지리적으로 가까운 서버에서 처리하도록 해야함.
- Edge Server 를 이용해서 정적 자원 뿐 아니라, 자주 사용되는 API 들 까지도 캐시 할 수 있음, 인증 까지도 엣지 서버에서 가능, 서버리스를 써서 특정 요청만 처리하는 방법도 가능함.
2단계 개략적인 설계안 제시 및 동의 구하기
대략적인 설계안을 제시하고, 면접관의 동의를 얻는게 중요함.
화이트보드나 종이에 핵심 컴포넌트를 포함하는 다이어그램을 올리는 것.
여기서 시스템 규모와 관계된 제약사항들을 만족시키는지 확인해봐야한다. (제약사항들은 따로 메모를 해야하네)
이 단계에서 API 엔드포인트나 데이터베이스 스키마와 같은 것은 보이지 않아도 되지만 면접관마다 다를 수 있음.
뉴스 피드 시스템 예시에서의 개략적인 설명:
- 두 가지 처리 Flow 로 구성해볼 수 있다.
- 피드 발생: 사용자가 포스트를 올리면 관련된 데이터가 캐시나 데이터베이스에 기록되고 사용자의 친구 뉴스 피드에 뜨게 되는 것.
- 피드 생성: 해당 친구들이 올린 포스트를 가지고 정렬해서 피드를 만드는 것.
3단계 상세 설계
면접관마다 집중하는 부분이 다르긴 할 것.
그러나 대부분의 면접관들은 시스템의 컴포넌트에서 깊이있게 보는 걸 원할 것.
채팅 시스템이라면 어떻게 Latency 를 줄여보도록 할건지, 사용자의 온/오프라인 상태를 표시할 것인지 듣고자 할 것.
면접에서 해야할 것
질문을 통해 혹인하는 것. (스스로 내린 가정이 옳다고 생각하지 말기)
문제의 요구사항을 이해하는 것
정답은 없다는 걸 아는 것.
면접관이 사고 흐름을 이해할 수 있도록 하는 것
가능하면 여러 해법을 제시하는 것
개략적인 설계에 동의하면 세부사항 설계를 시작하는 것
면접관의 아이디어를 이끌어내는 것
포기하지 말 것
하면 안되는 것
전형적인 문제에도 대비되지 않은채로 가지 않기
요구사항이나 가정들이 분명하지 않은 상황에서 설계를 제시하지 않기
처음부터 특정 컴포넌트의 세부사항을 너무 깊이 설명하지 말 것.
진행 중에 막혔다면 힌트를 청하기를 주저하지 마라.
소통을 주저하지 마라.
설계안을 내놓는 순간 면접이 끝났다고 생각하지마라.
'System Design > General' 카테고리의 다른 글
Consistent Hashing 설계 (0) | 2024.09.22 |
---|---|
Rate Limiter 설계 (0) | 2024.09.19 |
Cache 잘 쓰는 방법 정리 (0) | 2024.06.16 |
7 Must-know Strategies to Scale Your Database (0) | 2024.06.16 |
(1) Apache Flink 논문 리뷰 - 컴퓨터 세계를 완전히 변화시킨 25개의 논문 (0) | 2024.05.20 |