본 포스팅은 실무에서 발생한 이슈에 대해 기록한 것이다.
AWS RDS에서 3초 이상 슬로우 쿼리가 발생하면 slack으로 알림이 오도록 설정을 해두었다.
23년도 12월부터 드물게 슬로우 쿼리 발생 알림이 왔으나, RDS에 부하를 심하게 주는 정도가 아니라 인지만 하고 넘겼었다.
하지만, 24년도 3월 초부터 빈번하게 테이블 풀 스캔인 슬로우 쿼리가 발생하면서 RDS에 심한 부하가 생기기 시작했고 CPU 사용량이 높게 올라갔다.
slack에서 알 수 있는 정보는 [언제][어떤 DB에서][어느 DB 계정으로][어떤 쿼리가]발생했는지이다.
DB가 다운되기 전에 슬로우 쿼리의 범인을 찾기 위해 해당 DB를 바라보는 사내 모든 프로젝트의 소스 코드를 확인했다.
모든 프로젝트에서 해당 테이블에 대한 쿼리 관련 소스 코드를 찾아보았지만, 조건절 없이 테이블 풀 스캔하는 로직은 그 어디에도 없었다.
슬랙 메세지에서 알 수 있는 정보 중 [어느 DB 계정으로]에 IP 주소도 있다. IP주소에 해당하는 서버를 AWS에서 찾은 결과, 23년도 12월 초에 신규로 배포한 api 서버였다.
해당 api 프로젝트의 소스코드를 면밀히 들여다 보았지만, 여전히 조건절 없이 테이블 풀 스캔하는 로직은 그 어디에도 없었다.
슬랙 메세지로 슬로우 쿼리 발생 시각에 api 서버에 남은 로그를 확인해보았다.
그 결과, 코드 상에서 정의하지 uri로 데이터를 조회한 이력이 남아있었다.
실무 로그여서 공개할 수 없지만, 대략적인 형태는 아래와 같았다.
2024-03-12 11:11:11 INFO 1234555 --[api-prod] ReuestFilter :
[REQUEST] GET /entities 200 - 0.54321
Response Body : {
"_embeded" : {
"entites" : [ {
id : 1,
name : 'A'
},{
id : 2,
name : 'B'
},
...
]
}},
...
}
왜 이런 로그가 남았는지 검토하던 중 build.gradle.kt 파일에서 의심가는 의존성을 발견했다.
implementation("org.springframework.data:spring-data-rest-hal-explorer")
이 설정으로 인해 엔티티 자체를 조건절 없이 풀스캔으로 조회하고 있었던 것이다.
hateos를 적용해볼 생각으로 프로젝트 초기에 세팅되어 있던 의존성이었는데, 당장 실무에서 hateos를 적용하지 않고 있기에 해당 의존성을 제거하여 슬로우 쿼리 이슈를 해결하였다.
spring-data-rest-hal-explorer 이 무엇인지 궁금하신 분들은 해당 링크에서 확인하면 좋을 거 같다.
운영단계에서는 의존성 하나에도 어떠한 이슈가 발생할 지 모르니, 잘 알아보고 적용해야 할 거 같다.