Next.js로 SNS 앱을 개발하면서 AWS RDS를 데이터베이스로 사용하게 되었다.
처음에는 "데이터만 잘 저장되고 조회되면 되지 않나?" 싶었는데, 실제로 운영하다 보니 궁금한 게 생겼다.
지금 DB에 연결이 몇 개나 되어 있지? CPU 사용률은 괜찮은가? 느린 쿼리는 없나? 혹시 에러가 발생하진 않았나? 와 같은 궁금증이었다.
문제가 생기고 나서야 "아, 모니터링을 해뒀어야 했는데..." 하고 후회하기 전에, CloudWatch로 RDS를 모니터링하는 방법을 정리해봤다.
RDS는 기본적으로 CloudWatch에 메트릭을 자동으로 전송한다. 별도 설정 없이도 다음과 같이 확인할 수 있다!
RDS 인스턴스를 들어가 모니터링 탭을 선택하면 아래와 같은 매트릭 지표들을 확인할 수 있다.

(1) CPU 관련
1-1 CPUUtilization (CPU 사용률)
DB 인스턴스가 CPU를 얼마나 사용하고 있는지에 대한 지표이다.
예를 들어 80 % 이상 이라면 쿼리 최적와 또는 인스턴스 업그레이드가 필요할 수있다.

1-2 CPU 크레딧 관련 지표들
(1) CPUCreditUsage (CPU 크레딧 사용량)
(2) CPUCreditBalance (CPU 크레딧 잔액)
(3) CPUSurplusCreditBalance (초과 크레딧 잔액)
(4) CPUSurplusCreditsCharged (초과 크레딧 청구)
=> 이 지표들은 t 시리즈 등 성능 버스트 가능 인스턴스의 CPU 사용 패턴을 모니터링하고, 인스턴스 성능이 기준치를 초과할 때 크레딧을 얼마나 소비하고 있는지 추적하는 데 사용된다.
(2) 메모리 관련
2-1 FreeableMemory (사용 가능한 메모리)
사용 가능한 RAM (Bytes)를 나타내며 만약 해당 지표가 지속적으로 낮다면 메모리가 부족하다는 의미이기 때문에
쿼리 최적화가 필요하다.

2-2 SwapUsage (스왑 사용량)
디스크 스왑 공간 사용량 (Bytes)을 의미하고 해당 지표가 높다면 메모리가 부족해 성능 저하를 경험할 수 있다.
아마 나는 작은 인스턴스를 사용하고 있어 해당 지표가 평균보다는 높게 나오는 것 같다.

(3) 디스크 I/O 관련
ReadIOPS (읽기 IOPS)
초당 읽기 작업 수
WriteIOPS (쓰기 IOPS)
초당 쓰기 작업 수
TotalIOPS (전체 IOPS) = ReadIOPS + WriteIOPS
전체 디스크 부하 파악
ReadLatency (읽기 지연시간)
평균 읽기 작업 지연시간 (ms)
WriteLatency (쓰기 지연시간)
평균 쓰기 작업 지연시간 (ms)
ReadThroughput (읽기 처리량)
초당 읽은 데이터량 (Bytes/s) => 대용량 SELECT 쿼리 감지
WriteThroughput (쓰기 처리량)
초당 쓴 데이터량 (Bytes/s) => 대용량 INSERT/UPDATE 감지
DiskQueueDepth (디스크 대기 큐 깊이)
대기 중인 I/O 요청 수 => 높다면 디스크 병목이 일어날 수 있다.
(너무 많아서 사진은 생략하겠습니다.)
(4) 스토리지 관련
4-1 FreeStorageSpace (여유 스토리지)
사용 가능한 디스크 공간 (Bytes)

(5) 네트워크 관련
5-1 NetworkReceiveThroughput (네트워크 수신 처리량)
초당 받은 데이터량 (Bytes/s) -> 앱에서 DB로 전송되는 쿼리량

5-2 NetworkTransmitThroughput (네트워크 송신 처리량)
초당 보낸 데이터량 (Bytes/s) -> DB에서 앱으로 전송되는 결과량

(5) 연결 관련
5-1 DatabaseConnections (데이터베이스 연결 수)
현재 활성 DB 연결 수

만약 앱이 느려졌다면?
확인해볼수있는건 다음과 같을 것 이다.
1. CPUUtilization 가 80% 이상인지? 그렇다면 쿼리 최적화 시도할 것같다.
2. ReadLatency 가 높다 그렇다면 인덱스를 추가할 것 이다.
3. DatabaseConnections가 급증한다면? Connection Pool 설정을 시도한다.
4. 아니며 FreeableMemory가 낮은건지 확인할 것이다.
그런데 갑자기 에러가 발생한다면?
1. DatabaseConnections가 최대치를 찍고 있다면 연결 누수가 일어나고 있는지 확인해볼것이다.
2. 아니면 Error Log를 확인해볼것이다.
사실 메트릭 모니터링 만으로는 에러가 났을때 무엇이 문제인지를 알기가 어렵다.
예를 들어 CPU 이용율이 80퍼가 넘고 연결수 50개 , 메모리가 부족하다는 매트릭을 보면
문제가 있다는건 알겠지만 정확히 어떤 쿼리가 문제이고 어떤 에러가 발생했는지는 알기 어렵다.
때문에 로그를 수집해야 정확한 원인을 파악할 수 있다.
RDS는 다음과 같은 로그들을 제공한다.
RDS 설정에 들어가면 다음과 같이 모니터링 섹션에서 '로그 내보내기' 부분을 확인할수 있다.


1. Error Log (에러 로그)
MySQL 서버 시작/중지, 에러, 경고 메시지
- 예시:
- 연결 실패
- 테이블 손상
- 플러그인 로드 실패
- 용도: 서버 문제 진단
2. Slow Query Log (느린 쿼리 로그)
- 내용: 실행 시간이 오래 걸린 쿼리
- long_query_time 을 따로 파라미터 그룹에서 설정해줘야한다.
- 몇 초 이상을 느린 쿼리로 볼지 설정하기 위함.
- 나는 1초 이상으로 설정했다.
3. General Log (일반 로그)
- 내용: 모든 쿼리 기록하고 디버깅하기 위함이다.
- 모든 쿼리를 기록하기 때문에 로그량이 폭등할 수 있어 성능 저하가 될 수 있어 필요할때만 활성화하는 것이 좋다.
4. Audit Log (감사 로그)
- 내용
- 접속 이벤트: 누가, 언제, 어디서 로그인했는지
- 쿼리 실행: 어떤 쿼리를 실행했는지
- DDL 변경: CREATE, ALTER, DROP 등 스키마 변경
- 실패한 로그인 시도: 보안 위협 감지
RDS 로그를 수집하기 위해서는 커스텀 파라미터 그룹 설정을 해줘야 한다.

파라미터를 설정하는 방법은 하단의 참조에 있는 공식문서를 확인하면 된다!
RDS 에서 로그 내보내기 설정을 완료해주면 다음과 같이 CloudWatch 로그그룹에서 3가지 그룹이 생긴것을 확인할수있다.

정말 로그가 쌓이는지 아래의 쿼리문을 실행해 확인해보면 다음과 같다!
우선 table들을 조회하고 일부로 느린 쿼리를 실행해보았다.
SELECT * FROM users LIMIT 10;
SELECT * FROM posts LIMIT 10;
SELECT COUNT(*) FROM users;
SELECT SLEEP(2);
우선 slowquery 부터 살펴보면 로그 이벤트에 내가 실행한 쿼리문이 로그로 남겨져 있는것을 확인할 수 있었다.


general 로그 같은 경우는 정말 많이 쌓이긴 한다...;;

error 로그도 아래와 같이 쌓이게 된다.

[참조]
Amazon CloudWatch Logs에 데이터베이스 로그 게시 - Amazon Relational Database Service
이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.
docs.aws.amazon.com
Amazon CloudWatch Logs에 MySQL 로그 게시 - Amazon Relational Database Service
다음 예에서는 CloudWatch Logs에 로그 파일을 게시하도록 기존 MySQL DB 인스턴스를 수정합니다. --cloudwatch-logs-export-configuration 값은 JSON 객체입니다. 이 객체에 대한 키는 EnableLogTypes이며, 해당 값은 aud
docs.aws.amazon.com
[AWS] RDS MySQL Audit Log 설정 (옵션 그룹, CloudWatch)
로그 중 Error Log, General Log, Slow Query Log 는 AWS RDS Management Console 내 [파라미터 그룹] 에서 설정이 가능하지만,Audit Log 는 [옵션 그룹] 에서 설정이 가능하다. [옵션 그룹] 을 통해 감사 로그를 설정
ryean.tistory.com
https://repost.aws/ko/knowledge-center/rds-mysql-logs
RDS for MySQL에서 로그 활성화 및 모니터링
Amazon Relational Database Service(Amazon RDS) for MySQL DB 인스턴스의 로그를 활성화하고 모니터링하려고 합니다.
repost.aws