티스토리 뷰

 

주변에서 이 책을 여러번 추천 받았었다.

 

원래 읽고 있던 오브젝트는 생각보다 뒤로 갈수록 흥미가 떨어져서 재미가 없었는데,

 

이 책은 소개에 적힌대로 인프라 설계를 한눈에 볼 수 있도록 도해(그림)로 정리가 잘되어서 이해하기 쉬웠다.

 

읽다보면 안전 해시 함수나 블룸 필터, 캐시 같은 치트키를 계속 쓰는 것 같다는 느낌을 받지만,

 

그래도 생각하기 힘든 부분을 매 설계마다 짚어줘서 오.... 하고 넘어갈 내용이 꾸준히 등장해서 흥미로웠다.

 

그리고 AWS에서 관리해주는 부분들과 고가용성을 보장해주는 것에 대한 의미를 되새겨볼 수 있었다.

 

뒤로갈수록 재밌는 사례가 많아서 읽는데도 속도가 붙어서 이틀만에 다 읽을 수 있었다.

 

그리고, 기억력이 나쁜 내가 꼭 기억해둬야할 만한 것들이 있어서 정리해보려고 한다.

 

파랑색으로 강조된 내용은, 책의 내용이 아닌 내가 생각하는 코멘트다.


1장. 사용자 수에 따른 규모 확장성

사용자 수가 적을 때, 일반적으로 만들어지는 아키텍처에 대한 소개와

 

사용자 수가 늘어감에 필요한 인프라 의사선택들이 소개된다. 

 

DB, 메시지큐, CDN, 데이터 분리, 자동화와 같이 곧 맞이할 이슈들을 대략적으로 소개해 준다.

 

2장. 개략적인 규모 추정

시스템 요구 사항이나 성능 요구사항을 추정하는 방법에 대해서 알려줬는데, 나한테는 조금 어려운 내용이었다.

 

3장. 시스템 설계 면접 공략법

시스템의 구조를 설계하는 면접에서는 100% 완벽한 설계를 요구하진 않지만, 설계 그 이상을 본다.

 

오버엔지니어링을 주의하고 완고함, 편협함을 경계할 것.

 

효과적인 면접을 위한 4단계 접근법에 대해 정리해줌

 

요약하면, 절대 본인이 맞다는 확신을 하지 말 것. 요구 사항을 확실히 분석할 것. 면접관과 티키타카 할 수 있도록 의견이나 제한사항들에 대해 자주 물어보면서 진행할 것. 등이 있다.

 

4장. 처리율 제한 장치의 설계

어느 서비스에나 처리할 수 있는 한계가 있기 때문에 처리율 제한을 해야 한다.

- dos 공격 방어, 비용 절감, 서버 자원 고갈을 막을 수 있음

 

몇 가지 알고리즘 소개한다. 총 5가지 알고리즘이었고 한곳에서 자원을 공유해서 처리하거나 시간을 기준으로 제한을 두는 방법들이었다.

 

그리고, redis를 이용한 설계를 소개한다.

 

그러나 규모가 커지면 처리율 제한 장치가 여러 곳에 위치하게 되는데, 그럴 경우 경쟁조건과 동기화 문제가 발생한다.

 

경쟁 조건 : Redis의 Sorted set, 루아 스크립트로 처리

동기화 : 중앙화해서 처리

 

현재 서버 개발자인 내 입장에서 생각해보면, API 처리율 제한 장치는 로드밸런서 앞에 위치해야 한다. 오토 스케일링 된 서버 각각에서 막는건 큰 의미가 있을까 싶다. 

 

문제는 그래도 서버자원고갈이 되는 경우가 있을 것 같다. 우연찮게 펜딩이 길게 걸리는 API가 하나의 서버에 쏠리는 경우가 있을텐데 이런건 어떻게 처리할 수 있을지 잘 모르겠다.

 

그래서 모니터링/알람 기능이 중요하지 싶다. 

 

AWS에서는 이 역할을 WAF에서 처리할 수 있다.(근데 비쌈)


5장. 안정 해시 설계

수평적 구조를 만들기 위해서 균등한 요청 배분은 필수적이다. 서버는 늘어났다 줄어들었다 할텐데, 어떤 방식으로 균등하게 요청을 나눠줄 수 있을까에 대한 처리 방법이 안정 해시 알고리즘이다.

 

그림으로 설명하면, 해시를 원처럼 만들고 중간 중간 서버를 두고 가까운 곳에서 처리할 수 있도록 하는 방식이다.

 

그런데, 안정 해시 알고리즘만으로는 요청/데이터의 균등 분배를 할 수 없기 때문(핫스팟 키)에 가상 노드를 이용해 서버가 위치할 곳을 미리 지정해 놓는다.

 

가상 노드는 하나의 서버를 분리해 여러 구간에 배치하는 방식으로 가상 노드의 개수를 늘리면 점점 키의 분포를 균등하게 가져갈 수 있다.

 

가상 노드까지 추가된 안정 해시

 

문득 AWS는 어떤 방식의 로드밸런싱을 하고 있는지 궁금해졌는데, 생각보다 쉽게 알 수 있었다.

 

EC2 > 로드 밸런싱 > 타겟 그룹 > 그룹 이름을 선택 > 그룹 세부 정보 > 속성 > 편집 > 속성 편집 > 로드 밸런싱 알고리즘

 

 

디폴트가 라운드로빈 방식인 것 같은데, 내부적으로는 더 복잡한 방식을 쓰지 않을까 싶다.

 

6장. 키-값 저장소 설계

Redis, Memcached, AWS DynamoDB를 지칭하는 키-값 저장소. 값으로 뭐가 오든 상관하지 않는다.

 

분산해시테이블이라고도 불리고, CAP라고 하는 일관성, 가용성, 파티션 감내 중 최대 2가지를 지원(모두 지원하는건 불가능)해야 한다.

 

대용량의 데이터를 저장하기 위해서 분산 처리는 필수. 어떻게 분산 처리할 것인가는 안정 해시 알고리즘이 또 등장함

 

안정적인 고가용성을 확보하기 위해서는 데이터는 비동기 다중화를 해야한다.

 

그래서 다중화된 데이터는 적절한 동기화 과정이 필요한데 정족수 합의 프로토콜로 일관성을 보장한다. 

 

일관성도 프로토콜의 파라미터로 구분한다.

 

강한 일관성 모델일 경우 데이터 일관성을 위해서 락이 필요한데, 고가용성에 적절하지 못하다. 약한 일관성의 경우는 클라이언트에서 적절한 제어가 필요(데이터 버저닝).

 

장애처리에 대한 이야기는 생략(영구적 - 머클트리, 일시적 - 느슨한 정족수 알고리즘을 사용함)

 

AWS DynamoDB를 한창 쓸때, 일관성 확보에 대한 이야기를 스치듯 본 것 같아서 다시 한번 찾아봤다.

https://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/developerguide/HowItWorks.ReadConsistency.html

 

디폴트 옵션은 최종적 일관된 읽기, 선택적으로 강력한 일관된 읽기 기능을 제공한다.

 

여기서 강력한 일관된 읽기는 강한 일관성 모델이다. 그럼 최종적 일관된 읽기는 뭘까?

 

용어가 어려워서 그렇지 해석해보면,

 

복제본이 가지고 있는 데이터를 바로 줄거고, 이 데이터는 최종 데이터가 아닐 수 있어. 하지만 "최종적" 으로는 데이터 일관성을 보장해줄게. 타이밍이 꼬여서 그렇지 저장된 데이터는 "일관적으로" 최신이야. 라는 의미이다. 

 

7장 분산 시스템을 위한 유일 ID 생성기 설계

여기서부터는 요구사항이 명확한 설계를 요구한다.

 

분산환경에서의 db키를 어떻게 만드는 것이 좋을까? 에 대한 질문이다. 단일 DB 환경에서는 auto increment만으로도 충분할 수 있지만 db가 분산되어있다면 적절하지 못한 방식이다.

 

유일성만 생각한다면 uuid도 괜찮지만, uuid에는 시간 순서라던가 어떤 서버에서 생성됐다던가 하는 정보가 ID에 실려있지 않아서 아쉽다.

 

서버수 대로 xN을 해서 auto increment를 한다던가 티켓 서버를 둔다던가 등의 방법들을 제안하지만 모두 한계점이 있어서 트위터의 스노플레이크 접근법을 알려주고, 이러한 규모 확장성을 고려한 ID 생성 방식을 사용하는 걸 권장한다.

 

 8장. URL 단축기 설계

별도의 URL 생성 방식을 설계를 하지 않고, URL을 만들면 각종 파라미터가 붙어서 URL이 비정상적으로 길어지게 된다.

 

그래서 URL 단축기가 필요한데,

 

URL을 짧게 만드는 방법과 어떻게 하면 짧게 만들어진 URL이 원래 페이지로 유도할 수 있을까에 대해서 정리했다.

 

해시함수와 인코딩을 통해 URL을 짧게 만드는데 이 과정에서 중복체크가 필요한데 또 하나의 치트키 블룸필터가 나옴.

 

설계 자체는 어렵지 않지만 어떻게 중복없이 URL을 단축할 것인가?가 이슈였다.

 

책에서는 신기한 방법을 제안했지만 SSR 환경에서는 단축 URL을 해지하는 로직을 클라이언트에서도 가지고 있어서 솔직히 와닿지 않았던 부분이었다. 

 

9장. 웹 크롤러 설계

이 챕터는 너무 특이한 작업에 대한 설계라 빠르게 훑고 넘겼다.

 

단일 사이트를 크롤링해서 정보를 얻는 그런 크롤러가 아니라 포털 사이트와 같은 곳에서 웹 환경 전체를 훑는 크롤러 봇이 도는 방식을 설계하는 내용이었다.

 

이전에 크롤링한적이 있는 중복 컨텐츠 인가?를 검증하는 방식과 방문 알고리즘을 어떻게 설정할 것인가가 이슈였다.

 

재밌었던 부분은 페이지의 신선도(최근에 업데이트 혹은 업로드)를 평가하는 방법, 문제가 있는 콘텐츠(함정 사이트)를 피하기 위한 방법에 대한 내용이었다.

 

이 책에서는 소개하지 않았지만, 새로 생긴 페이지에 대한 정보는 어떻게 얻는걸까? 라는 의문이 남았다.

 

10장. 알림 시스템 설계

천만건의 push, 백만건의 sms, 5백만건의 email을 보내기 위한 시스템에 대한 설계다.

 

그런데 이정도는 나도 설계할 수 있을만한 내용이었다.

 

push, sms, email을 발송하기 위해서는 통신사를 제외하고는 자체 솔루션이 없기 떄문에 외부 서비스를 써야한다(SKT는 push/sms 발송 내부 서비스인 EMI 라는게 있었다).

 

외부 서비스를 사용할 경우 실패할 때 재시도하는 방식이 가장 중요한데, 큐와 재시도용 서버를 두고 반복 동작하는 방식을 책에서는 제안했다.

 

메인 설계 외의 추가 사항들 있었는데 내가 생각한건 로그 정도였는데, 모니터링과 템플릿까지는 고려하지 못했었음

(생각해보니 ZEM 서비스를 할 때, push나 sms도 템플릿을 엑셀파일에 만들어서 보내줬던 것 같다)

 

11장. 뉴스 피드 시스템 설계

이 책에서는 무상태 웹 계층이라는 표현을 자주 쓰는데, HTTP 통신을 하는 서버가 stateless하다는 것을 말하는 것 같다.

 

이는 곧 클라이언트의 상태를 서버가 따로 보관하고 있지 않는다는 뜻이다.

 

그래서 일반적인 서버-클라이언트 서비스에서는 서버가 클라이언트에게 서버의 변경사항을 전달할 수 없다.

(네이티브를 쓴다면 push로 보낼 수 있긴하다)

 

그래서 뉴스피드의 변경사항을 보려면 클라이언트에서 GET 요청을 해야 변경된 정보를 줄 수 있다.

 

생각 못한건 POST 방식으로 미리 뉴스피드를 만들어 놓는 것이다.

 

인프라 설계는 몇 가지 방법을 제안하기는 했는데, 여기서도 치트키 중 하나인 캐시, CDN이 등장하고 각각의 방법마다 장단점이 있어서, 결론은 정답은 없다였다.

 

딱히 특이한 내용은 없었다.


12장부터는 내용이 조금 복잡해지고 규모도 더 커진다.

 

원래는 하나의 포스팅이었는데 너무 길어지는 것 같아서 분리했다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함