본문 바로가기
팀 프로젝트/플러스 프로젝트

Transactional-Readonly가 어플리케이션에 미치는 영향

by pon9 2025. 4. 4.

개요

Hot Key를 관찰하려고 부하테스트를 하던 도중, 세션 자동 생성에 이어 이상한 점을 하나 더 발견했다.

우선, 짧게 실험 결과를 요약하고 가면..

1. 실험 목적:
Hot Key가 Redis 또는 시스템에 어떤 영향을 미치는지 확인

2. 실험 조건:
key: "popular:market:items"
TTL: 무제한 - '인기 검색' 은 redis만 사용하도록 할 것이기 때문. 물론 fallback도 존재함.
JMeter: 3000유저 / 1초 ramp / 1000 loop
Redis: 단일 인스턴스, 로컬
실험 도중 1-2번의 Key Update 진행하여, 시스템에 미치는 영향 확인

사용한 툴: Prometheus, Grafana, Jmeter

3. 결과 요약:

Redis key rate(GET) 초당 5000~6000회
Redis Hit/Miss 거의 100% Hit
Redis Network I/O 안정적으로 증가
Redis Eviction 없음
API 평균 응답 시간 변동 없음
95% latency 0.065 → 0.08초 미세 상승

4. 분석:
캐시 적중률이 Hot Key 병목을 막음
시스템 부하는 key rate보다 miss율에 더 민감
무한 TTL 전략은 위험한 key에 대해 안정장치가 될 수 있음
TTL이 무한인 상태에서는 한 번만 SET해두면 이후에는 모두 Hit이기 때문에,
Redis는 단순 read 요청만 처리하고, backend는 아예 호출되지 않는다.
이는 Redis의 처리 효율이 매우 높고, 네트워크 병목이나 memory eviction이 없을 경우
Hot Key 자체는 오히려 아주 안정적인 캐싱 전략이 될 수 있음을 보여준다.
(사담: 또한 내 맥북의 성능이 캐시 처리 성능이 아 주 좋 은 것 같음...)

 

하지만,,

분명 Redis에서 Get만 하고있는데 DB Connection을 최대치로 사용하고 있는 점을 모니터링 할 수 있었다.

코드에서는 DB를 그 어느 곳에서도 호출하고 있지 않다. 왜 이런 현상이 발생하는 것일까?

 

 

분석

DB에서 어떤 쿼리를 사용하는지 정확히 알기 위해서 쿼리 로그를 키고,

로그 파일 위치를 확인하고 cat으로 해당 로그를 확인하니

범인은 트랜잭션이었다. Transactional(readonly=true) 설정이 DB 커넥션을 무단 사용(?) 하고있었다.

JPA에서 트랜잭션은 DB커넥션을 기반으로 동작한다. 즉, 트랜잭션을 열었다는 건 해당 커넥션으로 커밋/롤백 가능한 컨텍스트를 만들었단 것이고, readonly도 커넥션을 미리 확보하게 된다.

내(MySQL InnoDB)기준 기본 트랜잭션 격리 수준은 Repeatable Read이고,

트랜잭션 시작 시점의 snapshot으로 모든 select를 보장하게 된다.

트랜잭션을 시작해야 그 시점 기준의 일관된 데이터를 읽을 수 있고, 트랜잭션이 없으면 snapshot을 잡을 수 없어서 커넥션이 필요하다.

Redis캐시에서만 조회하거나, 모두 DTO로 변환해오는 단일 쿼리 조회인데 readonly true를 굳이 써야되나? 빼야겠다..

영속성 컨텍스트를 생성하는 것도 모자라서 DB커넥션까지 불필요하게 사용하고 있다.

이참에 readonly가 시스템에 미치는 영향을 한번 알아보도록 하자.

 

 

불필요한 readonly=true가 어플리케이션에 미치는 영향 테스트

위와 같은 조건으로 읽기 부하테스트를 진행하며,

readonly true로 인해 커넥션 풀을 최대치로 사용하고 있을 경우 어플리케이션에 미치는 영향을 테스트해보자.

실험은 registerMarket(거래소에 물품 등록) api의 응답시간을 기준으로 진행한다.

1. 트랜잭션 O readonly true: 95% latency 0.0884, DB 커넥션 최대로 사용

2. 트랜잭션 사용 X: 95% latency 0.0501, DB커넥션 사용 X 

실험 결론:
단순 조회용 API또는 캐시 기반 로직에 Transactional(readonly=true)는
성능적으로 불필요하며, 커넥션 낭비와 서비스 평균 latency 증가 요인이 된다.
따라서 Transactional은 정말 ACID함이 지켜져야 하는 곳에만 사용하는 것이 성능상 유리하다.

 

 

회고

그래서 Hot Key는 언제쯤 관찰할 수 있을까 눈물이 난다

이정도면 충분히 핫한데

 

아 근데 또 이상한거 하나 더 발견해서 다음글에서 다뤄보장..