반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 생각일기
- Grafana
- 생각로그
- mysql
- 회고
- 기록
- 알고리즘
- 리눅스
- WIL
- next.js
- js
- Java
- javascript
- 코테
- til
- Git
- 생각정리
- MongoDB
- nest.js
- array
- typescript
- 트러블슈팅
- CS
- mongo
- 자바스크립트
- 주간회고
- react
- mongoose
- 네트워크
- 피드백
Archives
- Today
- Total
코딩일상
Spring Boot HikariCP 본문
반응형
Spring Boot HikariCP & R2DBC 커넥션 풀 총정리
1️⃣ HikariCP 역사와 도입 배경
- 초기 Spring Boot / Spring에서는 기본 커넥션 풀로 Commons DBCP, C3P0, Tomcat JDBC Pool 사용
- 문제점:
- 성능이 느림 (과도한 synchronized)
- 커넥션 누수, stale connection 문제
- 멀티스레드 환경 불안정
- 2012년, Brett Wooldridge가 성능과 안정성을 높인 HikariCP 개발
- 이름: 일본어 光(Hikari) = “빛”, 경량 & 고속 의미
- 설계 철학: 최소 동기화, lock-free 구조, JDBC 표준 준수
- Spring Boot 2.x부터 공식 기본 커넥션 풀로 채택
- 이유: 성능, 안정성, 낮은 메모리 오버헤드, 유지보수 신뢰성
2️⃣ HikariCP 구조
┌─────────────────────────────┐
│ HikariDataSource │ ← 사용자 접근
└───────────────┬─────────────┘
│
┌─────────▼─────────┐
│ HikariPool │ ← 풀 관리 핵심
└─────────┬─────────┘
│
┌─────────────┴─────────────┐
│ PooledConnection[] │ ← 실제 JDBC Connection 배열
└───────────────────────────┘
- HikariDataSource: Spring Boot에서 DataSource로 사용
- HikariPool: 커넥션 풀 관리
- PooledConnection: 실제 JDBC Connection을 Proxy로 감싸 재활용
3️⃣ 커넥션 요청 처리
1) Fast-path & Slow-path
경로의미특징
Fast-path | idle 커넥션 충분 시 | 즉시 반환, lock-free |
Slow-path | idle 없음 또는 경합 발생 시 | 새 커넥션 생성, connectionTimeout 동안 대기 |
flowchart TD
A[사용자 요청: getConnection()] --> B{ConcurrentBag에서 idle 커넥션 존재?}
B -- YES --> C[Fast-path: 상태 IN_USE로 변경 → 반환]
B -- NO --> D{총 커넥션 < maximumPoolSize?}
D -- YES --> E[새 커넥션 생성 → 반환]
D -- NO --> F[connectionTimeout 동안 대기 → 없으면 Exception]
C --> G[사용 후 connection.close() → IDLE 상태로 반환]
E --> G
F --> G
- ConcurrentBag: idle 커넥션 관리, lock-free 구조
- Proxy Connection: 반환 시 실제 닫지 않고 재활용
- Lazy 생성: 요청 시 필요한 만큼만 커넥션 생성
2) 최소 idle vs 최대 풀 동적 증가
- minimumIdle: 풀 시작 시 미리 생성, 항상 유지 → Fast-path 확보
- maximumPoolSize: 풀 최대치, DB 과부하 방지
- 요청 증가 시:
- idle 부족 → Slow-path
- 총 커넥션 < maximumPoolSize → 새 커넥션 생성
- 최대치 도달 → connectionTimeout 동안 대기
- idleTimeout: idle 상태 오래된 커넥션 폐기, minimumIdle 유지
flowchart TD
A[애플리케이션 시작] --> B[minimumIdle 커넥션 생성]
B --> C[커넥션 요청 발생]
C --> D{idle 커넥션 존재?}
D -- YES --> E[Fast-path 반환]
D -- NO --> F{총 커넥션 < maximumPoolSize?}
F -- YES --> G[새 커넥션 생성 → 반환]
F -- NO --> H[connectionTimeout 대기 → 없으면 Exception]
E --> I[connection.close() → IDLE 상태]
G --> I
H --> I
I --> J{idleTimeout 초과?}
J -- YES --> K[커넥션 폐기]
J -- NO --> L[idle 유지, minimumIdle 보장]
4️⃣ HikariCP 성능 고려 사항
- Fast-path 활용 → idle 충분히 확보
- Slow-path 발생 시:
- 커넥션 생성 시간 (JDBC 연결, 인증, SSL 등) 때문에 지연 가능
- 연관 문제
- minimumIdle 낮음 → Slow-path 폭주
- 커넥션 반환 지연 (close() 호출 지연)
- DB 최대 커넥션 제한 낮음 → 풀 확장 지연
- 해결 방법
- minimumIdle 증가, maximumPoolSize 확인
- DB 연결 최적화 (네트워크, 인증, SSL)
- 코드 최적화: 사용 후 즉시 close()
- 필요 시 connectionTimeout 조정
5️⃣ R2DBC 개요
- R2DBC (Reactive Relational Database Connectivity)
- 비동기, 논블로킹 방식의 리액티브 JDBC API
- Spring WebFlux 등 Reactive 시스템에서 사용
- 특징
- Flux/Mono 기반 → Reactor 지원
- 커넥션 풀 사용 가능 (r2dbc-pool)
- 기존 JDBC와 달리 스레드 블로킹 없음
항목JDBCR2DBC
방식 | 동기, 블로킹 | 비동기, 논블로킹 |
스레드 사용 | 쿼리 대기 시 블록 | 블록 없음 |
리액티브 호환 | ❌ | ✅ (Reactor, RxJava) |
적합 환경 | Spring MVC | Spring WebFlux, Reactive API |
6️⃣ 결론 요약
- HikariCP
- 최소 idle 유지 → 빠른 반환
- 요청 증가 시 최대 풀까지 점진적 확장
- Fast-path / Slow-path 구조로 동시성 최적화
- 성능 지연 원인
- DB 연결 자체 지연
- minimumIdle 낮음
- 커넥션 반환 지연
- R2DBC
- Reactive 환경에서 논블로킹 DB 접근
- 동기 JDBC 환경에서는 여전히 HikariCP 최적
반응형
Comments