사용자 수에 따른 규모 확장성 다루기
수직적 규모확장 vs 수평적 규모확장
-
수직적 규모확장 (스케일업)
- 서버에 고사양 자원(더 좋은 CPU, 더 많은 RAM)을 추가하는 행위
- 데이터베이스 서버 하드웨어에는 한계가 있어서, CPU, RAM 등을 무한 증설 할수는 없다. 사용자가 계속 늘어나면 결국 서버 한대로 처리하기는 어려움.
- SFOF(Single Point of Failure)로 인한 위험이 크다.
- SFOF 란 단일 장애 지점. 장애가 발생하면 이 하나의 서버로만 처리해야하는 것.
-
수평적 규모확장 (스케일아웃)
- 더 많은 서버를 추가하여 성능을 개선하는 것
- 샤딩 (sharding)이라고도 부름
- 샤딩은 데이터베이스를 샤드라고 부르는 작은 단위로 분할하는 기술
- 모든 샤드는 같은 스키마를 쓰지만 샤드에 보관되는 데이터 사이에는 중복이 없다.
- 아래와 같은 문제점이 있음
- 데이터의 재샤딩 : 데이터가 너무 많아져서 하나의 샤드로는 더 이상 감당하기 어렵거나, 샤드 간 데이터 분포가 균등하지 못하여 어떤 샤드에 할당된 공간 소모가 다른 샤드에 비해 빨리 진행 될 때. 샤드 소진이라고도 부르는 이런 현상이 발생하면 샤드 키를 계산하는 함수를 변경하고, 데이터를 재배치해야함.
- 유명인사 문제 : 특정 샤드에 질의가 집중되어 서버에 과부하가 걸리는 문제
- 조인과 비정규화 : 하나의 데이터베이스를 여러 샤드로 쪼개면, 여러 샤드에 걸친ㄷ ㅔ이터를 조인하기 힘들어진다. 이를 해결하는 한가지 방법은 데이터베이스를 비정규화 하여 하나의 테이블에서 질의가 수행될 수 있도록 하는 것
-
로드밸런서
- 부하 분산기
- 로드밸런서는 웹서버들에게 트래픽 부하를 고르게 분산하는 역할을 한다.
-
데이터베이스 다중화
- 주(master)-부(slave)관계를 정하고, 데이터 원본은 주서버에, 사본은 부서버에 저장하는 방식
- 쓰기연산은 마스터에만 지원하고 부 데이터베이스는 주 데이터베이스로부터 그 사본을 전달받아서 읽기 연산만을 지원한다.
캐시
- 캐시는 값비싼 연산결과 또는 자주 참조되는 데이터를 메모리 안에 두고, 뒤이은 요청이 보다 빨리 처리 될 수 있도록 하는 저장소이다.
- 캐시계층 (cache tier)은 데이터가 잠시 보관되는 곳으로 데이터베이스보다 훨씬 빠르다.
- 별도의 캐시 계층을 두면 성능이 개선될 뿐아니라, 데이터베이스의 부하를 줄일 수 있고 캐시 계층의 규모를 독립적으로 확장시키는 것도 가능해진다.
캐시를 사용 할 때에는 아래와 같은 유의점이 있다
- 캐시는 어떤 상황에 바람직한가?
- 데이터 갱신은 자주 일어나지 않지만, 참조는 빈번하게 일어난다면 고려해볼만하다.
- 어떤 데이터를 캐시에 두어야하는가?
- 캐시는 데이터를 휘발성 메모리에 두므로, 영속적으로 보관할 데이터를 캐시에 두는 것은 바람직하지 않다.
- 캐시에 보관된 데이터는 어떻게 만료 되는가?
- 일관성은 어떻게 유지되는가?
- 일관성은 데이터 저장소의 원본을 갱신하는 연산과 캐시를 갱신하는 연산이 단일 트랜잭션으로 처리되지 않는 경우 일관성이 깨진다.
- 장애에는 어떻게 대처할 것인가?
- 캐시 서버를 한대만 두는 경우 해당 서버는 단일 장애 지점 (SPOF)이 되어버린다.
- 캐시 메모리는 얼마나 크게 잡을 것인가?
- 캐시 메모리가 너무 작으면 액세스 패턴에 따라서는 데이터가 너무 자주 캐시에서 밀려나버려서 (eviction) 캐시의 성능이 떨어지게 된다. 이를 막을 방법은 캐시 메모리를 과할당하는것
- 데이터 방출(eviction) 정책은 무엇인가?
- 캐시가 꽉 차버리면 추가로 캐시에 데이터를 넣어야 할 경우 기존 데이터를 내보내야한다. 이것을 캐시 데이터 방출 정책이라고 하는데, LRU(Leat Recently Used), LFU(Least Frequently Used), FIFO(First In First Out)과 같은 정책이 있다.
CDN
- CDN은 정적 콘텐츠를 전송하는데 쓰이는 지리적으로 분산된 서버의 네트워크이다.
- 이미지/비디오/CSS/Javascript 파일등을 캐시 할 수 있다.
CDN 사용 시 고려해봐야할 점
- 비용
- 자주 사용되지 않는 콘텐츠를 캐싱하는 것은 이득이 크지 않으므로, CDN에서 빼는 것을 고려하자.
- 적절한 만료 시한 설정
- 시의성이 중요한 콘텐츠의 경우, 만료시점을 잘 설정해야한다. 너무 길면 콘텐츠의 신선도가 떨어지고, 너무 짧으면 원본서버에 빈번히 접속하게 되어 좋지 않다.
- CDN 장애에 대한 대처 방안
- CDN 자체가 죽었을 경우, 웹사이트/애플리케이션이 어떻게 동작할 지 고려해야한다.
- 콘텐츠 무효화 (Invalidation) 방법
- CDN 서비스 사업자가 제공하는 API로 무효화하기.
- 콘텐츠의 다른 버전을 서비스하도록 오브젝트 버저닝 이용하기. URL 마지막에 버전 번호를 인자로 주기.
무상태(Statelss) 웹 계층
웹 계층을 수평적으로 확장하는 방법을 고려해보자.
- 상태정보에 의존적인 아키텍쳐라면, 같은 클라이언트의 요청은 무조건 같은 서버에서 처리되어야한다.
- 대부분의 로드밸런서가 이를 지원하기 위해 고정세션이라는 기능을 가지고 있는데, 이는 로드밸런서에게 부담을 준다.
- 따라서, 무상태 아키텍쳐는 상태 정보(사용자 세션 데이터 같은 것)를 웹계층에서 제거하고 상태 정보를 별도의 데이터베이스에 저장하는 것이다.
메시지 큐
- 메시지 큐는 메시지의 무손실(durability, 즉 메시지큐에 일단 보관된 메시지는 소비자가 꺼낼 때 까지 안전하게 보관된다는 특성)을 보장하는 비동기 통신을 지원하는 컴포넌트이다.
- 메시지의 버퍼 역항르 하며 비동기적으로 전송한다.
- 메시지 큐의 아키텍쳐
- 생산자/발행자라고 불리는 입력 서비스가 메시지를 만들어 메시지 큐에 발행한다.
- 큐에는 보통 소비자 혹은 구독자라 불리는 서비스 혹은 서버가 연결되어 있는데, 메시지를 받아 그에 맞는 동작을 수행하는 역할을 한다.
- 메시지큐를 이용하면 서비스 또는 서버간의 결합이 느슨해져서, 규모 확장성이 보장되어야 하는 안정적인 애플리케이션을 구성하기 좋다.
- 생산자는 소비자 프로세스가 다운되어 있어도, 메시지를 발행할 수 있고 소비자는 생산자 서비스가 가용한 상태가 아니더라도 메시지를 수신할 수 있다.