Resolving Duplicate Notification Bursts with Redis-Based Rate Limiting

중복 발송 이슈 해결 - Redis 기반 Rate Limit 도입

(사내 보안 규정에 따라 실제 서비스·테이블·코드 식별자는 모두 일반화되어 있습니다)

배경:

기존 구조에서는 도메인 이벤트가 발생하면, 알림탭에 쌓이는 알림유저 기기로 발송되는 푸시가 자동으로 생성되는 구조였습니다.

이벤트 발생 빈도가 높은 특정 케이스에서는 중복 알림 발송 현상이 드러나기 시작했습니다.

  • 팔로잉한 유저가 짧은 시간 안에 여러 글을 연속으로 썼을 경우

  • 팔로우/언팔로우가 반복되는 경우

이로 인해 사용자 입장에서는

  • 알림 센터에 유사한 알림이 연속으로 쌓이고,

  • 푸시 알림이 짧은 시간 동안 여러 번 도착하는

알림 폭탄 문제가 발생했습니다.

원인 파악 - '중복'이 아니라 '빈번한 발생'의 상황.

이벤트는 '정상적으로' 여러 번 발생하고 있었고, 시스템 관점에서는 잘못된 이벤트가 아니라는 것을 확인했습니다.

기능적 오류는 아니라는 것을 확인하였고, "정책 문제"에 가까웠습니다.

해결 방법

해결 전략은 "중복을 막자"보다는, "같은 유형의 알림은 일정 시간에 한 번만 보내자" 였습니다.

이를 위해 고민한 방법들은 아래와 같습니다.

DB Unique 제약으로 중복 차단(X)

알림 테이블에 Unique 제약을 두어 중복 생성을 원칙적으로 막는 방식.

  • 중복의 기준을 컬럼 조합으로 판단하기가 어려웠고,

  • 정책 변경시 스키마 변경이 발생할 수 있으며,

  • 충돌 발생시 예외처리나 재시도 로직이 복잡해질 것,

정책 문제에 비해 오버엔지니어링라고 판단되고, 정책 변경에 대한 유연성이 떨어진다고 판단했습니다.

알림 생성 시, 최근 알림 조회(X)

알림Row 생성 시간을 확인하는 방법으로, 최근 비슷한 알림을 DB에서 조회 후 판단할 수 있습니다.

  • 알림 생성 시마다 추가 RTT와DB 부하 증가. 대량 트래픽 상황에서는

  • 쿼리 성능을 위해 테이블에인덱스가 추가되어야 했고, 데이터삽입시 부담 증가.

중복을 막기 위해 DB를 더 사용하는 구조는, 문제를 해결하기보다 새로운 병목을 만들 가능성이 높다고 판단했습니다.

메시지 큐 기반 처리(X)

정확히 한 번만 알림을 발송하도록 보장하는 방식으로, 중복 제거에 많이 사용됩니다.

  • 같은 이벤트가 중복으로 처리되어 같은 알림이 두 번 생성되는 상황에 사용합니다.

  • 식별 가능한 ID를 통해 처리된 작업인지 구별합니다.

이 방식은 ‘같은 이벤트가 여러 번 처리되는 문제’를 해결하는 방법이지, ‘정상 이벤트가 자주 발생해 알림이 많이 가는 문제’를 해결하는 방식은 아닙니다.

Redis 기반 Rate Limit(O)

키 존재 여부만 빠르게 판단할 수 있으면 충분했기 때문에, 복잡한 데이터 구조 대신 단순한 키 기반 접근을 사용했습니다.

  • 빠르고 가벼운 제어: Redis는 인메모리 NoSQL 저장소이고, 초당 수천 건 조회에도 부담이 적고,

  • 자동 만료:TTL 기반 자동 만료를 통해 관리가 쉬웠고,

  • 장애 영향 범위 분리: DB 트랜잭션과 분리가 가능했으며,

  • 추가 인프라 비용 없음: 새로운 기술 도입이 아닌, 기존에 Redis를 사용하고 있었고,

  • 정책 변경이 쉬웠습니다.

가장 단순하고 해당 문제에 적합한 해결책이었습니다.

핵심 설계

알림 생성 전에 Redis에 발송 이력 키를 기록 ( rate_limit: {notification_type}:{target_id}:{date} )

키가 존재하면 알림 생성을 스킵하고, 키가 없으면 알림 생성 후 TTL(내부적으로 논의)과 함께 저장했습니다.

  • 새 글 알림: 1일

  • 팔로우 알림: 1분

적용 위치

Event Subscriber 레벨에서 적용하였습니다.

  • 이벤트는 발생했지만, 알림을 생성할지 말지 결정.

  • 추후 사용처가 많을 것 같아서, 별도의 클래스로 정의하였습니다.

  • 정책 변경에 유연한 대처를 위해 타입별로(ENUM) TTL을 한곳에 모아 관리할 수 있게 설계했습니다.

결과

  • 동일 유형 알림의 중복 발송이 제거됐습니다.

  • 정책 계층만 추가하여 문제를 해결하였고,

  • 유틸리티 메서드를 활용해서 특정 알림 유형에만 선택적으로 적용할 수 있게 되었습니다.

Last updated