반응형
들어가며
최근 알림 시스템을 개발하면서 알게된 기능을 활용해 조금의 성능을 개선한 경험을 담아보았습니다.
문제 상황
‼️ 사용된 코드와 MySQL Event 정의 script 는 예시입니다..!
알림 시스템을 개발하면서 NotificationHistory 엔티티를 만들어 알림 히스토리를 관리했습니다.
@Entity
@Table(name = "notification_history")
class NotificationHistory(
@Column(name = "created_at", nullable = false)
val createdAt: Long = System.currentTimeMillis(),
// ... 다른 필드들
)
아래의 상황을 문제로 정의했습니다:
- 의미 없는 오래된 데이터: 1주일이 지난 알림은 누가 봐도 의미가 없음
- 데이터베이스 부담: 불필요한 데이터가 계속 누적되어 성능 저하 우려
Spring Scheduler
당연히 가장 먼저 떠오른 해결책은 Spring Scheduler였습니다.
@Scheduled(cron = "0 0 1 * * *") // 매일 새벽 1시
public void deleteExpiredNotifications() {
// 7일이 지난 데이터 삭제 로직
}
이렇게 문제를 해결할 수 있었지만, "굳이?"라는 생각이 들었습니다.
굳이 서버를 통해 실행하지 않아도 데이터베이스 단에서 직접 처리가 가능했고, 데이터베이스 레벨에서 처리하는 것이 조금이라도 더 효율적일 것 같았습니다.
MySQL Event
데이터베이스 레벨에서 직접 예약 작업을 수행할 수 있는 기능이었죠.
MySQL Event란?
- 데이터베이스에서 예약된 작업을 자동으로 실행
- 애플리케이션 레벨 스케줄러 불필요
- MySQL 서버가 실행 중이면 계속 동작
구현 과정
1. 이벤트 생성
CREATE EVENT delete_expired_notifications
ON SCHEDULE EVERY 1 HOUR
STARTS '2025-01-01 00:00:00.000'
ON COMPLETION NOT PRESERVE
ENABLE
DO BEGIN
DELETE FROM notification_history
WHERE created_at IS NOT NULL
AND created_at + (7 * 24 * 60 * 60 * 1000) < UNIX_TIMESTAMP() * 1000;
END
알림센터에 표출할 데이터의 만료기간을 7일로 설정해, 7일 이후의 데이터들을 자동으로 삭제되도록 처리했습니다.
2. 이벤트 관리 명령어
-- 이벤트 스케줄러 활성화 확인
SHOW VARIABLES LIKE 'event_scheduler';
-- 이벤트 목록 확인
SHOW EVENTS;
-- 이벤트 활성화/비활성화
ALTER EVENT delete_expired_notifications ENABLE;
ALTER EVENT delete_expired_notifications DISABLE;
개선 효과
1. 서버 리소스 절약
- CPU/메모리 사용량 감소: 애플리케이션 스케줄러 불필요함에 따라 별도 스레드나 프로세스 불필요
- 네트워크 트래픽 감소: 애플리케이션 ↔ 데이터베이스 통신 최소화
2. 안정성 향상
- 데이터베이스 레벨 처리: 더 안정적이고 일관성 있는 처리
- 애플리케이션 독립성: 서버 재시작과 무관하게 동작
- 오류 처리: 데이터베이스 레벨에서 직접 처리
3. 운영 편의성
- 유연한 조정: 필요시 즉시 스케줄 변경 가능
마무리
MySQL Event는 로그성 데이터와 같이 단순한 데이터 처리에 유용했습니다.
다만 복잡한 데이터를 다루거나 비즈니스 로직이 필요한 경우에는 아쉽게도 한계가 있을 듯 합니다.
'개발 > 성능 개선' 카테고리의 다른 글
| DB 조회 최적화: Map을 활용한 조회 횟수 줄이기 (1) | 2025.07.14 |
|---|---|
| Bulk Update 성능 개선: JPA에서 JdbcTemplate으로 전환 (0) | 2025.04.07 |