STUDY/책

1장. 사용자 수에 따른 규모 확장성 - 가상 면접 사례로 배우는 대규모 시스템 설계 기초

디리릭 2024. 7. 30. 01:22
728x90

 
 
 

 

 

사용자가 많지 않은 경우에는 단일 서버로 운영할 수 있지만, 사용자가 많아지면 서버에 부하가 쉽게 가므로 위와 같은 시스템으로 설계해야한다. 

 

각각의 컴포넌트가 어떤 역할을 하는지 어떤 흐름도를 갖는지 정리하고자 한다. 

 

클라이언트(웹이나 모바일)에서 API url을 통해 API를 호출한다. 이때, 가장 먼저 CDN을 통해 API url을 로드 벨랜서 ip로 바꿔 호출해 준다.

 

로드 밸랜서는 서버의 부하를 분산 시키는 역할을 한다. 위에서 말한 단일 서버의 경우, 로드 밸랜서를 쓸 필요가 없다. 왜냐면 서버가 한개인데, 분산 시켜봤자 갈 곳은 한 곳 뿐이니까.

로드 밸랜서가 각 서버와 private IP로 통신한다. 이런 면에서는 로드밸런서가 proxy 역할을 하는 것 같다. 

 

로드 밸런서가 task를 분산 시켜줌에도 사용자가 많을 경우, 서버를 확장해야할 때가 있다.

서버를 확장 하는 방법은 크게 2가지이다. 수직적 확장수평적 확장이 있다.

  • 수직적 확장(scale up) : 서버에 고사양 자원으로 추가
  • 수평적 확장(scale out): 동일한 서버의 수를 증가

일시적으로 사용자가 몰려 서버 확장이 필요하다면 수평적 확장을 하는 것이 낫다. 서버 자원 부족으로 task를 정상적으로 처리하지 못하는 상황이라면 수직적 확장을 선택하면 될 것 이다.

수평적 확장을 위해서 상태 정보(사용자 세션 데이터 등)를 웹 계층에서 제거해야 한다. 이런 웹 계층을 '무상태 웹 계층'이라 한다. 상태 정보를 분리하지 않는다면 유효한 사용자임을 인증 받은 서버에만 요청을 보내야한다. 그렇다면 로드밸런서의 역할이 무의미하지 않을까? 그러므로 상태 정보를 분리하여 유연하게 수평적 확장을 할 수 있다. 

 

이제 서버에서 API 호출 요청을 처리하기 위해서 DB에 접근해 쿼리를 날릴 것이다. 이 때, master DB와 slave DB를 둬 데이터 베이스 다중화를 한다면, 보다 안정적이게 쿼리를 처리 할 수 있다. 

주로 master DB에는 쓰기 연산 (insert, update), slave DB에서는 읽기 연산(select)을 처리한다. 

insert나 update문을 질의 할 때, transaction을 걸 수 있는데, 이때 master DB에 읽기 연산을 요청 했을 때, 응답 지연이 일어날 수 있다. slave DB 두어 읽기 연산을 요청하면 응답 지연을 최소한 할 수 있다. 

 

서비스를 운영하다보면 자주 호출하는 API가 있다. 이때, 매번 API 호출 할 때마다 DB에 쿼리 요청을 하게 된다면 (데이터 다중화를 했더라도) DB에 부하를 줄 수 있다. 이 때 캐시를 사용하여 DB 부하를 줄일 수 있다. 

캐시는 key&value 형태로 저장하고 value에는 API 응답 값 또는 DB질의 결과 값을 저장한다. 그래서 캐시 key를 통해 value를 얻어 클라이언트에 전달한다.

어느 API를 호출 했을 때, 캐시에 해당 API 응답값이 저장 된 키가 있는지 확인 한다. 
key가 있다면, 캐시에 저장 된 value를 반환하고 key가 없다면 DB에 질의하여 응답값을 얻는다. 

 

 

 

 

 

 

728x90