회고

[책 후기 | 완독] 가상 면접 사례로 배우는 대규모 시스템 설계 기초

sleesm 2023. 9. 5. 12:42

 

지난번에서 읽고 있다던 책에 대해 마무리 후기를 올려보겠다!!

 

이전 블로그 👉👉 2023.08.02 - [회고] - [책 후기] 가상 면접 사례로 배우는 대규모 시스템 설계 기초

 

[책 후기] 가상 면접 사례로 배우는 대규모 시스템 설계 기초

네이버 최종 결과가 나온 후 대규모 시스템 설계에 대해서 알아야겠다고 생각했다 2023.07.10 - [회고] - 2023 상반기 취준을 마무리하며,, 😂 2023 상반기 취준을 마무리하며,, 😂 벌써 2023 상반기 취

sleecode.tistory.com

 

 

 

 

 

일단 간단하게 읽은 소감부터 말하자면!

 

"읽은 후와 읽기 전의 세상이 완전히 다르다"

 

이전에는 소규모 프로젝트만 해왔기 때문에 몰랐던

분산 시스템의 자세한 내막에 대해서 알 수 있다

 

무엇보다 앞에서 배웠던 개념들이 뒤의 예제들과 함께 반복적으로 나오기 때문에

대략적으로 대규모 시스템들이 어떤 구성을 가지고 있을지

내가 습득한 지식들을 토대로 다음 주제에 대해 살을 붙이며 상상할 수 있다

 

 

 

 

 

 

 


 

 

책의 난이도는 그렇게 어렵지는 않은 것 같다

아마 cs 면접을 준비했던 사람들은 모두가 이해할 수 있을 것 같다

 

전체적으로 봤을 때 나에게 가장 생소한 개념은 '안정해시'였다

나머지 부분은 엄청나게 구체적으로 들어가는 것은 아니고

대략적인 구조와 시스템 흐름을 이해하면 되기 때문에 괜찮았지만

 

안정해시는 저번 글에서도 말한 것처럼 해시의 분산에 대해 이해하는 것부터 조금 어려웠다

N개의 캐시 서버를 균등하게 나누기 위해 사용하는 안정해시에는 해시공간을 해시링으로 구성하는 것이 중요하다

 

이 부분은 조금 어려우니 여러 번 반복해서 봐야 한다는 점!!

 

책을 읽으며 느낀 점은 캐시는 한 곳에서만 쓰이는 것이 아니라

DB를 사용할 때 빠른 사용성을 위해서 어디서든 사용된다고 느꼈다

숨 쉬듯이 기본적인 구조가 아닐까 생각한다 그러니 한 번에 이해하는 것이 좋을 것 같다

 

 

 

 

 

 


 

이후에는 어렵다기보다는 시스템을 만들 때 설계 범위를 어떻게 측정하는지

어떤 부분을 고려해야 하는지 시스템별로 생각해 볼 수  있었다

 

그리고 검색어 자동완성 시스템을 위해 트라이 자료구조를 사용하고,

웹크롤러 시스템에서 우선순위를 위해 큐를 사용한 것처럼,

시스템별로 특징에 맞춰서 자료구조가 조금씩 달라진다는 점에서

CS의 기본기가 중요하다는 것을 또 한 번 느꼈다

 

 

 

 

 


 

책을 읽으며 느낀 점은 캐시는 한 곳에서만 쓰이는 것이 아니라

DB를 사용할 때 빠른 사용성을 위해서 어디서든 사용된다고 느꼈다

숨 쉬듯이 기본적인 구조가 아닐까 생각한다

 

채팅 서비스를 구성할 때 채팅서버와 알림 서버 API 서버를 분리하여 사용한 것처럼

대부분의 시스템을 구성할 때 서버를 분할할 필요가 있음을 느꼈다

여기서 MSA 개념이 발생하게 된 건가? 하고 혼자 생각했다

 

 

 

 


 

마지막으로 가장 인상 깊었던 채팅 시스템 설계에 대해 소개하고 글을 마무리하고자 한다

 

아무래도 채팅 서비스를 몇 개 개발해서 그런지 가장 와닿았던 것 같다

 

 

 


채팅 서비스의 요구사항과 해결과정이 다음과 같다

  • 클라이언트로부터 메시지 수신 👈 웹소켓 사용
  • 메시지 수신자 결정 및 전달 👈 API 서버와 채팅 서버의 분리
  • 채팅 이력 저장 👈 키-값 저장소 사용
  • 수신자 접속 상태가 아닌 경우에는 접속할 때까지 해당 메시지 보관 👈 메시지 큐 사용

 

 

자세하게 살펴보자면,,

 

먼저 클라이언트와 서버가 통신을 하기 위해서는 프로토콜을 생각해야한다!

  • 클라이언트로부터 메시지 수신 👈 웹소켓 사용

 

기본적으로 웹에서는 HTTP를 사용하는데

HTTP는 클라이언트가 연결을 만드는 프로토콜로 단방향이고 무상태이기 때문에

2가지 기법이 추가적으로 필요하다 👉 폴링, 롱 폴링, 스트리밍(이건 책에 존재하지 않으므로 설명하지 않겠다)

 

 

폴링 : 클라이언트가 주기적으로 서버에게 물어보는 방법

  • 폴링을 자주 할수록(주기가 짧을수록) 폴링 비용이 증가한다
  • 답해줄 메시지가 없는 경우는 서버 자원이 불필요하게 낭비된다
  • 응답을 실시간으로 받지 않아도 되는 경우에 사용한다
  • 다수의 사용자가 동시에 사용하는 경우에 사용한다

출처 : https://ws-pace.tistory.com/104

 

 

 

롱폴링 : 폴링의 비효율적인 부분을 개선한 방법

  • 클라이언트는 새 메시지가 반환되거나 타임아웃될 때까지 연결을 유지한다
  • 클라이언트가 새 메시지를 받으면(서버로부터) 기존 연결 종료하고 새로 서버에게 요청을 보낸다
  • 이 절차를 반복하는 방법이다
  • HTTP 서버는 무상태이기 때문에 메시지 보내는 클라이언트와 수신하는 클라이언트가 같은 채팅 서버에 접속하게 되지 않을 수도 있다
  • 서버 입장에서 클라이언트가 연결을 해제했는지 알 수 없다
  • 메시지 많이 받지 않는 클라이언트도 타임아웃 때마다 주기적으로 서버에 다시 접속하므로 비효율적이다
  • 응답을 실시간으로 받아야 하는 경우에 사용한다
  • 적은 수의 사용자가 동시에 사용하는 경우에 사용한다

출처 : https://ws-pace.tistory.com/104

 

 

 

 

 

 

 

폴링과 롱 폴링을 보면 채팅 서비스에 완전히 적합하다고는 할 수 없다

그렇기 때문에 서버가 클라이언트에게 비동기 메시지를 보낼 때

가장 대중적으로 사용하는 웹소켓을 사용하기로 했다 (책에서 웹소켓을 사용)

 

 

웹소켓 : 클라이언트가 시작하지만 한번 맺어진 연결은 항구적이며 양방향인 프로토콜

  • HTTP 포트 80과 HTTPS 포트 443 위에서 동작한다
  • 처음에는 HTTP 연결이지만, 업그레이드 헤더를 통해 웹소켓 프로토콜로 변경된다
    • 방화벽이 있는 환경에서도 잘 동작하는 이유
  • 웹소켓 연결은 항구적이므로 서버 측에서 연결 관리를 효율적으로 해야 한다

출처 : https://code-lab1.tistory.com/300

 

 

 

 

 

 

 

 

 

 

그다음으로 생각한 부분은 서버의 분리다

  • 메시지 수신자 결정 및 전달 👈 API 서버와 채팅 서버의 분리

앞서 말한 것처럼 웹소켓 프로토콜을 사용하기로 했으니

서버 측에서는 연결 관리를 효율적으로 해야 한다

 

그런 의미로 채팅 의외의 API는 굳이 웹소켓을 쓸 필요가 없다는 것을 생각해야 한다

그렇기 때문에 채팅 기능을 제외한 나머지의 기능들은 (회원가입, 로그인 등)

일반적인 HTTP 상에서 사용하도록 서버를 분리하여 설계했다

 

 

책에 초반부터 가장 강조했던 것은 무상태 서비스다

그렇기 때문에 API 서버는 로드밸런서를 통해 관리될 것이다

 

추가적으로 로드밸런서로 통해 연결된 API 서버는
클라이언트에게 적합한 채팅 서버를 추천해 주는 서비스 탐색 기능이 필요할 것이다

 

 

 

 

 

 

 

그다음으로 가장 중요한 부분이기도 한

사용자들의 채팅 이력을 저장하는 공간이다!

  • 팅 이력 저장 👈 키-값 저장소 사용

 

채팅 이력을 저장하는 데는 키-값 저장소를 사용할 것인데

  • 수평적 규모 확장이 쉽다
  • 데이터 접근 지연시간이 낮다
    • join을 지양하는 형태니까

이와 같은 특징들을 가지고 있기 때문에 키-값 저장소를 채택했다

특히 RDB는 롱 테일에 해당하는 부분을 잘 처리하지 못하는 경향이 있기 때문에 키-값 저장소가 더 유리하다

 

실제로 페이스북 메신저나 디스코드도 키-값 저장소를 사용하고 있다고 한다

 

 

 

 

 

 

 

 

마지막으로 수신자의 상태에 따른 메시지 처리 과정이다

  • 수신자 접속 상태가 아닌 경우에는 접속할 때까지 해당 메시지 보관 👈 메시지 큐 사용

 

사용자 2명이 서로 메시지를 주고받는다고 생각하자

 

  1. 먼저 사용자1은 채팅 서버 1에 접속할 것이다
  2. 그리고 채팅 서버1에서 사용자가 메시지를 보내면
  3. 이를 메시지 동기화 큐에 넣는다

 

이때 사용자2가 접속 상태가 아니라면

  1. 메시지가 키-값 저장소로 이동하고
  2. 사용자2가 채팅서버에 접속하면 보내준다

 

만약 사용자2가 접속 상태라면

  1. 메시지 동기화 큐에서 사용자2가 접속 중인 채팅 서버2에 전달된다
  2. 채팅 서버2는 사용자2와 웹소켓으로 연결되어 있으므로 메시지를 받는다

 

 

 

 

 

 


 

 

이로써 채팅 시스템 설계에 대한 내용이 끝났다

물론 책에서는 좀 더 구체적이고 추가적으로 있는 내용들이 있다

그러니 한 번쯤 읽어보는 것을 추천한다

 

정말 막연하게 생각했던 개념들을 어디서 사용되는지 대략적으로 가늠할 수 있게 되니!

나도 아직 완전히 이해했다고는 생각하지 않기 때문에 시간이 될 때마다 틈틈히 다시 읽어보려고 한다!!

 

 

그럼 이제 글을 마무리하도록 하겠다!!!

 

 

 

 

 

p.s. 만약 틀린 부분이 있다면 댓글로 알려주세요:)

 


참고 자료

https://code-lab1.tistory.com/300

 

[Web] 웹소켓(WebSocket)이란? 웹소켓과 HTTP의 차이

웹소켓(WebSocket) 프로토콜이란? 웹소켓(WebSocket)은 클라이언트와 서버(브라우저와 서버)를 연결하고 실시간으로 통신이 가능하도록 하는 첨단 통신 프로토콜이다. 웹소켓은 하나의 TCP 접속에 전

code-lab1.tistory.com

https://junhyunny.github.io/information/spring-boot/polling-long-polling-and-spring-example/

 

폴링(Polling), 롱 폴링(Long polling) 그리고 스프링 예제

<br /><br />

junhyunny.github.io

https://pearlluck.tistory.com/335

 

Http통신 vs Socket통신 (WebSocket)

네트워크를 통해 서버로 데이터를 가져오기 위한 통신방법 http통신, socket통신 1.Http 통신 Client의 요청이 있을때만, 서버가 응답해서 정보를 전송하고, 곧바로 연결을 끊는 방식 즉, Client가 요청

pearlluck.tistory.com

https://ws-pace.tistory.com/104

 

HTTP vs. WebSocket 정리

HTTP 기본적으로 HTTP Protocol은 비연결성의 특징을 갖고 있으므로 실시간 통신을 하기에 적합하지 않은데, 이를 구현하는 방식 3가지를 알아보자 HTTP의 실시간 통신 방식 Polling Long Polling Streaming poil

ws-pace.tistory.com

https://doqtqu.tistory.com/347

 

[양방향 통신 방법] Polling vs WebSocket

기존의 양방향 통신 방법 HTML5 표준 기술인 웹소켓 방식 이전에는 마치 실시간인 것처럼 작동하게 하는 방법들이 있었다. Polling(폴링) 클라이언트가 n초 간격으로 request를 서버로 계속 날려서 resp

doqtqu.tistory.com