들어가며
중간 규모 트래픽을 처리하는 Spring Boot 애플리케이션에서 MySQL 데이터베이스 설정을 최적화하는 방법에 대해 정리하겠습니다. HikariCP 커넥션 풀, JPA/Hibernate, Flyway 마이그레이션까지 모든 설정을 상세히 다루어보겠습니다.

HikariCP 커넥션 풀 설정
기본 커넥션 풀 크기 설정
datasource:
hikari:
minimum-idle: 10
maximum-pool-size: 20
pool-name: "MainHikariPool"
- minimum-idle: 최소 유지 커넥션 수를 10개로 설정합니다. 이는 갑작스러운 트래픽 증가에 대비하여 기본적인 커넥션을 미리 확보해두는 역할을 합니다.
- maximum-pool-size: 최대 커넥션 수를 20개로 제한합니다. 중간 규모 애플리케이션에 적합한 수치이며, 데이터베이스 서버의 과부하를 방지합니다.
- pool-name: 모니터링 도구에서 커넥션 풀을 식별하기 위한 이름을 지정합니다. Actuator와 연동할 때 유용합니다.
타임아웃 설정 최적화
datasource:
hikari:
connection-timeout: 20000
idle-timeout: 600000
max-lifetime: 1800000
validation-timeout: 5000
leak-detection-threshold: 300000
- connection-timeout: 커넥션 풀에서 커넥션을 가져오기까지 대기하는 최대 시간을 20초로 설정합니다. 이는 적절한 응답 시간을 보장하면서도 시스템 안정성을 확보합니다.
- idle-timeout: 유휴 커넥션이 풀에서 제거되기까지의 시간을 10분으로 설정합니다. 너무 짧으면 커넥션 생성 비용이 증가하고, 너무 길면 불필요한 리소스를 점유하게 됩니다.
- max-lifetime: 커넥션의 최대 생존 시간을 30분으로 설정합니다. 이는 데이터베이스 서버의 타임아웃 설정보다 짧게 설정하여 예기치 않은 커넥션 끊김을 방지합니다.
- validation-timeout: 커넥션 유효성 검사의 최대 대기 시간을 5초로 설정합니다.
- leak-detection-threshold: 커넥션 누수를 감지하는 임계값을 5분으로 설정합니다. 이 시간을 초과하여 커넥션이 반환되지 않으면 로그에 경고를 출력합니다.
MySQL 최적화 설정
PreparedStatement 캐시 최적화
data-source-properties:
cachePrepStmts: true
prepStmtCacheSize: 250
prepStmtCacheSqlLimit: 2048
useServerPrepStmts: true
- cachePrepStmts: PreparedStatement 캐싱을 활성화합니다. 반복적으로 실행되는 쿼리의 성능을 크게 향상시킵니다.
- prepStmtCacheSize: 캐시할 PreparedStatement의 최대 개수를 250개로 설정합니다.
- prepStmtCacheSqlLimit: 캐시할 SQL 문의 최대 길이를 2048자로 제한합니다.
- useServerPrepStmts: 서버 사이드 PreparedStatement를 사용하여 성능을 최적화합니다.
배치 처리 최적화
data-source-properties:
rewriteBatchedStatements: true
useLocalSessionState: true
cacheResultSetMetadata: true
cacheServerConfiguration: true
elideSetAutoCommits: true
maintainTimeStats: false
- rewriteBatchedStatements: 배치 INSERT/UPDATE 문을 단일 네트워크 호출로 최적화합니다. QueryDSL과 JPA의 배치 처리 성능을 크게 향상시킵니다.
- useLocalSessionState: 세션 상태를 로컬에서 추적하여 불필요한 서버 통신을 줄입니다.
- cacheResultSetMetadata: ResultSet 메타데이터를 캐싱하여 반복 쿼리의 성능을 향상시킵니다.
- cacheServerConfiguration: 서버 설정 정보를 캐싱하여 초기화 시간을 단축합니다.
- elideSetAutoCommits: 불필요한 autocommit 설정 호출을 제거하여 성능을 향상시킵니다.
- maintainTimeStats: 시간 통계 수집을 비활성화하여 오버헤드를 줄입니다.
네트워크 및 문자셋 설정
data-source-properties:
connectTimeout: 15000
socketTimeout: 300000
characterEncoding: UTF-8
useUnicode: true
serverTimezone: Asia/Seoul
- connectTimeout: 데이터베이스 서버와의 연결 시도 시간을 15초로 제한합니다.
- socketTimeout: 소켓 읽기 타임아웃을 5분으로 설정하여 긴 실행 시간이 필요한 쿼리를 지원합니다.
- characterEncoding/useUnicode: UTF-8 인코딩을 명시적으로 설정하여 한글 처리를 보장합니다.
- serverTimezone: 한국 시간대를 설정하여 날짜/시간 처리의 일관성을 보장합니다.
JPA/Hibernate 최적화 설정
기본 설정
jpa:
hibernate:
ddl-auto: none
properties:
hibernate:
dialect: org.hibernate.dialect.MySQLDialect
format_sql: true
use_sql_comments: false
generate_statistics: false
- ddl-auto: Flyway를 사용하므로 Hibernate의 DDL 자동 생성을 비활성화합니다.
- dialect: MySQL 방언을 명시적으로 설정하여 최적화된 SQL을 생성합니다.
- format_sql: 개발 환경에서 SQL 로그의 가독성을 향상시킵니다. 운영 환경에서는 false로 설정하는 것이 좋습니다.
- generate_statistics: 성능 통계 수집을 비활성화하여 오버헤드를 줄입니다.
배치 처리 최적화
properties:
hibernate:
jdbc:
batch_size: 50
batch_versioned_data: true
order_inserts: true
order_updates: true
fetch_size: 50
- batch_size: 배치 처리 시 한 번에 처리할 엔티티 수를 50개로 설정합니다.
- batch_versioned_data: 버전 관리되는 엔티티도 배치 처리를 적용합니다.
- order_inserts/order_updates: INSERT와 UPDATE 문을 정렬하여 데드락 위험을 줄이고 배치 효율성을 높입니다.
- fetch_size: JDBC 드라이버 레벨에서 한 번에 가져올 행 수를 설정합니다.
쿼리 최적화
properties:
hibernate:
default_batch_fetch_size: 16
query:
in_clause_parameter_padding: true
plan_cache_max_size: 128
fail_on_pagination_over_collection_fetch: true
- default_batch_fetch_size: N+1 문제를 완화하기 위한 배치 페치 크기를 16으로 설정합니다.
- in_clause_parameter_padding: IN 절의 파라미터를 2의 거듭제곱으로 패딩하여 쿼리 캐시 효율성을 높입니다.
- plan_cache_max_size: 쿼리 실행 계획 캐시의 최대 크기를 128개로 제한합니다.
- fail_on_pagination_over_collection_fetch: 컬렉션 조인 페치와 페이징을 동시에 사용할 때 에러를 발생시켜 성능 문제를 예방합니다.
JPA 추가 설정
jpa:
show-sql: true
open-in-view: false
defer-datasource-initialization: true
- show-sql: SQL 로그를 출력합니다. 개발 환경에서 디버깅에 유용합니다.
- open-in-view: OSIV(Open Session In View)를 비활성화하여 성능을 최적화하고 명확한 트랜잭션 경계를 설정합니다.
- defer-datasource-initialization: Flyway 마이그레이션 완료 후 JPA를 초기화하도록 설정합니다.
Flyway 마이그레이션 설정
기본 설정
flyway:
enabled: true
locations: classpath:db/migration
encoding: UTF-8
baseline-on-migrate: true
- enabled: Flyway를 활성화합니다.
- locations: 마이그레이션 파일의 위치를 지정합니다.
- encoding: 마이그레이션 파일의 인코딩을 UTF-8로 설정합니다.
- baseline-on-migrate: 기존 데이터베이스에 Flyway를 처음 적용할 때 베이스라인을 생성합니다.
검증 및 보안 설정
flyway:
validate-on-migrate: true
out-of-order: false
group: false
mixed: false
clean-disabled: false
fail-on-missing-locations: true
placeholder-replacement: false
sql-migration-suffixes: [".sql"]
- validate-on-migrate: 마이그레이션 실행 전 파일 무결성을 검증합니다.
- out-of-order: 순서를 벗어난 마이그레이션을 허용하지 않습니다.
- group: 각 마이그레이션을 개별 트랜잭션으로 실행합니다. 운영 환경에서는 true로 설정하는 것이 좋습니다.
- mixed: SQL과 Java 마이그레이션의 혼용을 방지합니다.
- clean-disabled: 데이터베이스 전체 삭제 기능을 비활성화합니다. 운영 환경에서는 반드시 true로 설정해야 합니다.
- fail-on-missing-locations: 마이그레이션 위치가 존재하지 않을 때 실패하도록 설정합니다.
- placeholder-replacement: 플레이스홀더 치환을 비활성화하여 보안을 강화합니다.
- sql-migration-suffixes: SQL 마이그레이션 파일의 확장자를 명시적으로 지정합니다.
마무리
이러한 설정을 통해 중간 규모 트래픽을 안정적으로 처리할 수 있는 데이터베이스 환경을 구축할 수 있습니다. 각 설정값은 애플리케이션의 특성과 트래픽 패턴에 따라 조정이 필요할 수 있으므로, 모니터링을 통해 지속적으로 최적화하는 것이 중요합니다.
특히 HikariCP의 커넥션 풀 설정과 JPA의 배치 처리 설정은 성능에 직접적인 영향을 미치므로, 실제 운영 환경에서의 테스트를 통해 최적값을 찾아가시길 권장합니다.
'Spring 7기 프로젝트 > 모임 플렛폼 프로젝트' 카테고리의 다른 글
| WebClient의 비동기 처리와 블로킹: 성능 최적화의 핵심 이해 (3) | 2025.08.09 |
|---|---|
| Spring WebClient 프로덕션 레벨 설정 완벽 가이드 (1) | 2025.08.09 |
| Spring Boot에서 RabbitMQ Publisher Confirm 도메인별 설정하기 (1) | 2025.08.06 |
| Spring의 @TransactionalEventListener와 새로운 트랜잭션 전파 (0) | 2025.08.05 |
| 아웃박스 패턴과 RabbitMQ를 활용한 안전한 이벤트 발행 (0) | 2025.08.05 |