Team
[CS 스터디] 시스템 설계
seungh2
2023. 6. 13. 14:09
수평적 vs 수직적 규모 확장
🤍수직적 규모 확장 Vertical Scaling
- 특정 노드의 자원(Resource)의 양을 늘리는 방법
- ex) 서버에 메모리를 추가해 서버의 처리 능력을 향상시키는 것
🖤수평적 규모 확장 Horizontal Scaling
- 노드의 개수를 늘리는 방법
- ex) 서버를 추가함으로써 서버 한 대가 다뤄야 하는 부하(load)를 줄이는 것
- 수직적 규모 확장이 일반적으로 수평적 규모 확장보다 쉽다.
- 하지만 메모리 혹은 디스크와 같은 것만 추가할 수 있기 때문에 제한적이다.
서버 부하 분산 장치 (load balancer)
- 사용자와 서버 그룹 사이에 위치하며 모든 리소스 서버가 동일하게 사용되도록 한다.
- 서버에 걸리는 부하를 여러 대의 서버에 균일하게 분산시킬 수 있다.
- 서버 한 대 때문에 전체 시스템이 죽거나 다운되는 상황을 방지할 수 있다.
- 최신 애플리케이션은 수백만 명의 사용자를 동시에 처리하고 정확한 텍스트, 비디오, 이미지 및 기타 데이터를 빠르고 안정적인 방식으로 각 사용자에게 반환해야 한다. 많은 트래픽을 안정되게 처리하기 위해 Load Balancer를 사용한다.
데이터베이스 반정규화(Denarmalization)와 NoSQL
- 관계형 데이터베이스의 JOIN 연산은 시스템이 커질수록 굉장히 느려진다. 따라서 JOIN 연산은 가능하면 피해야 한다.
- 반정규화
- 데이터베이스에 중복된 정보를 추가해 읽기 연산 속도를 향상시키는 것
- NoSQL
- JOIN 연산 자체를 지원하지 않는다.
- 데이터를 저장할 때 관계형 데이터베이스와 다른 방식으로 구성하는데 이 방식이 규모 확장성에 좋다.
네트워크 성능 척도
대역폭(bandwidth)
- 단위 시간에 전송할 수 있는 데이터의 최대치
- 보통 초당 몇 bit를 보낼 수 있는지로 계산한다.
처리량(throughput)
- 단위 시간에 실제로 전송된 데이터의 양
높이는 방법
- 서버의 개수를 늘리자.
- Thread Pool 또는 DB Connection Pool의 크기를 늘리자.
- 서버의 요청 처리 시간을 줄이자.
지연 속도(latency)
- 데이터를 전송하는데 걸리는 시간
- 발송자가 데이터를 보낸 시점부터 수신자가 데이터를 받는 시점까지 걸린 시간
- Latency는 무시되기 쉽지만 특정 상황에선 중요한 역할을 한다. 예를 들어 온라인 게임에서는 Latency가 아주 중요하다.
줄이는 방법
- 응답 크기를 줄이자.
- 트래픽을 분리하자.
- 대역폭을 늘리자.
트래픽을 분리하는 방법으로 이미지와 같은 정적 파일을 CDN을 통해 제공하는 방법이 있는데 이 방법이 대역폭을 늘리는 방법과 비교했을 때 비용 측면에서 유리하다.
💎CDN (Content Delivery Network)
- 데이터 사용량이 많은 애플리케이션의 웹 페이지 로드 속도를 높이는 상호 연결된 서버 네트워크
- 사용자가 해당 서버에서 멀리 떨어져 있는 경우 동영상이나 이미지 같은 대용량 파일을 로드하는데 시간이 오래 걸리기 때문에 사용자와 가까운 CDN 서버에 저장되어 사용자에게 훨씬 빨리 도달하도록 만드는 것
- 즉, 사용자와 웹 사이트 서버 간에 중간 서버를 두어 효율성을 높이는 방법
- 사용의 주 목적은 Latency를 줄이거나 네트워크 설계로 인해 발생하는 통신 지연을 줄이는 것
시스템 설계 시 고려할 점
실패 Failures
- 시스템의 어떤 부분이든 실패 가능성이 존재한다.
- 가 부분이 실패했을 때를 대비한 대비책을 준비해야 한다.
- Error Handling
읽기 중심 vs 쓰기 중심
- 읽는 연산이 많은지 아니면 쓰는 연산이 많은지에 따라 설계 방식이 달라질 수 있다.
- 쓰는 연산이 많다면 큐를 사용하는 방법을 한 번 고려해봐라.
- 읽는 연산이 많다면 캐시를 사용하는 것이 좋을 수도 있다.
보안 Security
- 보안 위협은 시스템에 엄청난 해를 가할 수 있다.
- 해당 시스템이 직면할 수 있는 문제점에 대해 생각해보고 이를 해결하기 위해 어떻게 시스템을 설계해야 하는지 고려하자.
면접에서 어떤 서비스를 설계 및 구현을 해보라고 했을 때 고려해야 할 점
- 클라이언트 측의 사용 편의성
- 클라이언트가 사용하기 쉬운 서비스여야 한다.
- 서버 측의 편의성
- 우리가 구현하기도 편해야 한다.
- 구현 비용이나 유지보수 비용 측면에서 불필요한 일을 하지 않도록 해야 한다.
- 나중에 생길 수 있는 요구를 수용하기에 유연한 구조
- 요구사항의 변화는 언제든 생길 수 있다. 이를 수용할 수 없으면 곤란하기 때문에 구현에만 집중해 생각하면 안된다.
- 규모 확장성과 효율성
- 서비스에 과도한 부하가 가해지지 않도록, 효율성에 대해서도 신경써야 한다.
완벽한 시스템은 없다.
- 완벽하게 동작하는 시스템 설계란 존재하지 않는다.
- 모든 시스템에는 장단점이 존재한다. 각 시스템 마다 상황에 맞는 설계를 해야 한다.
- 우리는 사례를 잘 이해하고, 문제의 범위를 설정하고, 합리적인 가정을 세운 뒤, 명확하게 설계한 시스템을 만드는 것이다.
728x90