
아키텍트가 알아야 할 커넥션 풀의 기본과 함정 | 멤버십 영상
요약
DB 커넥션 풀의 개념과 필요성, 그리고 적절한 풀 사이즈를 결정하는 방법에 대해 다룹니다. 커넥션 생성 시 발생하는 오버헤드를 줄이기 위한 풀링의 원리와 라이브러리별 기본 설정값을 설명합니다.
핵심 포인트
- DB 커넥션 생성 시 발생하는 핸드셰이크 및 프로세스 할당 비용 절감
- PostgreSQL의 프로세스 기반 구조에 따른 메모리 사용 특성 이해
- 경험이나 기본값에 의존하기보다 부하 테스트를 통한 최적값 도출 권장
- HikariCP, ADO.NET 등 주요 라이브러리의 기본 풀 사이즈 차이 확인
Video: 아키텍트가 알아야 할 커넥션 풀의 기본과 함정 | 멤버십 영상
Channel: 코딩하는기술사
Duration: 37m 33s
Source: subtitle (auto, ko)
Transcript:
안녕하세요. 사랑하는 멤버 여러분. 오늘은이 DB 커넥션 풀 얘기를 좀 해 볼까 합니다. 실무에서이 DB 커넥션 풀 다들 사용하고 계시죠?이 풀 사이즈를 몇 개로 설정해서 사용하고 계시나요? 어, 오늘은이 DB 커넥션 풀을 몇 개로 설정해야 될지에 대해서 한번 알아보겠습니다. 자, 먼저 다들 아시겠지만 어, DB 커넥션 풀 개념에 대해서 잠시만 보고 넘어가겠습니다. 어, DB 커넥션 풀은이 DB 커넥션을 미리 만들어 놓고 필요할 때 빌려쓰고 다 쓰면 반납하는 것을 말하죠. 어, TV 커넥션을 새로 만들 때는 비용이 많이 들기 때문에 이렇게 미리 만들어 놓고 풀에 담아 놓고 필요할 때 빌려쓰고 반납하고 그런 식으로 사용을 하는데요. 어,이 비용은 뒤에서 다시 한번 말씀을 드릴 거고요. 참고로이 포스트 SQL은 프로세스 기반이라서 크네션 수가 늘어나면 메모리도 함께 증가하죠. 그래서이 매 요청마다 커넥션을 새로 만든다 그러면이 오버헤드가 누적되어서 시스템이 부하가 갈 수 있습니다. 그래서 DV 커넥션 풀을 사용하는데요.
어 개념적인 그리름을 보면 이런 식이죠. 풀을 이렇게 만들고 커넥션 객체를 풀에 담아두죠. 그리고 어플리케이션에서 필요할 때마다이 풀을 가져와서 데이터베이스 작업을 하고 작업이 끝나면 다시 풀로 반납을 하죠. 어,이 부분은 다들 알고 계시리라 봅니다. 자, DV 커넥션을 풀에 미리 만들어 놓은 형태가 아니라 매번 코리를 할 때 커넥션을 만든다 그러면 HCP 스류 핸드세이크 비용 그리고 어, 보안을 사용할 때는 이런 SSL TLS 협상 비용 그리고 데이터베이스 개정 인정하는 비용 그리고 백엔드의 프로세스를 할당하는 비용 아까 말씀드렸죠? 포스트레스Q은 커넥션당 별도 프로세스가 만들어진다고. 자, 그래서 이렇게 커넥션을 한번 생성할 때 보통 수밀리세에서 수십m까지 발생을 할 수 있기 때문에 우리가 풀에 미리 만들어 놓고 필요할 때마다 빌려서는 것으로 사용을 하는 거죠. 역시 개적으로 보면 어 불이 없을 때랑 불이 있을 때 차이인데요. 없을 때는 매번 DB 코리가 필요할 때 생성하는 비용 들고 코리를 하고 또 파괴하고 또 다음 번 DB 코리가 발생할 때는 또 생성하는 비용을 발생시키고 매번 이렇게 생성 비용이 발생하는대 반해서 풀로 미리 커넥션을 만들어 두면 어 DV 요청할 때마다 미리 생성된 거를 가져와서 사용하고 다 사용하면 반납을 하기 때문에 매번 생성 비용이 발생하지 않죠.
그래서 생성 비용은 한 번만 풀에 처음에 생성될 때 한 번만 생성 비용이 발생하는 거죠. 자, 그런데 한번 체크 한번 해 볼게요. 어, 여러분들은 어떤 기준으로이 DB 커넥션 풀 사이즈를 결정하나요? 어, 수정 없이 그냥 라이브러리에서 사용하는 기본값을 그대로 사용하시나요? 아니면 어, 경험이나 감으로 특정한 개수를 지정하시나요? 뭐 가령 예전 프로젝트에서 50개를 썼으니까 이번에도 50개. 그게 아니라면 어 일종에이 업계에 통되는 표준 공식을 참조를 하시나요? 또이 부하 테스트를 직접 실행해서 그 스위트 스포 즉 최적값을 찾으시나요? 어, 실제이 실무 현장에서는 1, 2번으로 하는 경우도 많습니다. 그런데 우리 아키텍트들은 3번과 4번으로 접근하시는 것을 권장드립니다. 자,이 내용을 한번 살펴보겠습니다. 자, 그럼 먼저이 각 백엔드이 언어 진영마다이 DV 코넥션 풀에 대한 라이브러리가 있고 그 라이브러리들의 기본값을 한번 보겠습니다. 자바 같은 경우에는이 스프링부트 2.0부터 부터 시카리 CP가 기본 커식 풀로 재택이 되었죠.
그래서 대부분의 현재 자바리케이션은 히카리시 CP 히카리 풀로 사용하고 계실 거고요. 풀의 맥시멈 풀 사이즈의 기본값은 열 개입니다. 그리고 단넷이 ADO 단넷 내장풀을 사용하죠. 단넷은 단넷의이 기본값은 100입니다. 좀 많은 감이 있죠. 그리고이 노드 JS이 노드 포스트레이 피지풀의 값은 역시 히카리와 같이 열 개입니다. 그리고이 파이썬에 SQL 알케미의 큐풀이 큐풀의 풀 사이즈는 다섯 개고 초과 임시 연결수는 열 개입니다. 그래서 순간 최대 15개까지 가능합니다.이 참고로 단넷이 100개 좀 차이가 많이 나는데요.이 MS 시콜 서브의 기본 맥스 커넥션이 32,000개 정도 됩니다. 아주 크죠?이 이 포스트 그래 SQL의 맥스 커넥션이 100K이고 마이 SQL이 15개인 것에 비해서 굉장히 크죠. 그래서이 마이크로소프트의 시골 서브의 최대 커넥션이 충분히 크니까 어 여유 있게 잡아도 된다는 판단이 깔려 있고요. 그리고 전통적으로이 자바 진영에서는 작게 시작하는 즉 작게 시작해서 넓혀가는 이런 철학을 가진대 비해서이 마이크로소프트 진영은 좀 여유 있게 시작하는 트락을 가졌다는 차이점도 있습니다.
자, 그래서 단넷을 제외하고는 다섯 개에서 15개 범위 이런이 표준 라이브러리들이이 비슷한 수치를 사용하고 있다는 것은이 숫자의 기술적 근거가 있음을 시사하는 것이죠. 그리고 단넷 같은 경우에도 마이크로소프트의 공식 가이드에 기본값을 배 그대로 쓰지 말고 오크로드에 맞게 조정해서 사용하라고 명시하고 있습니다. 즉 안전한 상한선이지 권장되는 값은 아니라는 거죠. 자, 그러면 보통 우리 실무에서 풀 사이즈를 어떻게 사용하는지 대략 예측을 해 보면 보통이 개발 스테이징에서는이 히카리 풀의 기본값을 그대로 많이 사용을 하십니다. 그냥 열 개. 그리고이 소규모 뭐 백엔드 서비스 같은 경우 뭐 열 개값 많이 사용하고요. 그리고 뭐 10열 개에서 20개 정도 이렇게 설정하는 경우들도 있고요. 어, 중규모 정도는 20개에서 30개. 어, 서버 코어가 올라가면이 커넥션 풀수도 조금 올리는 경우가 많습니다. 그리고 트래픽이 많은 경우 30에서 50개. 어, 대규모 부화 테스트로 검증한 후 이런 수치를 사용하기도 하죠.
그런데 이렇게 100개 이상 이렇게 지정하는 것은 안티 패턴입니다. 너무 많아요. 자, 그렇다면 현재 우리 멤버십 여러분들의 서비스는 몇 개로 사용하고 계신가요? 셀프 체크 좀 해 볼까요? 현재 맥시멈 풀 사이즈가 몇 개인가요? 그리고이 데이터베이스 서버의 코어는 몇 개인가요? 코수 그리고 부하 테스트를 해봤을 때 평균 액티브 커넥션은 몇 개였나요? 뒤에서 자세히 알아보겠지만 어 DB코어 곱하기 2라는 표준 공식 있습니다. 어 참고로이 히카리 풀의 위키 벤치마크를 보면이 포스트거리 SQL에서 약 50 커넥션 부근부터 TPS 즉이 처리량 있죠? 처리량이 더 증가하지 않고 이렇게 평탄화 된다는이 테스트가 있습니다. 그리고이 오라클 리얼월드 퍼포먼스 RWP라고 해서이 오라클 데이터베이스 본사의이 성능 엔지니어링 팀인데요. 여기서도이 CPU 코어당 평균 열개 이하를 지정하라고 말하고 있습니다. 자이 페이지가 히카리시피 위키 페이지인데요. 여기 보면 자 그래프가 있죠. 자, 여기 DB 클라이언트 수가 자, 여기서부터 약 50개부터 이렇게 평탄화 된다는 얘기입니다.
그리고 이게이 오라클에서 작성한 문서인데요. 데이터베이스 어플리케이션의 코넥션 전략 여기 부분인데요. 번역을 해 보겠습니다. 자, 여기 데이터베이스 서버에 CPU 코어당 평균 프로세스 수를 10개 이하로 유지할 것을 권정한다라고 되어 있습니다. 연결수는 CPU 코수를 기준으로 해야 하며 코어의 쓰레드 수를 기준으로 해서는 안 된다. 어이 참조 사이트는 제가이 댓글이나 영상 설명에 올려 두겠습니다. 자 그래서 흔한 오행입니다.이 불 크기를 크우면 즉 동시에 이렇게 연결할 수 있는 커넥션 개체를 많이 만들면 처리량도 늘어나겠죠라고 오해하시는 분들이 가끔 계십니다. 다시 말해서 일꾼이 많으면 일이 더 빨리 끝난다. 이렇게 직관적으로 보면 맞는 얘기 같은데요. 근데이 데이터베이스에서는 정 반대로 작동할 때가 많습니다. 커넥션 수가 일정수를 넘기면 처리량은 오히려 떨어진다. 다시 말해서 커넥션을 늘릴수록 시스템이 일을 더 못 한다. 아까 봤던이 오라클 문서에서도 커넥션을 줄이면 CPU 부담이 줄고 처리 늘어난다라고 말하고 있습니다.이 오라클 문서를 다시 볼까요?
여기 있죠. 연결수를 줄이면 CPU 보화가 줄어들어 응답 속도가 빨라지고 처리 증가한다라고 명시하고 있습니다. 역설적으로 볼 수 있지만 성능 향상은 다음과 같은 이유로 발생한다라고 해서 어떤 경합 문제가 줄어들고 뭐 캐시 일관속 문제도 줄어들고 자이 문서는 한번 읽어 보시길 권장드립니다. 자 그래서 어이 전형적인 TPS 그래프죠. 쭉 올라갔다가 즉이 커넥션 격체가 늘어날수록 처리량이 쭉 올라갔다가 어느 시점부터는 어 평탄화 되거나 오히려 떨어질 수도 있다라는 것이죠. 예전에 우리 TPS 강의할 때이 그래프 보셨죠? 자 이거죠. 예전에 TPS 영상에서 동시 소속자가 늘어날수록 쭉 처리량이 늘어나다가 어느 지점부터는 처리량이 더 이상 늘어나지 않죠. 그리고 응답 시간은 오히려 이렇게 엄청나게 증가하기 시작하죠. 자,이 그래프가 동일한 메커니즘입니다. 자, 그러면 이제 본격적으로이 풀 크기를 어떻게 설정하는게 좋을지 한번 알아보겠습니다. 자, 여기 공식을 한번 보시죠. 풀 사이즈가이 코어의 수에 곱하기 2. 그리고 스핀들 카운트.
자,이 공식은이 포스트레 SQL 위키에서 출발했습니다.이 수많은 벤치마크에서 경험적으로 수렴된 공식이라고 하는데요. 자,이 페이지가이 포스클의 SQL의 위키입니다. 자, 여기 밑에 보시면 자, 번역을 해 볼게요. 자, 여기 있죠?이 이 수년간 다양한 벤치마크에서 상당히 정확한 것으로 입정된 공식은이 최적의 처리량을 위해서 활성 연결수가 코어 개수 곱하기 그리고 거기에 유효 스펜드 개수를 더한다. 이렇게 공식이 나와 있습니다.이 히카리 CP 공식 가이드에서도이 값이 다른 데이터베이스에도 대체로 적용 가능하다라고 명시하고 있습니다. 그래서이 백엔드 진행 표준 출발점으로 받아들여지고 있는 공식이죠. 자,이 페이지가 아까 봤던 히카리 풀의 위키 페이지인데요. 여기도 보면 자, 이렇게 코넥션 수가 코어 곱하기 그리고 스피드 카운트라고 똑같이 되어 있죠. 그래서 풀 사이즈를 지정할 때이 공식을 기준 시작점으로 보시면 됩니다. 자, 먼저이 코수부터 한번 보시죠. 데이터베이스의 물리 CPU의 코수라고 되어 있습니다.이 물리 코수의 곱하기 2가 출발점입니다.
참고로이 하이프 쓰레딩은 제외해야 합니다. 예를 들어서 8코어의 16스레드 CPU라면 여기 있는 물리 코어만 코어 카운트에 대입을 하는 거죠. 다음으로 여기 디스크 회전축 수인데요. 어이 수치는 옛날에이 하드디스크 HDD를 떠올리시면 됩니다.이 하드디스크 안에는이 자석 디스크 즉 플래티가 회전하면서 데이터를 읽고 쓰는데 그 회전축이 스핀들입니다. 만일에이 하드디스크를네 개 레이드로 구성했으면 스핀들 값이 4가 되어서 4를 더해 주는 것인데요. 그 이유는이 디스코 아오 대기 동안에 비어 있는이 CPU 자리를 추가적인 커넥션에 들어와서 일을 할 수 있도록 하기 위함입니다. 다만 요즘에는 데이터베이스 서버에 HTD는 잘 안 쓰죠.이 이 SSD나이 MVME SSD를 사용하는데요. 이렇게 요즘이 MVME 환경에서는 회전축 자체가 없고 IO 대기도 거의 없어서이 스핀들 카운트는 0에 가까운 수로 보면 됩니다. 그리고 데이터가 메모리에 다 캐시되 있을 때도 마찬가지로이 스핀들 카운트를 0으로 보시면 되고요. 그래서 요즘이 MVM 환경에서는요 스핀들 카운트는 의미가 없고 코어 카운트 두 개 이것을 풀 사이즈의 시작점으로 잡으시면 됩니다.
자, 다시 한번 말씀드리지만이 공식은 포스트레 SQL 커뮤니티에서 널리 알려진 경험칙 시작점입니다. 무조건이 값으로 설정해라가 아니라이 값을 시작점으로 해서 보화 테스트를 통해서 조정해 나가야 된다는 것이죠.이 이 포스트 그리 위키에서도이 값은 시작값일뿐 실제 스위스팟 즉 최적값은 보화 테스트로 찾아야 한다라고 언급하고 있습니다. 어 그리고 참고로이 엄밀하게 말하면 포스트레 SQL 위키의 공식은이 활성 커넥션 수에 대한 겁니다. 그런데이 활성 커넥션수는 그 상황인이 풀 사이즈 즉 맥시멈 풀 사이즈가 정하기 때문에이 풀 사이즈를 스위스팟에 맞추면이 활성도 자동으로 그 안에 머무르게 되죠. 그래서 실무에서는이 공식을 맥시멈 풀 사이즈 가이드로 활용하면 됩니다. 어, 참고로 앞서 봤던이 오라클의이 RWP 그룹은 코어당 한 개에서 열 개까지 지정하라고 했는데요.이 하은이 포스트 SQL 공식보다 더 작고 상하는 코당 열 개 그러니까 더 크죠. 그래서 거기서는 환경별 유연성을 감안한 가이드입니다. 자, 그리고 여기 아래 보면 또 다른 공식이 하나 있습니다.
자,이 공식인데요.이 공식도 시카리시피 문서에 나와 있는 공식인데요.이 공식은 내드락을 회피하기 위한 최소한의 연결수를 안내하고 있습니다. 여기서 TN는 동시레드 수이고요. CM은 한 레드가 동시에 잡아주는 커넥션 수입니다. 그래서 하나의 요청이 커넥션을 여러 개 동시에 잡고 있는 코드이 중첩 트랜잭션 같은 거죠. 이런 코드에서 데드락을 피하기 위한 최소 값이라고 보면 됩니다. 예를 들어서 동시 쓰레드수가 4이고 풀 사이즈가 4라면네 개의 쓰레드가 각각 첫 커넥션을 한 개씩 받아갈 겁니다. 그러면 풀에는 커넥션 객체가 없겠죠. 그런데 이때 특정 스레드가 다른 커넥션을 필요로 하게 되면 커넥션 풀에는 더 이상 커넥션 객체가 없기 때문에 영원히 대기하게 되겠죠. 그러면 대들하게 걸릴 수 있다는 거죠. 그래서이 공식은 하나의 쓰레드만이라도 완전하게 일을 끝낼 수 있도록 하면 되드락이 풀린다는 원리를 가지고 있습니다. 그렇지만 요즘 대부분이 일반적인 어플리케이션들은이 CM 즉 하나의 스레드가 동시에 점류하는 최대 커넥션 수가 대체로 하나죠.
그렇게 되면 여기이 값이 0이 되어서 커넥션 수가 1이 됩니다. 즉 의미가 없어지죠. 자, 여기 그 내용이 있죠. 그래서이 공식은 풀 사이즈를 지정할 때 사용한다기보다는 데드락이 발생했을 때 진단독으로 사용하는 공식으로 보시면 됩니다. 그래서 실제 우리 실무에서는 여기 있는이 공식이 CPU 코어 곱하기 2이 공식을 기준점으로 잡으시면 됩니다. 자, 어떤가? 여러분이 현실 우리 개발자분들 중에서는이 공식을 미리 알고 기준점으로 사용하는 분들도 계시고요. 대충 코수의 두 배 정도라고 알고 계신 분도 계시고요. 아니면이 공식 자체를 모르고 기본값 우리 히카리 풀은 열 개였죠. 기본값이나 아니면 그냥 직감적으로 좀 많이 잡거나 하는 분들도 많이 계시고요. 그래서이 공식은 인지도는 높지만 정확한 계산으로 실제 적용까지 하는 비율은 그렇게 많지는 않은 것 같습니다. 자 그러면이 공식의 각 항을 조금 더 자세히 볼까요? 자, 다시 한번 공식을 보면이 CPU 물리적인 코어 곱하기 2 그리고 스핀들 수입니다. 첫 번째 왜 코어 곱하기 2인가?이 수학적으로 정확히이어야 한다는 증명이 따로 있는 것은 아닙니다.
다만 수년간 다양한 벤치마크에서 잘 들어맞는 경험치라고 하는데요. 다만 추측해 보면 이렇습니다.이 데이터베이스 코리는 보통이 두 단계를 거치죠. CPU 작업과 IO 대기 이게 번갈라 일어나죠. 즉 CPU 계산했다가 IO 대기하다가 또 CPU 처리하다가 IO 대기하다가 그래서이 io 대기 시간 동안 코어는 놀고 있기 때문에 다른 콜이 하나를 더 끼워 넣으면 CPU를 100% 가까이 활용할 수 있다는 전제입니다. 즉 아유 대기 동안 코어가 놀지 않도록 한 콜이 여유분을 더 둔 것이죠. 그렇다고 해서 곱하기 2가 아니라 뭐 곱하기 3, 4 이렇게 너무 많이 하게 되면이 쓰레드 교체에 따른 컨텍스트 스위칭 비용 그리고 CPU 캐시2 캐시이 캐시 무효화에 따른 비용 그리고 쓰레드가 내부락 경쟁 비용 때문에 너무 많이 하는 것도 안 좋은 거죠. 그래서이 곱하기가 최적값인 이유는 IO 대기를 채우기엔 충분하지만이 컨텍스트 스위칭과 캐시 비용을 일으킬만큼 많지는 않은 비율이기 때문이죠. 자, 그리고 왜 하이프스레딩은 빼는가?이 이 하이퍼 스트레딩이 만드는이 논리적인 코어는이 물리 코어가 아니죠.
즉 진짜 연산 자원이 아니라는 말씀입니다.이 DV 작업처럼이 메모리 접근이 빈번하고이 캐시 미스가 많은 그런 작업에서는이 하이프 슬레딩 효과가 크지 않습니다.이 두 개의 하이프 쓰레딩 쓰레드가 같은 캐시를 두고 경쟁하면서 오히려 성능이 떨어지기도 합니다. 그래서 앞서 말씀드린 대로 8코어의 16레드 CPU일 경우 쓰레드 하이프 스레딩은 감안하지 않고 물리코어수만 계산해서 곱하기 1을 해 주는 겁니다. 그리고 세 번째 스핀들은 뭔가? 앞서 말씀드린 대로 하우드디스크의 물리 디스크 회전축입니다.이 HDD 시대에 동시에 디스크를 회전시키면서 읽기 서기를 할 수 있는이 물리 디스크의 스핀들 개수인데요.이 HDD가 한 개일 땐 스핀들이 안 하고이 레이드 구성으로네 개의 디스크 어레이가 있다면 스핀들이네 개인 거죠. 반면 메모리의 데이터가 다 들어가 있다면 스핀들은 0 개인 거죠. 디스크를 잃지 않으니까. 그러나 이것은 HDDCD대의 잔재입니다. 요즘이 SSD, MVM이 SSD에서는이 회전축의 개념이 무의미하죠.
그래서이 값은 0 또는 0으로 가까운 값으로 간주하면 됩니다. 그리고이 공식은 앞서 말씀드린 대로이 포스트의 SQL 공식 위키에서 언급된 공식입니다. 수년간 누적된 벤치마크에서 경험적으로 수렴된 값이니까 신뢰할 만한 값입니다. 결론적으로 2026년 현실에는 대부분 우리 데이터베이스의 디스크는 HDD를 사용하지 않고 MVM이 SSD를 사용하기 때문에 스핀들 값을 0으로 주면 됩니다. 그래서 사실상 공식은 이렇게 풀 사이즈는 CPU 물리코수 곱하기 2 이렇게이 공식을 출발점으로 보시면 되겠습니다. 자, 그러면 커넥션이 많아질수록 느려지는 이유를 한번 보겠습니다. 자, 여기 USL 유니버셜 스퀘어 레벨리티로 보편적인 확장성 법칙이라고 하는데요.이 시스템에 부활를 늘릴 때 처리량이 어떻게 변하는가를 수학적으로 모델링한 법칙입니다. 다시 말해서 시스템이이 사용자수 또는 스레드 수 증가에 따라서 왜 선형적으로 늘지 않고 한계가 오는지 설명하는 성능 확장 모델인데요. 동시 처리 단위 N을 늘릴수록이 자원 경쟁과 일관선 비용이 누족되어서 어느 시점부터는 처리량이 오히려 감소한다는 법칙입니다.
우리가 이전 강의 TPS에서이 시츄레이션 포인트가 바로이 지점에 해당하는 거죠. 자, 또 보시면이 지점인 거죠. 자, 그래서 구체적인 이유를 하나씩 보면이 커넥션 수가 많아지면 컨텍스트 스위칭 비이 복정합니다. CPU 코어가 여덟 개인데 동시에 일하는 쓰레드가 200개라면 CPU는 일을 안 하고이 쓰레드를 바꾸느라고 시간을 다 쓰겠죠. 그리고 쓰레드가 교재될 때이 CPU LN L2 캐시도 무효화되어서 메모리 접근이 또 늘어나죠. 두 번째 락 경쟁 증가입니다.이 같은 테이블, 같은 행을 노리는 쓰레드가 많아질수록 락 대기 시간이 늘어나죠. 그래서 경우에 따라서는 처리 시간보다이 대기 시간이 길어지는 역전 현상이 발생하기도 합니다. 마지막으로 캐시 효율 저하입니다.이 많은 커넥션이 각자 다른 데이터를 읽으면 데이터베이스에이 버퍼 캐시 메모리 캐시가 빠르게 교체되어야 하죠. 그러면 캐시 미스가 늘어나기 때문에 디스크 아이오가 또 그만큼 증가하게 되는 것이죠. 자, 이런 이유들이 커넥션이 많아질수록 오히려 속도가 느려지는 이유들인데요.
핵심은 이겁니다. 동시에 일하는 커넥션은 CPU가 처리할 수 있는 양만큼만 의미가 있다.이 말은이 DV 커넥션 풀에만 해당되는 개념은 아니죠. 우리 슬레드 풀이나 뭐 HTTP, 클라이언트 풀, 기타이 프로세스 풀들이 모든 종류의 풀이이 비슷한 원리로 작동합니다. 풀을 아무리 키워도 물리 자원의 처리 능력 이상으로는 처리량이 늘어나지 않죠. 사실 이것은이 컴퓨터 아키텍처의 본질에서 오는 거라서 풀 사이징은 하나만 이렇게 개념적으로 알고 있으면 평생 쓸 수 있는 지식이 되는 거죠. 자, 그러면 우리가이 성능이 안 나올 때 정말로이 풀의 커넥션이 부족한지 아니면 코리가 느린지를 생각해 봐야 됩니다. 앞서이 TPS 공식 있었죠? 우리 예전 TPS 강의에. 자,이 공식인데요. TPS는 동시 접속자를 평균 응답 시간으로 나눈 거죠. 자, 데이터베이스로 오면 동시에 접속자수가이 활성 커넥션 수죠. 커넥션 객체수. 그것을 코리 실행 시간으로 나눈 거죠. 리틀의 법칙 그대로입니다. 자, 여기서 우리가 풀을 16개로 설정했다고 가정합니다.
그리고 부화 테스트로 확인을 해 보니까 활성 커넥션 수가 평균 14개입니다. 그리고 컬이 실행 시간은 50mms입니다. 그리고 실측 TPS는 280이 나왔다고 가정해 보겠습니다. 자, 여기서 활성 커넥션이 14개고 코리가 50ms니까 0.6 용호 이렇게 하면 280이 나오죠. 즉 이론적인 값과 실적 값이 이렇게 거의 같다고 가정을 하고 있습니다. 그리고 이때이 풀 사이즈가 맥스 풀 사이즈에 거의 도달을 했죠. 거의 90% 가까이 커넥션을 사용한 겁니다. 자, 이런 상황에서 처리량을 늘리려면 어떻게 접근할까요? 자, 먼저 DB 코어에 한 개에 도달한 경우입니다.이 활성 커넥션 수가 데이터베이스 코어 곱하기 2 건처하면 이때는이 풀을 늘려도 앞서 봤던 그 USL 법칙에 따라서 처리량이 더 증가하지 않죠. 오히려 평탄해지거나 줄어들 수 있죠. 그래서 이럴 때는 코리의 응답 시간을 줄이는게 답일 수 있습니다. 반면에이 데이터베이스 서버에 코어수가 여력이 있을 경우 활성 커넥션이 더 늘어날 여지가 있는 거죠. 즉 풀의 맥스 풀 사이즈를 확장하면 되는 거죠.
그래서이 처방은 먼저이 쿼리의 실행 시간을 만일에 이렇게 절반으로 줄일 수 있다면 처리량도 배로 늘어나죠. 그다음에 코어에 여력이 남아 있으면 풀의 맥스 풀 사이즈 확장도 함께 검토하는게 좋습니다. 자, 핵심은이 리틀 슬로우가 풀 크기를 정해 주는 공식이 아니라이 풀 부족과 코리 부족을 구별하는 진단 도구라는 점입니다.이 풀 사이즈를 무조건 느리기 전에이 코리 튜닝 그리고 인덱스, 캐시 등을 사용해서 데이터베이스의 응답을 빠르게 하면 처리량은 그 배수만큼 늘어날 수 있다는 거죠. 자, 그러면 시나리오를 하나 만들어서 적용해 보겠습니다. 자, 데이터베이스 서버가 8코어 단일 로드인 경우입니다. 자, TV 사용이 데이터베이스 CPU, 물리 CPU가 8코 그리고 디스크는 SSD입니다. 그리고 충분한 램이 있고요. 그리고 트랜잭션 패턴은 하나의 요청이 하나의 커넥션입니다. 그리고 P95 코리 시간 즉 95%의 코리 시간은 50mm입니다. 그리고 목표 TP에서는 300. 그리고 왓스는 단일 즉 한 대라고 가정을 하겠습니다.
자, 이런 상황에서이 처리량 공식으로 시작점을 잡아 보겠습니다. DB코가 여덟 개니까 8 * 2 그리고 SSD에 충분한 램이 있다고 했으니까 스핀들은 0으로 보겠습니다. 그렇게 해서 첫 시작은이 공식에 따라서 맥스 풀 사이즈를 16개로 시작합니다. 그리고이 리틀 슬로우로 처리 능력을 검정합니다. 자, 커넥션 16개를 50mms으로 나눕니다. 그렇게 하면 처리량의 이론적인 상한는 320 TPS가 나옵니다. 그런데 앞서 목표 TPS가 300이었죠. 우리가 보통 이렇게 이론적인 상한이 나오면이 값에 한 80% 정도를 TPS로 잡는데요. 320에 80%를 잡으면 256 TPS가 됩니다. 이것은 목표 300 TPS보다 다소 따뜻한 수치죠. 그래서 우리는이 시작값 26으로 시작해서 무화 테스트를 하면서 최적점을 탐색해 나가야 합니다. 자, 풀의 맥시멈 풀 사이즈를 16으로 지정하고이 히카리 풀의 매트릭 즉 액티브 웨이팅 매트릭을 모니터링하면서 단계적으로 조정을 해 나가야 된다는 말입니다. 자, 이때이 목표 TPS이 300을 도달하지 못했을 때 이런 절차로 처리량 증가를 꾀합니다.
첫 번째 코리 그리고 인덱스 최적화 등으로이 응답 시간 즉 P95%의 응답 시간인 50m를 단축시킵니다. 코리들을 검토를 해야 된다는 거죠. 그다음에이 16으로 설정한이 풀 사이즈를 18에서 20까지 점진적으로 확장을 해 봅니다. 자, 이렇게 했는데도 TPS 300을 달성하지 못한다면 데이터베이스 자원 정서를 고려해야 합니다. 코어를 추가하거나 리플리카를 활용하거나. 자, 이렇게 단일로드 8코어 기준으로 우리가 목표 TPS를 어떤 식으로 달성할지 그 시나리오를 한번 말씀드려 봤습니다. 근데 우리 실무에서는이 단일 와스 환경이 아니죠. 대부분 와서를 두대 이상 사용을 하죠. 이때 주의할 점은이 와스 별풀을 곱하면 안 됩니다. 자, 8코어 데이터베이스에 공식을 적용하면 맥시멈 풀 사이즈는 16이라 그랬죠. 그런데이 16값을 와스가 내 있다고 가정했을 때 각각의 와스에 적용을 해 버리면 어떻게 됩니까? 전부 다 합치면 총 64개가 되죠.이 데이터베이스가 16개 감당할 수 있는데 64개는 감당할 수 있는 양의 네배가 되는 거죠.
가끔 이런 실수를 합니다.이 공식을 적용하려고 했더니 와스에 그 부분을 지정을 해 놓고 처음에 한 대로 출발했다가 확장시킬 때 그 부분을 깜빡하고 와스가 모두 16개 불을 지정해서 사용하는 거죠. 자, 만일에 이렇게 잘못 설정된 경우에 많은 트래픽이 나와서 데이터베이스 커넥션 수가 왔다 거의 풀로 차게 되면 아까 말씀드린 그런 커넥션이 너무 많아서 오히려 성능이 떨어질 수도 있고요. 그리고 데이터베이스에이 맥스 커넥션이라는 수치가 있는데 이것을 만일에이 풀 사이즈의 커넥션 개수가 증가하게 되면 바로 오류가 나 버리겠죠. 그래서 이론적으로는 이렇게 설정합니다. 8코어 DB 서버의 총량 16개를 총 와스 인스턴스에 분배를 하는 거죠. 적코 곱하기 2 나누 와스 수를 하는 거죠.이 이 경우라면 8코 16개 나누기 4 즉 각 와스마다 풀 사이즈를네 개씩 설정하는게 이론적으로 안정적인 값인데요. 그러나 현실적으로는 이렇게 단순히 나누기 n을 해서 분배를 하면 한 대가 장애가 났을 때이 다른 왓스가 부담을 떠앉는 위험이 있습니다.
그래서 약간의 여유는 두대이 합계가 db코어 * 2을 크게 넘지 않도록 하는 것이 좋습니다. 자, 그래서 데이터베이스를 보호하는게 우선이다. 그러면 앞서 말씀드린 대로 각 와스가네 개씩만 설정을 하고 어 가용성이 우선이다 그러면 각 와스별로 다섯 개 혹은 여섯 개를 설정합니다. 이렇게 하면 총네 대기 때문에 커넥션은 20개에서 24개 한 대가 장애가 나더라도 괜찮은 거죠. 여기서 의사 결정의 핵심은 무엇을 우선할 것인가입니다.이 보수적으로 가면네 개씩 총 16개 DV보가 우선일 때 선택한다고 했죠. 가용성 우선이면 대여섯 개씩 한대 장애를 견디는게 우선일 때 선택하는 겁니다. 이렇게 하면 DB 부담은 살짝 늘지만 와스 한 대가 다운데도 나머지 와스가 여유 있게 처리를 할 수 있게 되는 거죠. 여러분의 서비스가 무엇을 우선하냐에 따라서 결정을 하시고 여기 나와 있는 것처럼 실제 값은 부하 테스트로 검증을 해야 된다는 것입니다. 어 참고로이 오토 스케일링 환경도 많죠. 요즘 이럴 때는이 파수가 동쪽으로 변하면이 매번 풀 사이즈를 거에 맞춰서 수동으로 변경하기는 힘들죠.
자, 이럴 때는이 피지 바운스와 같은 외부 풀러를 사용하는 것이 좋습니다. 자, 그런데 한 가지 높심에서 말씀을 드리자면 앞서 우리가 이렇게 와스가 내일 때 각 와스별로네 개씩 혹은 가용성 우선이라면 대여섯 개씩 설정하라고 했었는데요. 어,이 값을 적용하기 전에 반드시 측정을 먼저 해야 됩니다. 자, 지금 시스템이 잘 돌고 있는데 오늘이 값을 들었다고 해서 바로 풀 사이즈를 줄이려고 접근하시면 안 됩니다.이 이 풀을 축소하는 것은 풀을 확정하는 거보다 위험할 수 있습니다. 트래픽이 폭정하면 적각 장애로 이어질 수 있는 거죠. 그래서이 현재 잘 돌아가고 있는 시스템이 있다 그러면 평균 액티브 커넥션을 측정을 해야 됩니다.이 각 와스 서버에이 히카리시피 매트릭들이 있죠. 피크 시간대에 이런 액티브 값들을 확인을 합니다. 그리고 그렇게 측정된 값을 기준으로 방금 우리가 알아봤던이 16에서 20이라는 풀 사이즈 적용을 할지 판단을 합니다. 자, 다시 말해서 1번에서 측정했던이 값,이 각 와스의 평균 액티브 커넥션 수이 수를 그 와스의 풀 사이즈로 나눴을 때 25% 이하라면 예를 들어서 풀이 10개였는데 액티브 풀이 2.5개 목에 이하라면 앞서 우리가 알아본 대로 풀 축소를 해도 안전합니다.
그러나 25에서 65%를 이미 사용하고 있으면이 신중이 적용을 해야 되는 거고요. 지금 현재 60% 이상 사용하고 있다 그러면 서플리 풀 사이즈를 줄이지 마세요. 한 번에 다 적용하는게 아니라 단계적으로 적용하고 모니터링을 해 가면서 단계적으로 적용을 해야 됩니다. 그리고 만일 적용할 때도 즉시 롤백 가능한 상황을 준비해 두는 것이 필요합니다. 오늘이 강의의 가이드가 지금 당장 현재 시스템들을 다 수정하라고 하는게 절대 아닙니다. 잘 동작하는 시스템은 건들지 말자라고 하는게 우리 기본적인 운영의 황금 누이죠. 다만 오늘 가이드를 적용하실 곳은 두 가지. 첫 번째이 처리량이 자원 대비 떨어져서이 트러블 슈팅이 필요할 때 그 진단 기준으로 활용하면 좋습니다. 두 번째이 신규 시스템을 새로 구축할 때 우리가 이런 기준점을 가지고 출발하면 좋은 거죠. 자, 다음으로이 데이터베이스에 맥스 커넥션이라는 설정이 있습니다. 자,이 DB에 맥스 커넥션의 수를 커넥션 풀 사이즈가 넘으면 안 됩니다. 다시 말해서 모든 와스의 커넥션 풀 사이즈의 합산이 데이터베이스의 맥스 커넥션보다 크거나 같으면 장애가 발생할 수 있다는 거죠.
참고로 포스트레 SQL의 맥스 커넥션의 기본값은 100개죠. 근데 여기서 우리가 시스템 예약 일부를 빼고 관리자 접속 부분을 빼면 가용할 수 있는 커넥션 수는 90개 정도로 보셔야 됩니다. 그래서이 와스들의 전체 풀 사이즈 합산이이 데이터베이스의 맥스 커넥션 즉 앞서 100개에서 90개 예 90개 곱하기 여기서도 안전 마진으로 0.8 정도 곱해서 그 수치보다 작아야 된다는 것이죠. 참고로이 AWS RDS에서도 이렇게 가이드하고 있어요. 맥스가 500이면이 풀러는 400으로 설정하라고. 자, 장애 시나리오를 보시죠. 와스가 다섯 대인데 맥스 풀 사이즈가 30개로 각각 지정을 했다고 생각해 봅시다. 그렇게 되면 모든 와스를 통틀어서는 합계가 150개죠. 이것은 데이터베이스의 맥스 커넥션 100개를 초과해 버린 거죠. 이때 장애는 고정풀 크기일 때는이 애플리케이션이 시작할 때 즉시 오류가 나죠. 즉 파드가 시작할 때 실패하게 됩니다. 그리고 동적 풀일 경우에는 트래픽이 폭증해서이 커넥션 수가 100개 이상 도달할 때 장애가 발생하겠죠.
참고로 고정 풀이라는 것은 풀 사이즈의 최소값과 최댓값이 같은 겁니다. 동쪽 풀은 최댓값보다 최솟값을 작게 해서 동적으로 증가할 수 있도록 해 놓은게 동적 풀이고요. 어, 그리고이 데이터베이스의 맥스 커넥션을 그냥 올리면 안 되나요? 이렇게 생각할 수도 있는데요. 이론적으로는 가능할 수 있겠지만 한계가 있죠. 앞서 말씀드린 대로이 포스트 SQL은 프로세스 기반 구조라서이 커넥션마다 수메에서 수십MB의 메모리를 잡아먹게 됩니다. 컨텍스트 스위칭 비용도 누적되게 되죠. 그래서이 맥스 코넥션을 정설해야 될 일이 있으면이 맥스 커넥션을 정설하기보다는이 바운서와 같은 중간에이 풀러를 두는 것을 권장합니다. 자, 이번에는 실무에서 마주치는네 가지 함정을 보겠습니다. 자, 첫 번째롱 트랜잭션입니다.이 트랜잭션 안에서 외부를 호출하거나 무거운 계산 등을 하면이 커넥션 점류 시간이 길어지죠. 공식에 맞게 풀 사이즈를 지정했더라도 이런 긴 트랜잭션이 있으면 풀이 고갈될 수 있습니다. 그래서 트랜잭션의 길이는 최대한 짧게 트랜잭션 안에 외부 호출이 있으면 밖으로 빼기를 권장드립니다.
그리고 유효 커넥션 타임아웃 미스매치입니다.이 히카리 CP의 맥스 라이프 타임이라는 설정이 있는데요.이 이 값이 데이터베이스의 아이들 타임아웃보다 길게 되면이 데이터베이스가 먼저 끊어 버린이 커넥션을 풀이 그대로 가지고 있다가 나중에 사용하려고 할 때 오류가 발생할 수 있습니다.이 히카리 풀의 맥스 라이프 타임은 풀에 있는 커넥션의 최대 수명을 지정하는 것인데요. 기본값은 30분입니다.이 커넥션을 만든지 30분이 지나면 풀에서 제거하고 새 커넥션으로 교체해라는 의미고요. 이것은 풀이 자체적으로 커넥션을 주기적으로 깨끗하게 관리하기 위한 설정인데요.이 값이 DV 아이들 타임아웃.이 이 DB 아이들 타임아웃은 DB가 클라이언트와 연결된 세션이 일정 시간 동안 아무런 활동이 없을 때 그 세션을 DB 차원에서 강제로 끊어 버리는 것을 말하거든요. 뭐 참고로이 포스트 SQL은이 값이 0입니다. 제한이 없다는 것이고요. 바이스QL은 8시간 아주 길게 설정되어 있긴 합니다. 그런데 가령이 히카리 CP의 맥스 라이프 타임아웃이 30분이고이 DV 아이들 타임아웃이 10분으로 설정된 환경이라면 데이터베이스 쪽에서 유주 상태로 10분 후에 먼저 끊어 버렸는데 커넥션 풀은이 사실을 모르고 있다가 실제로이 죽어 버린 커넥션을 사용해서 DB 코리를 시도할 수 있게 되는 거죠.
그렇게 되면 오류가 나는 거죠. 근데 앞서 말씀드린 대로이 포스트의 SQL은이 아이들 타임아웃이 무제 아니고 마스QL은 8시간이라고 했잖아요. 그래서 대부분 문제가 되진 않죠. 그런데 실무에서이 함정이 자주 나오는 이유는 데이터베이스 앞단에 다른 레이어가 끼어 있기 때문입니다. 다른 계층이 끼어 있기 때문에 예를 들어서 PG 바운서를 추가했다 또는 RDS 프록시를 도입했다. NLB를 거친다.이 순간부터는 히카리 CP의이 맥스 라이프타임 30분이 그 중간에 끼어든 계층들의 더 짧은 타임아웃과 충돌할 수 있다는 거죠. 가장한 케이스가이 PG 바운서입니다. 서브 아이들 타임아웃 기본값이 10분이라서이 시카리 CP의 기본값 30분과 미스매치가 즉시 발생합니다. 그래서이 외부 풀러나 프록시를 도입하면 맥스 라이브 타임을 무조건 점검해 줘야 합니다. 히카리시피 기트업 리드미 원문에서도 데이터베이스나 인프라가 부과하는 어떤 커넥션 시간 제안보다도 몇 초 짧게 설정을 하세요라고 공고하고 있습니다. 자, 우리는이 맥스라이프 타임을 데이터베이스의 아이들 타임보다 혹은 그 중간 계층에 아이들 타임보다 30초 이상 짧게 설정하는 것을 권장드립니다.
자, 그리고 CM이 1 이상인 코드입니다. 앞서이 데드락을 피하기 위한 커넥션 수, 최소하는 커넥션 수 공식을 봤죠. 한 메드 안에서 여러 커넥션을 동시에 점유하는 패턴. 이런 패턴이 있다면 풀 크기를 키우는 것보다 코드 구조를 고치는게 우선입니다. 트랜잭션을 분리하거나 JTA를 활용하거나. 그리고이 커넥션 누수 잡기입니다.이 릭디텍션 스트레스 홀드 값을 이렇게 60초로 설정을 해 두면 풀에서 나간 커넥션이 60초 이상 반환되지 않으면 로그로 알려 줍니다. 저 커넥션 누수를 알 수 있는 거죠. 자, 다시 한번 말씀드리지만 풀 크기를 키우면 해결되겠지라는 섣불은 처방보다는 대부분 풀의 고갈은 풀 크기 문제가 아니라 커넥션 점류 시간의 문제일 수 있다는 점을 기억하시기 바랍니다. 자, 오늘의 핵심 다섯 가지입니다. 첫 번째 커넥션 수가 많다고 좋은게 아니다. 말씀드렸죠? 컨텍스트 스위칭, 락 경쟁, 캐시 교체 이런 것들로 인해서 일정수를 넘어가면 더 이상 처리량이 오르지 않습니다. 두 번째 물리적인 코스 곱하기 2 그리고 스핀드리게스 우리 풀 사이즈 사이징의 출발점입니다.이 공식을 시작값으로 해서 보화 테스트로 스위스팟을 찾으시기 바랍니다.
다음으로 이틀 스로우로 검증한다. TPS는 활성 커넥션 나누기 커리 실행 시간이라는 공식을 사용해서 커리 실행 시간부터 줄여서 TPS를 올리는 것을 먼저 시도해 보시기 바랍니다. 그리고 풀 사이즈는 작게 시작해서 측정하면서 늘려 나가는 것을 권장합니다. 임의의 큰 가수로 시작하지 말고이 아까 앞서 봤던이 시작값에서 출발해서 보화 테스트를 통해서 적정값을 찾으시길 권장드립니다. 그리고롱 트랜잭션이 진짜 적입니다.롱 롱 트랜잭션을 유발하는 모든 것을 제거하시기 바랍니다. 자, 커넥션을 늘려도 처리량이 안 드러나는 시점이 우리 시스템의 한계점이다. 자,이 그래프 아시죠? 자, 여기이 세츄레이션 포인트가 한계점이라는 거죠. X의 수를 아무리 늘려도 처리량은 더 이상 늘지 않는 지점인 거죠. 자, 우리 멤버십 회사에 출근 후 바로 점검할 여덟 가지를 말씀드리겠습니다. 첫 번째 맥시멈 풀 사이즈는 DB서 서브의 물리코어 곱하기 2부터 시작하고 있는지 확인 한번 해 보시길 바랍니다. 임의 값 50, 100 이렇게 넓게 설정한 건 아닌지 한번 확인해 보세요.
그리고 고정 풀로 운영하세요. 리가리 풀 기준으로이 미니멀 아이들 값과 맥시멈 불 사이즈 값을 갖게 해서 런타임의 풀 변동 오버헤드를 줄이십시오. 어, 다른 풀은요 설정이 미니멈 풀 사이즈일 수도 있습니다. 즉 최소 풀 사이즈와 최대 풀 사이즈를 갖게 하라는 거죠. 자, 그리고 코넥션 타임아웃은 뭐 기본값을 유지하시고요. 너무 길면 오히려 안 좋습니다. 그리고 앞서 말씀드린 대로이 커넥션 누수를 방지하기 위해서이 값을 지정해서 로그를 확인하시는게 좋습니다. 그리고롱 트랜잭션은 가장 큰 척입니다.이 트랜잭션 안에 불필요하게 길어지는 모질이 있다면 걷어내십시오. 가장 흔한 풀 고갈의 원인입니다. 그리고 풀에 이런 매트릭들을 볼 수 있는 대시보드를 만드시길 권장드립니다. 그리고 데이터베이스의 맥스 커넥션 수보다이 왓스의 인스턴스 수와이 맥스풀을 곱한 수가 더 크면 안 된다고 했죠.이 이 값을 초과할 때는이 PG 바운서 같은 외부 풀러 도입을 검토해 보시기 바랍니다. 그리고 마지막으로이 부하 테스트를 통해서이 세츄레이션 포인트 즉 처리량이 꺾이는 지점을 찾기 바랍니다.
불 크기를 바꿔 가면서이 지점을 찾아내는 거죠. 자, 멤버심 여러분 늘 감사합니다.이 오늘 강의가 여러분의 아키텍트 영향에 작은 도움이 되었기를 바랍니다. 여러분들의 성장이이 채널에 가장 큰 보람입니다. 더 좋은 내용으로 다시 찾아뵙겠습니다. 수고했습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 YouTube 코딩하는기술사 (개발/IT)의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기