위 글을 읽다가 SLOW QUERY가 뭔지 궁금해져서 정리해 봄
SLOW QUERY
slow query란?
- DBMS가 클라이언트의 요청을 받아 응답하는 과정에서 오래 걸리는 query는 slow query로 분류하고 log를 남겨준다.
유사한 용어 정리 : slow query == Transaction 시간이 길다 == QPS(query per second)가 길다
- 비정상적인 DB connection으로 인해 메모리 및 CPU 리소스가 비정상적으로 높게 소모되면, 서비스 전체에 악영향을 미칠 수 있으므로 주의.
slow query를 인지하는게 왜 중요한지?
- 서비스를 운영하다보면 여러 이유로 서버 장애가 발생하는데, 높은 확률로 장애 원인이 DB의 slow query임
- 어떤 쿼리가 언제, 얼마나 긴 시간 동안 수행되었는지에 대해 알람/모니터링이 되어야 서비스에 이슈가 될만한 쿼리들을 지속적으로 탐지하고 개선이 가능할 수 있음
어떻게 확인?
- AWS를 쓰는 경우 : console 에서 slow query를 손쉽게 필터링하고 확인 가능
- 하지만 매번 확인하기 귀찮음 → slow query 발생 시 slack에 알림이 오도록 개발하면 편하다.
어떻게 해결?
1. Redis cache 쓰기 (임시 해결책)
- 서버 ~ DB 접근 수를 줄이는 방법, 임시적으로 사용하면 좋을 듯 하나, 근본적인 해결책은 아님
- 문제 해결될 때까지 임시로 쓰다가 제거해야…
- 장점 : 빠르게 해결 가능
- 단점1: 매 요청마다 Redis가 업데이트되어야 한다. (동시성, 데이터 정합성 문제) → 자주 업데이트 되는 테이블은 Redis에 넣으면 안 됨
- 단점 2: 비즈니스 로직 복잡도 증가 → 유지보수에 악영향
2. Transaction의 길이 줄이기
- Transaction 구간을 잘 분리
- 다른 API를 요청하지 않도록 하기
- OSIV를 false로 바꾸기 (default = true)
OSIV(Open Session In View)란? 영속성 컨텍스트를 뷰까지 열어두는 기능이다
- OSIV가 true인 경우, 요청 전 구간에 Transaction이 걸린다.
- 3rdParty 요청/응답받는 구간이 DB Transaction에 포함되므로 무척 오래 걸린다.
- 각각의 요청이 db connection을 오래 유지하고 있기 때문에, db connection pool 개수가 모자라진다.
- 이 경우 tomcat thread가 아무리 많아도 소용없음 (어차피 DB 기다려야 함)
고속도로 휴게소로 비유하자면… 주차장(스레드)에 자리가 차는 엄청 많이 들어올 수 있지만, 화장실(DB connection pool)은 10칸밖에 없어서 결국 다들 화장실만 기다리고 있는 그런 느낌….?
- OSIV를 false로 하면 Transaction 길이는 짧아지지만,
lazy loading
문제가 생길 수 있어 주의해야 함- api 요청 전 구간에 걸려있던 Transactional 이 없어지면서 이슈가 생길 수 있음
- lazy loading 예방을 위해해 JPA EntityGraph 제거, Entity 대신 Dto 쿼리 작업 등이 필요. (꽤 귀찮은 작업….)
'TIL' 카테고리의 다른 글
함수 명명시 자주 사용되는 동사 표현 정리 (유의어, 반의어) (1) | 2024.05.02 |
---|---|
JPA 단방향 연관관계, 양방향 연관관계 (1) | 2024.04.28 |
JPA 연관관계 매핑 (0) | 2024.04.27 |
Java 기초 문법(2) (0) | 2024.02.19 |
Java 기초 문법 (1) (0) | 2024.02.18 |