본문 바로가기

개발공부/원티드 챌린지 정리

7월 백엔드 챌린지 4. 예제 적용

728x90

1. 알림 시스템 설계

1.1 개요

알림 시스템은 많은 서비스에서 최신 뉴스, 제품 업데이트, 이벤트 등 비즈니스적으로 중요한 내용을 비동기로 제공한다. 모바일 푸시, SMS, 그리고 이메일로 분류할 수 있다

 

1.2 기본 설계

1) IOS

- 알림 제공자 : 알림 요청을 만들어 애플 푸시 알림 서비스로 보내는 주체. 알림 요청을 보내려면 device token, payload 데이터가 필요하다

- 알림 서비스(APNS) : 애플에서 제공하는 원격 서비스. 푸시 알림을 IOS 장치로 보내는 역할을 담당한다

2) AOS : APNS 대신 FCM을 사용한다(기본 설계는 같다)

3) 이메일, SMS 역시 동일

 

4) 연락처 정보 수집 절차

- 알림을 보내려면 모바일 단말 토큰, 전화번호, 이메일 주소 등의 정보가 필요

- 앱을 설치한 후 계정 가입 시 사용자 정보를 DB에 저장

 

5) 설계 2차

5-1) N개의 서비스 : 각각 마이크로서비스, 크론잡, 분산 시스템 컴포넌트일 수 있다

5-2) 알림 시스템 : 시스템은 서비스 1번부터 N번까지 알림 전송을 위한 API를 제공해야 하고, 제 3자 서비스에 전달할 알림 페이로드를 만들어 낼 수 있어야 한다

5-3) 제 3자 제공 서비스 : 사용자에게 실제로 알림을 전달하는 역할. 확장성이 중요하다. 쉽게 새로운 서비스를 통합하거나 기존 서비스를 제거할 수 있어야 한다

 

* 발생가능한 문제

1. SPOF : 알림 서비스의 서버가 하나밖에 없어, 그 서버의 장애 발생 시 전체 서비스 장애로 이어진다

2. 규모 확장성 : 푸시 알림에 관계된 모든 것을 한 대의 서버에서 처리하기 때문에 추후 확장이 어렵다

 

6) 최종 설계

- 데이터베이스와 캐시를 알림 시스템의 주 서버에서 분리한다

- 알림 서버를 증설하고 자동으로 수평 규모 확장이 가능하도록 한다

- 메시지 큐를 이용한 시스템 컴포넌트 사이 강한 결합을 끊는다

2. 구글 드라이브 설계

2.1) 요구사항

- 파일 추가

- 파일 다운로드

- 여러 단말에 파일 동기화

- 파일 갱신 이력 조회

- 파일 공유

- 파일 편집 & 삭제 알림 표시

 

2.2) 구현 API

(1) 파일 업로드 API

- 단순 업로드 : 파일 크기가 작을 때 사용

- 이어 올리기 : 파일 크기가 크거나 네트워크 단절이 생길 경우 사용한다

(2) 파일 다운로드 API

ex) POST https://api.example.com/files/download --data '{"path" : "/recipes/soup/best_soup.txt"}'

 

2.3) 한 대 서버 제약 극복

파일시스템의 여유 공간이 없다면 ~ 데이터를 샤딩하여 여러 서버에 나눠 저장할 수 있다

여유 공간이 없을 때마다 매번 샤딩을 하는 것은 번거롭다. ~ 알려진 서비스를 사용 : AWS S3

 

2.4) 고민 포인트

(1) 로드 밸런서

- 네트워크 트래픽을 분산하기 위해 사용

- 로드 밸런서는 트래픽을 고르게 분산할 뿐 아니라 장애가 발생하면 자동으로 해당 서버를 우회한다

(2) 웹 서버

- 로드 밸런서를 추가하고 나면 더 많은 웹 서버를 쉽게 추가할 수 있어 트래픽이 증가해도 쉽게 대응이 가능하다

(3) 메타 데이터 데이터베이스

- 데이터베이스 파일 저장 서버에서 분리해 SPOF를 회피

- 사용자 이름, 파일 이름, 업로드 날짜

(4) 파일 저장소

- S3 파일 저장소로 사용하고 가용성과 데이터 손실을 막기 위해 두 개 이상의 지역에 데이터를 다중화

 

2.5) 동기화 충돌

~ 두 명 이상의 사용자가 같은 파일이나 폴더를 동시에 업데이트할 경우

-> 버전으로 해결

-> 먼저 처리되는 변경은 성공한 것으로 보고, 나중에 처리되는 변경은 충돌이 발생한 것으로 표시 ~ 두 가지 버전을 합칠 지 대체할 지 결정

 

2.5) 설계

(1) 사용자 단말 : 웹 브라우저 등

(2) 블록 저장소 서버

- 파일 블록을 클라우드 저장소에 업로드하는 서버, 클라우드 환경에서 데이터 파일을 저장하는 기술

- 이 저장소는 파일을 여러 개의 블록으로 나눠 저장하며 각 블록에는 고유한 해시값이 할당

- 고유한 해시값은 메타데이터 DB에 저장

- 각 블록은 독립 객체로 취급되며, S3에 보관된다

- 파일을 재구성하려면 블록들은 원래 순서대로 합쳐야 한다

(3) 클라우드 저장소

- 파일은 블록 단위로 나눠져 S3에 보관된다

(4) 아카이빙 저장소

- 비활성 데이터를 저장하기 위한 시스템

(5) 로드 밸런서

- 요청을 모든 API 서버에 고르게 분산

(6) API 서버

- 사용자 인증, 사용자 프로파일 관리, 파일 메타데이터 갱신 등

(7) 메타데이터 DB

- 사용자, 파일, 블록, 버전 등의 메타데이터 정보를 관리

- 실제 파일은 클라우드에 보관, 해당 DB는 메타데이터만 저장

(8) 메타데이터 캐시

- 성능을 높히기 위해 자주 쓰이는 메타데이터는 캐시한다

(9) 알림 서비스

- 특정 이벤트가 발생했음을 클라이언트에게 알리는데 쓰이는 시스템

- 예를 들어 클라이언트에게 파일이 추가되거나, 편집 삭제되었음을 알림

(10) 오프라인 사용자 백업 큐

- 클라이언트가 접속 중이 아니라서 파일의 최신 상태를 확인할 수 없을 때, 해당 정보를 이 큐에 둬 나중에 클라이언트가 접속했을 때 동기화될 수 있도록 한다

 

2.6) 블록 저장소 서버

정기적으로 갱신되는 큰 파일들은 업데이트가 일어날 때마다 전체 파일을 서버로 보내면 네트워크 대역폭을 많이 잡아먹는다. 이를 최적화하는 방법

- 델타 동기화 : 파일이 수정되면 전체 파일 대신 수정이 일어난 블록만 동기화한다

- 압축 : 블록 단위로 압축해 데이터 사이즈를 줄인다

델타 동기화는 그림처럼 갱신된 부분만 S3에 업로드하면 된다

2.7 알림 서비스

(1) 알림 서비스

- 이벤트 데이터를 클라이언트들로 보내는 서비스

- 알림 서비스 구현으로 롱 폴링, 웹 소켓 방식을 채택할 수 있다

(2) 롱 폴링

- 드롭박스

- 각 클라이언트는 알림 서버와 롱 폴링용 연결을 유지

- 특정 파일에 대한 변경 감지 -> Connection 끊음

- 이 때 클라이언트는 반드시 메타데이터 서버와 연결해 파일의 최신 내역을 다운로드한다

- 다운로드 작업이 끝나거나 timeout이 되면 새 요청을 보내 롱 폴링 연결을 복원 및 유지

(3) 웹 소켓

- 클라이언트 <-> 서버, 클라이언트 간 지속 통신 채널 제공

 

2.8) 저장소 공간 절약

(1) 중복 제거

- 두 블록이 같은 블록인지 해시 값을 비교해 판단한다

- 예시) MD5와 같은 해시 함수 사용해 해시 값 비교

(2) 지능적 백업 전략 도입

- 파일 버전 개수에 상한을 둔다 -> 상한에 도달하면 제일 오래된 버전은 버린다

- 중요한 버전만 보관한다 -> 자주 수정되는 파일은 불필요한 버전을 많이 생성한다

(3) 자주 쓰이지 않는 데이터는 아카이빙 저장소로 옮긴다

- S3 글래시어 같은 아카이빙 저장소 사용

728x90