들어가기
비동기 작업을 이용하려면 스레드 풀을 이용해야 합니다.
요청마다 스레드를 생성하게 되면 생성 비용, 메모리 부족, 콘텍스트 스위칭 비용 등 여러 문제가 발생한다.
따라서 적정 수준의 스레드 수를 선택하는 방법을 알아보려합니다.
CorePoolSize, WorkQueueSize, MaximumPoolSize, KeepAliveTime
스레드 풀은 스레드를 미리 생성해 놓고 요청이 발생하면 스레드를 할당한 뒤에 응답이 완료되면 해당 스레드는 제거되지 않고 스레드 풀에 반환됩니다.
CorePoolSize : WorkQueue가 꽉 차지 않으면 스레드는 CorePoolSize 만큼 생성돼 존재합니다. CorePoolSize를 넘어서는 요청은 WorkQueue에 대기합니다.
MaximumPoolSize : CorePoolSize만큼 스레드가 실행 중이고 WorkQueue 또한 꽉 차있다면 추가로 MaximumPoolSize까지 스레드 풀을 확장합니다.
KeepAliveTime : CorePoolSize를 넘어선 스레드들은 KeepAliveTime에 설정된 시간이 지나면 제거됩니다. 항상 CorePoolSize를 유지하여 오버헤드를 줄이기 위함입니다.
위 설정을 잘못 변경하면 스레드를 무분별하게 생성할 수 있고 이는 스레드 풀이 가지는 의미를 무색하게 할 수 있습니다.
MaximumPoolSize!= CorePoolSize [newCachedThreadPool]
WorkQueue 크기 설정에 따라 달라지겠지만 위 설정을 적용한 스레드풀은 스레드풀의 크기가 달라질 수 있습니다.
MaximumPoolSize와 CorePoolSize의 차이가 커질수록 스레드를 생성할 수 있는 범위는 그때그때 달라집니다.
즉 서버의 부하는 사용자의 요청에 의존적인 상태가 됩니다.
newCachedThreadPool은 CorePoolSize = 0, MaximumPoolSize = Interger.MAX_VALUE로 매우 극단적인 스레드 풀 전략입니다. 해당 스레드풀을 사용하는 모든 테스크의 실행시간과 트래픽이 예측가능하다면 사용해도 되겠지만 그런 상황이 있을까 싶습니다.
MaximumPoolSize = CorePoolSize [newFixThreadPool]
MaximumPoolSize와 CorePoolSize를 같도록 지정하면 이 스레드 풀은 크기가 고정됩니다.
WorkQueue가 꽉 찬다고 하더라도 스레드 풀의 크기를 늘리지 않습니다. (WorkQueue의 기본 값은 Integer.MAX_VALUE 입니다.)
하지만 스레드 풀이 고정이라는 것은 사용자의 요청을 처리하지 못하고 task를 reject 할 수 있기에 그에 대한 방안을 생각해 놓아야 합니다.
Reject 시 대응 방안만 있다면 서버가 부하를 감당하지 못하고 내려가는 것보다는 훨씬 좋다고 생각합니다.
공식?
적정 스레드 풀 = CPU 수 * (CPU 목표 사용량) * (1+대기 시간/서비스 시간)라는 공식이 있습니다.
솔직히 CPU 수와 CPU 목표 사용량을 제외한 나머지 두 파라미터는 가변적이고 예측하기 어렵습니다.
그래서 서버 스펙에 따라서 부하테스트를 달리 적용하며 적정 스레드 풀 크기를 찾아가야 합니다.
EC2 t2.micro를 사용 중이라면 CPU가 1개이고 t2.micro의 baseline은 5%이기에...
스레드풀을 매우 적게 설정하고 사용해야 할 것 같습니다.
참고로 EC2T유형에서 말하는 baseline이란 간단히 CPU 활용률에 제한을 거는 용도로 사용됩니다.
baseline을 상회하면 크레딧를 소모하고 그 이하라면 크레딧을 소모하지 않습니다.
'Spring' 카테고리의 다른 글
위치기반 서비스 데이터베이스 선택 [MySQL] (0) | 2024.07.12 |
---|---|
게시글과 이미지 등록 API 분리로 API Latency 개선기 (3) (0) | 2024.07.06 |
게시글과 이미지 등록 API 분리로 API Latency 개선기 (2) (0) | 2024.06.19 |
게시글과 이미지 등록 API 분리로 API Latency 개선기 (1) (0) | 2024.06.19 |
회원 도메인 객체 코드 개선하기 (0) | 2024.04.12 |