limdef 2023. 7. 20. 12:05

키워드 위주 + 읽으면서 드는 생각들 정리 


지은이의 글

“지원자를 평가하는 방법 중 하나는 모호한 문제를 어떻게 분석하고 단계적으로 해결하는지를 보는 것”


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

따로 찾아보면 좋을 것 같은 부분

- DNS 계층적 구조는 어떤 방식이고 어떻게 동작할까

- IP에 따라 라우터가 destination까지 어떻게 패킷을 전송할까

 

Scale-up vs Scale-out

- Scale-up 이 단순하지만 한계가 있다.

   - cpu, memory 자원의 한계

   - 장애가 나면 서비스 중단

 

- Scale-out이 여러모로 유리

  -로드밸런서 활용 가능

 

DB master-slave, 다중화하면 좋다.

- 성능과 장애대비면 좋음

 

캐시 서버 활용하면 좋다.

- memcached 의 consistent hasing을 활용할 때 일관성이 깨지는 경우 조심

  -특정 노드가 죽고, 해당 노드의 특정 데이터가 갱신되고 다시 죽었던 노드가 살아났다 다시 죽으면?

  - https://charsyam.wordpress.com/2011/11/25/memcached-%EC%97%90%EC%84%9C%EC%9D%98-consistent-hashing/

  -캐시 만료를 짧게 가져가면 불일치의 시간을 그나마 줄일 수 있음. 

 

CDN(콘텐츠 전송 네트워크)

- 정적인 컨텐츠 전달. 지리적으로 서버가 분산되어 있음. 이미지, 비디오, css, js 등

- 캐시와 비슷. 이미지 접근 시 CDN에 있으면 CDN에서 가져오고 없으면 원본 서버에서 가져오고 CDN에 저장.

 

서버가 여러개 이므로 세션 저장소를 고려해야 한다.

 

 데이터센터 다중화 -> zero-downtime

- 트래픽 우회하는 방법 무엇이 있을까 ? GSLB 에서 VIP 제거 ?

 

데이터베이스 확장 

- 수직적 : 고성능 서버 사용

- 수평적 : 샤딩 방식으로 확장 가능하지만 다음과 같은 문제 고려.

  - 재샤딩 : 샤드 키 계산하는 함수도 변경하고, 데이터도 재배치 해야함.

  - 핫스팟키 : 특정 샤드에 부하가 몰릴 수 있다. 부하가 고르게 분산되도록 고민 필요.

  - 조인과 비정규화 : 여러 샤드에 걸친 데이터를 조인하기 힘듦.

 

 

2장 개략적인 규모 측정

결과보다 올바른 절차를 밟는 것이 중요

QPS : Query Per Second

HA : High Availability 고가용성 

 

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

오버엔지니어링 조심

병목 구간 고려

 

4장 처리율 제한 장치 설계 

고려할 사항

서버 측에서 제한하나? 클라이언트 측에서 제한하나?

-> 서버측 제한 가정. 클라이언트 측 제한에 의존하면 위변조 같은 공격에 취약

제한하는 기준이 IP ? 유저 ID ? 

-> 유연하게 설정할 수 있도록 가정

독립적인 컴포넌트인가? 코드에 포함되어야 하는가?

-> 독립적인 컴포넌트라 가정

 

보통은 클라우드 마이크로서비스를 많이 사용한다.  cloudflare?

클라이언트와 서버 사이에 미들웨어(gateway)로 둔다.

레디스같은 메모리 기반 저장소를 처리율 제한 미들웨어로 많이 쓴다.

-> 쓰기 읽기 연산이 많아서 디스크는 적합하지 않음

 

클라이언트 -> 미들웨어 -> API 서버

 

클라이언트는 처리율 제한에 걸리면 보통 429 응답과 X-Ratelimit-? 헤더를 응답으로 받음

요청은 버려질 수도 큐에 보관될 수도 있다.

 

동기화 이슈

- 처리율 제한 장치를 여러 대 둔다고 할 때

- 특정 클라이언트가 요청을 반복할 때 서로 다른 처리율 제한 장치에 요청을 보낼 수 있음

- 고정 세션을 사용해서 같은 클라이언트를 같은 처리율 제한 장치로 보내는 방법이 있다.

- 하지만 유연성이 떨어져 그냥 레디스 하나 쓰는 게 답.

 

 

처리율 제한 알고리즘 

a. 토큰 버킷 

- 토큰 버킷에 토큰이 일정 시간마다 공급됨.

- 토큰 공급이 토큰 용량을 초과하면 토큰은 버려짐

- 요청 하나당 토큰 하나를 사용

- 토큰 버킷에 사용할 토큰이 없으면 요청은 버려짐

 

토큰 버킷을 몇개 쓰는가 ? -> 엔드포인트마다 혹은 IP주소 마다 등으로 정할 수 있다.

시스템의 처리율을 통합해서 제한하고 싶으면 하나의 버킷 사용.

 

토큰 공급률, 버킷 크기의 값을 적절히 선정하기가 까다로움.

 

b. 누출 버킷

- 요청을 큐에 넣음

- 큐가 가득차면 새요청은 버려짐

- 지정된 시간마다 요청을 큐에서 꺼냄

 

c. 고정 윈도 카운터

- 타임 라인을 고정된 간격의 윈도로 나누고 윈도마다 카운터 붙임

- 요청이 접수될 때마다 카운터 증가

- 카운터 값이 임계치에 도달하면 새요청은 새윈도가 열릴 때까지 버려짐

 

윈도 경계에 일시적으로 트래픽이 몰리면, 기대 했던 처리 한도보다 많은 처리되어 단점이 됨.

 

d. 이동 윈도 로깅

- 타임스탬프에 만료시간을 달아 로그로 저장

- 로그의 크기가 허용치보다 작거나 같을 때만 시스템에 요청 전달

 

메모리를 많이 잡아 먹는 단점이 있다

 

e. 이동 윈도 카운터

- 고정 윈도와 이동 윈도 로깅 결합, 겹치는 비율 계산해서 곱함