TIL

DB CPU 스파이크 원인 추적기

하얀잔디 2025. 10. 27. 22:20

 

 

 

 

며칠 전, ezariadb01 서버 모니터링 그래프를 보다 이상한 걸 발견했음.
CPU 사용률이 갑자기 확 튀어올랐던 것.
그 시간대엔 배포도 없고, 딱히 트래픽이 몰린 시점도 아니었는데
그래프가 찔끔 튀어 있는 게 너무 찜찜했음.

처음엔 “DB 쪽에서 뭐 돌았나?” 싶어서 PostgreSQL 로그도 보고,
운영 중인 서비스 로그도 쭉 확인했는데 다 깨끗함.
결국 남은 건 Redis.

 

 

AOF 리라이트의 존재감

 

 

Redis 로그를 살펴보니 그 시점 근처에서 AOF(Append Only File) 리라이트가 돌았던 흔적이 있었음.
AOF는 Redis가 데이터를 안전하게 보존하기 위해
모든 쓰기 명령을 순서대로 파일에 기록하는 기능임.
그런데 계속 쌓이기만 하면 파일이 너무 커지니까,
주기적으로 “리라이트”라는 정리 작업을 수행함.

문제는 이 리라이트가 그냥 단순한 파일 저장이 아니라,
fork()를 통해 자식 프로세스를 하나 더 띄워서
메모리 데이터를 새로 복사해 파일을 재작성한다는 점임.

 


즉, 순간적으로 CPU랑 메모리를 동시에 잡아먹는 작업이 된다는 거.

그때 Redis 최대 메모리가 1GB로 설정되어 있었고,
AOF 파일이 커진 상태에서 리라이트가 돌다 보니
fork 시 메모리 복사 비용이 크게 튀면서 CPU가 급상승한 걸로 보임.

 

 

 

 

대응 — 메모리 확장과 튜닝

일단 급한 불은 껐음.
Redis 최대 메모리를 1GB → 4GB로 확장했고,
그 뒤로는 같은 리라이트가 돌아도 CPU 그래프가 거의 흔들리지 않음.
여유 메모리가 생기니까 fork 시 복사 비용이 훨씬 줄어든 것 같음.

하지만 여기서 끝이 아님.
AOF 리라이트는 주기적으로 반복되는 작업이라
언젠가는 또 발생할 수 있음.
그래서 아래처럼 예방 조치를 같이 걸어뒀음 👇

 

 

 

⚙️ AOF 리라이트 부하 완화 팁

  1. 리라이트 주기 완화하기
CONFIG SET auto-aof-rewrite-percentage 150
CONFIG SET auto-aof-rewrite-min-size 128mb

 

 

→ AOF 파일이 너무 자주 리라이트되지 않도록 비율과 최소 크기를 조정함.

 

2. 비동기 삭제(lazyfree) 활성화

 

CONFIG SET lazyfree-lazy-eviction yes
CONFIG SET lazyfree-lazy-expire yes
CONFIG SET lazyfree-lazy-server-del yes

 

→ 삭제나 만료 작업이 CPU를 덜 점유하게 함.

 

 

 

  • RDB와 AOF 작업이 겹치지 않게 하기
    → RDB 스냅샷 주기를 늘리거나 비활성화해서
    리라이트 타이밍이 동시에 겹치지 않도록 함.

 

 

이번 CPU 스파이크는 장애가 아니라,
Redis가 자기 일을 너무 열심히 한 결과였다.


AOF 리라이트는 Redis의 정상적인 동작이지만,
메모리 여유가 부족하면 그 과정이 다른 서비스에 영향을 줄 수 있음.

지금은 4GB로 확장해서 안정적으로 돌아가고 있고,
리라이트 주기도 조정해서 추후에 같은 현상이 생겨도
영향이 거의 없을 거로 예상됨.

 

 

운영하면서 이런 “잠깐 튄 그래프” 하나에도
시스템 내부에서 무슨 일이 일어나는지 추적해보면
확실히 배울 게 많음. Redis 진짜 단순한 듯, 깊은 놈임.

 

공부를 더 해야겠다.