과거에 주로 사용되던 Commons DBCP나 C3P0 같은 "옛날 스타일"의 커넥션 풀과 현재 표준인 HikariCP는 설계 철학부터 성능 최적화 방식까지 큰 차이가 있습니다.
단순히 "더 빠르다"를 넘어, 어떤 기술적 포인트가 다른지 비교해 정리해 드립니다.
1. 한눈에 보는 비교 (Old vs. Modern)
| 구분 | 옛날 스타일 (DBCP, C3P0) | 요즘 스타일 (HikariCP) |
| 철학 | 풍부한 기능과 세밀한 옵션 제공 | 극단적인 단순화와 성능 최적화 |
| 라이브러리 크기 | 상대적으로 무거움 (수 MB) | 매우 가벼움 (약 130KB) |
| 동기화 전략 | synchronized 등 무거운 락 위주 | Lock-free 설계 (ConcurrentBag) |
| 연결 검증 | testOnBorrow, validationQuery 위주 | maxLifetime 기반의 선제적 교체 |
| 바이트코드 | 표준 JDK Proxy 사용 | Javassist를 이용한 바이트코드 최적화 |
2. 결정적인 기술적 차이점
① 연결 관리의 패러다임: "검사" vs "교체"
- 옛날 방식: "이 커넥션 아직 살아있나?"라고 끊임없이 DB에 물어봅니다 (test-while-idle, testOnBorrow). 이 과정 자체가 DB 부하가 되고 응답 속도를 늦춥니다.
- HikariCP 방식: 커넥션의 **유효 수명(maxLifetime)**을 정해두고, 시간이 다 되면 조용히 폐기하고 새것으로 바꿉니다. 굳이 살아있는지 찔러보지 않아도 신선한 상태를 유지하는 전략입니다.
② 동기화 구조: ConcurrentBag
옛날 풀들은 여러 스레드가 동시에 커넥션을 요청하면 줄을 세우기 위해 무거운 락(Lock)을 걸었습니다. 반면, HikariCP는 ConcurrentBag이라는 특수한 구조를 사용합니다.
- ThreadLocal 캐싱: 내가 썼던 커넥션을 우선적으로 다시 찾게 해줍니다.
- Queue-stealing: 내 주머니에 없으면 다른 스레드의 주머니에서 남는 걸 가로채 옵니다. 이 과정에서 락 경합을 최소화하여 성능을 폭발적으로 끌어올렸습니다.
③ 바이트코드 수준의 다이어트
HikariCP 개발자들은 CPU 캐시 적중률까지 고려했습니다. 코드를 극단적으로 줄여서 컴파일된 바이트코드가 CPU 캐시에 더 잘 올라가도록 설계했습니다. 심지어 Java의 표준 Proxy 객체가 무겁다고 판단해, Javassist라는 도구로 직접 최적화된 프록시를 생성해서 씁니다.
3. 설정 시 주의사항 (마이그레이션 팁)
과거 설정 방식에 익숙하다면 HikariCP를 쓸 때 당황할 수 있는 부분들입니다.
- minimumIdle 설정 지양: 과거에는 커넥션을 미리 많이 만들어두는 게 미덕이었으나, HikariCP는 maximumPoolSize와 동일하게 맞추는 Fixed Pool 방식을 강력히 권장합니다. (풀 크기가 변하면 그 자체가 오버헤드이기 때문)
- validationQuery 생략: 최신 JDBC 드라이버는 isValid() API를 지원하므로, SELECT 1 같은 쿼리를 직접 작성할 필요가 없습니다. HikariCP는 드라이버 수준에서 유효성을 체크합니다.
- maxLifetime의 중요성: DB의 wait_timeout보다 최소 30초 이상 짧게 설정해야 "죽은 커넥션"을 잡는 불상사를 막을 수 있습니다.
LIST
'스프링 개발자 > DB' 카테고리의 다른 글
| 📌 MariaDB vs PostgreSQL vs Oracle – 실무 개발자를 위한 핵심 비교 정리 (0) | 2025.11.26 |
|---|---|
| mybatis 변천사(feat. iBATIS ) (1) | 2025.09.22 |
| MyBatis 3에서는 SQL을 자동으로 실행해주는 기능 (0) | 2025.09.22 |
| 마이바티스의 장단점 (0) | 2025.09.21 |
| 데이터 모델링( 비즈니스 로직 tdd로 가기전) (2) | 2024.02.10 |