You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
스케일 아웃 (Scale Out) : 인스턴스의 수를 늘려서 병렬적으로 작업을 분산하는 것을 의미한다.
🥐 AWS의스케일 아웃의 단계
로드 밸런서를 설정한다. AWS Elastic Load Balancer(ELB)를 설정하여 트래픽을 여러 인스턴스에 분산시킨다.
AWS Auto Scaling 그룹을 구성하여 트래픽 증가 시 자동으로 인스턴스를 추가하고 감소 시 제거한다.
CPU 사용률, 네트워크 트래픽 등 기준에 따라 스케일 아웃/인 조건 설정한다.
—> 우리의 서비스에서는 스케일아웃보다는 스케일업을 먼저 진행하면 좋을 것 같고, 훗 날 사용자가 매우 많아진다면 스케일아웃을 하는 것이 좋을 것이라고 판단하였다.
🍩 우리가 사용한 RDS 에서 자원을 확장시킨다는 것은 무엇을 의미하는 것일까 ?
우선, 앞선 과제에서 우리의 서비스는 write 성 API가 많다는 것을 확인하였다.
그렇다면, 아래의 표를 참고했을 때 스케일 아웃보다는 스케일업이 더 적합하다는 것을 알 수 있다.
구분
스케일 업(Scale Up)
스케일 아웃(Scale Out)
적용 시점
- CPU, 메모리 부족 시
- 읽기 트래픽이 많아 부하 분산이 필요할 때
방법
- 더 높은 스펙의 인스턴스 클래스로 업그레이드
- 읽기 전용 복제본(Read Replica) 추가
효과
- 단일 인스턴스 성능 증가
- 병렬 처리 가능, 읽기 작업 부하 분산
비용
- 스펙에 따라 비용 증가
- 복제본 수에 따라 비용 증가
한계
- 단일 인스턴스의 최대 한계
- 쓰기 성능에는 영향 없음
🥐 RDS의 스케일 업 과정
AWS Management Console로 이동
AWS Management Console에 로그인
RDS 서비스로 이동하여 업그레이드할 인스턴스를 선택
인스턴스 클래스 변경
RDS 콘솔 → 데이터베이스 → 변경하려는 인스턴스 선택:
인스턴스 세부 정보를 확인하고, 스케일 업이 필요한지 검토
수정 버튼 클릭:
"Modify" 버튼을 클릭하여 인스턴스 변경 작업을 시작
인스턴스 클래스 선택:
현재 인스턴스 클래스에서 더 높은 사양의 인스턴스 클래스를 선택합
예: t2.micro → m5.large.
스토리지 및 옵션 변경 (선택 사항)
필요에 따라 스토리지 크기 또는 타입(EBS)을 업그레이드
예: 기존 gp2 → io1 (프로비저닝된 IOPS).
백업 및 유지관리 옵션을 검토하고 변경
변경 사항 적용
변경 사항 검토 및 저장:
모든 설정을 검토하고 "Continue" 버튼을 클릭합니다.
변경 적용 옵션:
즉시 적용(Apply Immediately):
변경 사항을 즉시 적용하지만, 서비스 중단(다운타임)이 발생할 수 있음
유지관리 창에서 적용(During Maintenance Window):
유지관리 창에 변경 사항이 적용되며, 다운타임이 최소화 됨.
스케일 업 진행
AWS가 스케일 업 작업을 진행하며, 인스턴스가 재부팅될 수 있다.
진행 상황은 RDS 콘솔의 상태(Status)에서 확인할 수 있다.
완료 후 검토
스케일 업 작업 완료 후, 인스턴스가 정상적으로 동작하는지 확인한다.
RDS의 메트릭(CPU, 메모리 사용률 등)을 CloudWatch로 모니터링한다.
🍞 톰캣 워커 쓰레드 수, DB 커넥션 수에 대해 고민하기
🚨 잠깐 ! 톰캣 워커 쓰레드 수와 DB커넥션 수에 대해 알아보기 전에 이것저것 먼저 알아보고 가자 !
🍩 API 요청 흐름
백엔드 서버에서 API 요청을 DB 서버로 보내는 과정의 통신은 TCP(연결지향적) 기반으로 동작한다.
이 과정에서 connection 을 열고, 닫는 과정에서 꽤 많은 시간이 소요된다. ( 3 way, 4 way handshaking)
🍩 DBCP 등장 배경
위의 시간적인 비용 때문에 API 응답이 늦어지는 문제점.. 을 해결하기 위해 등장!
API 요청을 받게 되면
connection pool 에서 놀고 있는 connection 을 데려와서 이를 바탕으로 쿼리를 보낸다.
쿼리 요청, 응답 후 close connection 하게 되면
connection pool 에다가 다시 connection 을 반환한다.
즉, 본격적으로 API 요청을 맺기 전에
요청이 있을 때마다 새로운 커넥션을 생성하는 것이 아니라
백엔드 서버와 DB 서버 간에 DB connection 을 미리 만들어놓고,
재사용함으로써 연결을 open 하고 close 하는 시간을 절약한다.
⇒ 이 Pool 을 DBCP(Database Connection Pool) 라고 부른다 !!
1️⃣ 톰캣 워커 쓰레드란 ?
톰캣 서버에서 클라이언트의 요청을 처리하기 위해 사용하는 실제 스레드를 의미한다.
각 HTTP 요청은 톰캣 워커 쓰레드 중 하나에 의해 처리된다.
🍩 톰캣 워커 쓰레드의 동작 과정을 쉽게 이해해보자 !
클라이언트(사용자)가 브라우저를 통해 서버에 요청(HTTP Request)을 보낸다.
요청을 받은 톰캣은 대기 중인 워커 쓰레드 중 하나를 할당해준다.
요청 처리 중에는 해당 워커 쓰레드가 다른 요청을 처리할 수 없습니다.
워커 쓰레드는 클라이언트 요청을 처리(비즈니스 로직 실행, 데이터베이스 작업 등)한 후 응답(HTTP Response)을 반환한다.
요청 처리가 끝난 워커 쓰레드는 다시 대기 상태로 돌아간다.
만약, 요청이 많아 워커 쓰레드가 부족하면 요청은 대기 큐에 들어간다.
🍩 너무 적은 워커 쓰레드를 사용한다면 !
요청이 대기 큐로 넘어가 응답 시간이 증가한다.
일부 요청은 거부 될 위험이 존재한다.
🍩 너무 많은 워커 쓰레드를 사용한다면 !
CPU와 메모리를 과도하게 사용하여 서버 성능이 저하될 수 있다.
2️⃣ DB 커넥션 수란 ?
애플리케이션(예: 톰캣)이 데이터베이스(DB)와 연결을 생성하고 사용하는 최대 연결 수를 의미한다.
애플리케이션은 보통 커넥션 풀이라는 구조를 통해 DB 연결을 효율적으로 관리한다.
🍩 db 커넥션 수에 대해서 쉽게 이해해보자 !
DB 커넥션은 애플리케이션과 데이터베이스 간의 네트워크 통신 채널을 의미한다.
클라이언트 요청 중 DB와 상호작용이 필요한 작업(조회, 삽입, 업데이트 등)이 발생하면 DB 커넥션을 통해 데이터베이스와 통신한다.
커넥션 풀은 미리 생성된 DB 커넥션을 관리하여 요청 시 빠르게 연결을 제공하고, 작업이 끝난 후 다시 반환하도록 한다.
🍩 DB 커넥션 수가 너무 부족하다면 !
요청이 대기 상태로 전환되거나 실패 (TimeoutException)할 수 있다.
애플리케이션의 동시 요청 처리가 느려진다.
🍩 DB 커넥션 수가 너무 많다면 !
DB 서버가 과부하에 걸려 성능이 저하되거나 다운될 수 있다.
🍩 우리 서비스가 사용하고 있는 디폴트로 맺어지는 연결의 수는 ?
별도의 설정을 하지 않으면 HikariCP는 기본적으로 최대 10개의 DB connection 을 관리한다.
HikariCP 에서 권장하기를..
minimumidle의 기본값은 maximumPoolSize 와 동일한데,minimumidle 값을 별도로 설정하지 말고 maximumPoolSize와 동일하게 유지하는 것을 권장한다.
즉, Connection Pool 의 사이즈가 고정이라는 의미다 !!
왜 그렇게 해용?
💡 minimumidle < maximumPoolSize 라고 생각해볼까?
추가 트래픽이 몰릴 때마다 connection 을 만들어주어야 하는데, 아까 살펴보았던 것처럼 connection 을 만드는 과정은 시간이 많이 듭니다. connection 을 만들어 주는 속도보다, 더 빠른 속도로 트래픽이 몰려오게 되면 백엔드 서버의 응답이 느려질 수 있습니다.
⇒ 애초에 처음부터 적절한 개수로 Connection Pool size를 고정해서 사용하라! 는 말
⇒ 왜냐? 트래픽이 급증해도 새로운 connection 생성하느라 시간낭비 안하고 즉각 대응이 가능하니까!
🍩 결론 !!!!
DB 커넥션 수는 트래픽, 요청당 처리 시간, DB 서버 용량 등을 고려하여 적절히 설정해야한다.
일반적으로 동시 요청 수** ≤ **DB 커넥션 풀 크기** ≤ **DB 서버 최대 커넥션 처리 용량 로 계산한다.
🍞 그렇다면 우리 서비스가 TPS 1000 이 된다 가정하면, 톰캣, 스프링 설정 값을 어떻게 변경하는 것이 좋을까 ?
TPS 1000의 경우, 서버는 초당 1000개의 요청을 처리해야 하므로 성능 병목을 방지하고 효율적인 처리를 보장하기 위해 톰캣과 스프링의 설정을 최적화해야 한다.
예상 설정 값
설정 항목
설정 값
톰캣 maxThreads
150~200
톰캣 maxConnections
2000
톰캣 Keep-Alive
활성화 (maxKeepAliveRequests=1000)
DB 커넥션 풀 크기
100
스프링 Task Execution Pool
core-size=50, max-size=150
🍞 그렇다면 적정한 DB connection 수는요?
딱 정해져 있는 정답은 없다 !!!
: 모니터링 & 부하 테스트 를 통해…..
1️⃣ 모니터링 환경을 구축
CPU, 메모리, 서버 스레드 수, DBCP 상태 등을 파악한다.
2️⃣ 부하 테스트 진행
request per second(백엔드 시스템의 전체적인 처리량) & avg response time(API 성능확인)을 확인
request per second : 트래픽 늘어나다가 어느 순간에는.. RPS가 일정하게 유지, avg response time또한 일정하게 유지되다가 계속 증가.
→ 이 유지, 증가 되는 병목 포인트들에서 지표들이 어떻게 되는지 모니터링 해야겠다!
3️⃣ 백엔드 서버 & DB 서버의 등의 리소스(CPU, MEM) 사용률 확인
백엔드 서버의 리소스 사용률 많으면 많으면 백엔드 서버 추가!
DB서버의 리소스 사용률 많으면.. 부하 낮추는 방법 여러가지 존재함 (생략)
→ But, 둘 다 괜찮은데 병목 포인트가 생기면??
4️⃣ 추가적인 지표 확인 1
thread per request(요청당 하나의 스레드를 사용) 모델이라면 → active thread 수 확인 → 괜찮은데?
그럼 DBCP의 active connection 수 확인 → 헉 이게 문제였군.
maximumPoolSize 를 올려가면서 다시 부하 테스트
⇒ 근데, connection pool 사이즈를 늘려도 어느 순간부터 성능이 개선이 안된다면??
5️⃣ 추가적인 지표 확인 2
DB 서버의 max_connections 의 수 확인해서 필요하면 늘린다!
⇒ 사용할 백엔드 서버 수(CPU등등)를 전체적으로 고려하여 DBCP의 max pool size 결정
⇒ 종합적으로 고려하면서 적절한 DB의 connection 수 설정
요약
DB의 max_connections 수 확인 → 필요 시 조정
그를 기준으로 백엔드 서버 수를 고려해서
max_connections 초과하지 않도록 각 서버의 DBCP 별로 max pool size를 어떻게 가질건지 설정
🍞 전체 3줄 요약
우리 서비스에서 병목지점이 될 만한 기능과 해결방법
우리 서비스에서 스케일 아웃 혹은 스케일 업할 때 필요한 스팩
톰캣 워커 쓰레드 수 및 db 커넥션 수에 대한 조사
The text was updated successfully, but these errors were encountered:
TODO
🍞 TPS란 ?
TPS (Transaction Per Second)
: 초당 처리 가능한 요청(트랜잭션)의 수를 의미한다.TPS 1000이라면 서버가 1초에 1000개의 요청을 처리해야 한다는 것 의미한다.
🍞 우리의 서비스에서 병목지점이 될 만한 기능 !
🍩 병목 지점이란 ?
시스템의 처리 속도(성능)가 특정 구성 요소의 한계로 인해 전체 성능이 저하되는 지점을 의미한다.
🍩 우리의 서비스에서는 “학기별 과목 목록 조회 API” 에서 병목현상이 생길 위험이 크다 !!
해당 API를 호출할 때 수많은 조인을 거치기 때문에 발생하는 쿼리 개수는 12개다.
2차과제인 트러블슈팅에도 적었지만, 학기별 과목 목록 조회하기 API에서 필요한 데이터들을 가져오기 위한 과정이 너무 길어서 2번에 나눠서 쿼리문을 작성했다.
따라서 해당 API를 조회할 때마다 리소스가 많이 들게 된다. !!!!
🍞 우리의 서비스에서 병목 지점을 해결하기 위한 방법 !
스케일 아웃하는 서버 수 혹은 스케일 업을 어떤 스펙으로 등 어떻게 트래픽을 받아볼 수 있을지 고민하기
1️⃣ 쿼리 최적화
🍩 인덱스 추가
데이터베이스 테이블에서 데이터를 더 빠르게 조회하기 위해 사용하는 인덱스를 이용해보자 !
특정 컬럼에 대해 인덱스를 생성하면 데이터를 순차적으로 탐색하는 것이 아니라 인덱스를 통해 필요한 데이터를 바로 조회할 수 있다.
우선, 현재 우리의 ERD는 이러하다. 모든 테이블들이 서로서로 연결되어 있으므로 데이터를 관리하기가 너무 힘들다. 기본적으로 모든 API에서 쿼리문이 4개정도 나가게 되므로 자주 사용하는 정보들을 조회할 때는 인덱스를 도입하는 것이 효과적일 것이라고 판단되었다.
가장 많이 조회된다고 생각하는 내용은 다음과 같다.
🍩 필요한 데이터만 조회하여 조인을 최소화한다.
SELECT *
로 모든 데이터를 조회하지 않고 필요한 내용만 조회하도록 한다.🥐 AWS의 스케일 업의 단계
현재 우리의 인스턴스 타입은
t2.micro
이다.스케일 아웃 (Scale Out) : 인스턴스의 수를 늘려서 병렬적으로 작업을 분산하는 것을 의미한다.
🥐 AWS의 스케일 아웃의 단계
—> 우리의 서비스에서는 스케일아웃보다는 스케일업을 먼저 진행하면 좋을 것 같고, 훗 날 사용자가 매우 많아진다면 스케일아웃을 하는 것이 좋을 것이라고 판단하였다.
🍩 우리가 사용한 RDS 에서 자원을 확장시킨다는 것은 무엇을 의미하는 것일까 ?
우선, 앞선 과제에서 우리의 서비스는 write 성 API가 많다는 것을 확인하였다.
그렇다면, 아래의 표를 참고했을 때 스케일 아웃보다는 스케일업이 더 적합하다는 것을 알 수 있다.
🥐 RDS의 스케일 업 과정
t2.micro
→m5.large
.gp2
→io1
(프로비저닝된 IOPS).🍞 톰캣 워커 쓰레드 수, DB 커넥션 수에 대해 고민하기
🚨 잠깐 ! 톰캣 워커 쓰레드 수와 DB커넥션 수에 대해 알아보기 전에 이것저것 먼저 알아보고 가자 !
🍩 API 요청 흐름
백엔드 서버에서 API 요청을 DB 서버로 보내는 과정의 통신은 TCP(연결지향적) 기반으로 동작한다.
이 과정에서 connection 을 열고, 닫는 과정에서 꽤 많은 시간이 소요된다. ( 3 way, 4 way handshaking)
🍩 DBCP 등장 배경
위의 시간적인 비용 때문에 API 응답이 늦어지는 문제점.. 을 해결하기 위해 등장!
즉, 본격적으로 API 요청을 맺기 전에
요청이 있을 때마다 새로운 커넥션을 생성하는 것이 아니라
백엔드 서버와 DB 서버 간에 DB connection 을 미리 만들어놓고,
재사용함으로써 연결을 open 하고 close 하는 시간을 절약한다.
⇒ 이 Pool 을
DBCP(Database Connection Pool)
라고 부른다 !!1️⃣ 톰캣 워커 쓰레드란 ?
톰캣 서버에서 클라이언트의 요청을 처리하기 위해 사용하는 실제 스레드를 의미한다.
각 HTTP 요청은 톰캣 워커 쓰레드 중 하나에 의해 처리된다.
🍩 톰캣 워커 쓰레드의 동작 과정을 쉽게 이해해보자 !
🍩 너무 적은 워커 쓰레드를 사용한다면 !
🍩 너무 많은 워커 쓰레드를 사용한다면 !
2️⃣ DB 커넥션 수란 ?
애플리케이션(예: 톰캣)이 데이터베이스(DB)와 연결을 생성하고 사용하는 최대 연결 수를 의미한다.
애플리케이션은 보통 커넥션 풀이라는 구조를 통해 DB 연결을 효율적으로 관리한다.
🍩 db 커넥션 수에 대해서 쉽게 이해해보자 !
🍩 DB 커넥션 수가 너무 부족하다면 !
TimeoutException
)할 수 있다.🍩 DB 커넥션 수가 너무 많다면 !
🍩 우리 서비스가 사용하고 있는 디폴트로 맺어지는 연결의 수는 ?
별도의 설정을 하지 않으면 HikariCP는 기본적으로 최대 10개의 DB connection 을 관리한다.
HikariCP 에서 권장하기를..
minimumidle
의 기본값은maximumPoolSize
와 동일한데,minimumidle 값을 별도로 설정하지 말고 maximumPoolSize와 동일하게 유지하는 것을 권장한다.왜 그렇게 해용?
💡
minimumidle < maximumPoolSize
라고 생각해볼까?추가 트래픽이 몰릴 때마다 connection 을 만들어주어야 하는데, 아까 살펴보았던 것처럼 connection 을 만드는 과정은 시간이 많이 듭니다. connection 을 만들어 주는 속도보다, 더 빠른 속도로 트래픽이 몰려오게 되면 백엔드 서버의 응답이 느려질 수 있습니다.
⇒ 애초에 처음부터 적절한 개수로 Connection Pool size를 고정해서 사용하라! 는 말
⇒ 왜냐? 트래픽이 급증해도 새로운 connection 생성하느라 시간낭비 안하고 즉각 대응이 가능하니까!
🍩 결론 !!!!
DB 커넥션 수는 트래픽, 요청당 처리 시간, DB 서버 용량 등을 고려하여 적절히 설정해야한다.
일반적으로
동시 요청 수** ≤ **DB 커넥션 풀 크기** ≤ **DB 서버 최대 커넥션 처리 용량
로 계산한다.🍞 그렇다면 우리 서비스가 TPS 1000 이 된다 가정하면, 톰캣, 스프링 설정 값을 어떻게 변경하는 것이 좋을까 ?
TPS 1000의 경우, 서버는 초당 1000개의 요청을 처리해야 하므로 성능 병목을 방지하고 효율적인 처리를 보장하기 위해 톰캣과 스프링의 설정을 최적화해야 한다.
예상 설정 값
🍞 그렇다면 적정한 DB connection 수는요?
1️⃣ 모니터링 환경을 구축
CPU, 메모리, 서버 스레드 수, DBCP 상태 등을 파악한다.
2️⃣ 부하 테스트 진행
request per second(백엔드 시스템의 전체적인 처리량) & avg response time(API 성능확인)을 확인
request per second : 트래픽 늘어나다가 어느 순간에는.. RPS가 일정하게 유지, avg response time또한 일정하게 유지되다가 계속 증가.
→ 이 유지, 증가 되는 병목 포인트들에서 지표들이 어떻게 되는지 모니터링 해야겠다!
3️⃣ 백엔드 서버 & DB 서버의 등의 리소스(CPU, MEM) 사용률 확인
백엔드 서버의 리소스 사용률 많으면 많으면 백엔드 서버 추가!
DB서버의 리소스 사용률 많으면.. 부하 낮추는 방법 여러가지 존재함 (생략)
→ But, 둘 다 괜찮은데 병목 포인트가 생기면??
4️⃣ 추가적인 지표 확인 1
⇒ 근데, connection pool 사이즈를 늘려도 어느 순간부터 성능이 개선이 안된다면??
5️⃣ 추가적인 지표 확인 2
⇒ 사용할 백엔드 서버 수(CPU등등)를 전체적으로 고려하여 DBCP의 max pool size 결정
⇒ 종합적으로 고려하면서 적절한 DB의 connection 수 설정
요약
🍞 전체 3줄 요약
The text was updated successfully, but these errors were encountered: