작성
·
8
·
수정됨
0
안녕하세요! 자주 질문드리는데 정성껏 답변해주셔서 감사합니다!
동일한 이벤트가 중복 전송될 가능성이 있기 때문에 article-read 서비스에 이벤트 id를 통한 중복 처리 로직을 추가 하려고합니다.
article-read 는 redis를 사용하고 있기 때문에 redis에 이벤트 id를 저장해 해결하려고했습니다.
예를 들어 article-read가 이벤트를 받았을때
redis 에서 이벤트 id 확인
동일한 이벤트 id가 저장돼 있으면 추가 처리 안하고 message ack
redis 에서 이벤트 id 확인
동일한 이벤트 저장된게 없으면 서비스 로직 수행
서비스 로직 결과 redis 업데이트
처리 완료한 이벤트 id redis 저장
이런식으로 진행하려 했으나 만약 어떠한 문제로 인해
서비스 로직 결과 redis 업데이트 ( 성공 )
처리 완료한 이벤트 id redis 저장 ( 실패 )
하게되면 이벤트 처리는 성공했지만 처리된 이벤트 저장에는 실패해 추후에 중복 처리가 발생할 가능성이 생길 것 같습니다.
이러한 문제 해결을 위해
서비스 로직 결과 redis 업데이트
처리 완료한 이벤트 id redis 저장
두 작업을 하나의 트랜잭션으로 묶어 처리하려고했지만 rdb 와 동작이 다르기 때문에 (롤백 기능 제공 안함 등) 적절한 방법인지 판단이 안서는 상태네요
혹시 article-read에 이벤트 중복 처리를 한다고 하면 어떻게 구현이 가능할지 여쭤보고싶습니다
답변 1
0
안녕하세요, 인프런 AI 인턴입니다. 김진현님.
Kafka와 같은 메시지 브로커를 사용할 때, 이벤트의 중복 전송은 예상 가능한 문제입니다. 이를 방지하기 위한 방법 중 하나는 이벤트의 ID를 기반으로 중복 처리를 구현하는 것입니다.
Redis를 사용한 중복 처리에 대한 전략을 아래와 같이 정리해보겠습니다.
제시하신 로직에서는 이벤트 처리 후 ID 저장이 실패할 경우 중복 처리가 되지 않을 수 있다는데, 이는 일관성 문제로 이어질 수 있습니다.
중복 처리 로직 강화:
이벤트를 처리할 때는 두 가지 작업, 즉 “서비스 로직 수행”과 “이벤트 ID 저장” 모두 실패할 경우 전체 작업을 무효화해야 합니다.
원자적 작업 활용:
Redis의 멀티 명령어 트랜잭션을 활용하여 “서비스 로직 결과 업데이트”와 “이벤트 ID 저장”을 하나의 원자적 명령으로 묶을 수 있습니다. 이는 Redis의 MULTI
와 EXEC
명령어를 사용하여 구현할 수 있습니다.
분산 락 이용:
중복 처리를 위해 분산 락을 사용할 수 있습니다. 예를 들어, 처리 중인 이벤트에 대해 락을 걸고, 처리가 완료될 때까지 다른 인스턴스에서 동일한 이벤트를 처리하지 못하게 할 수 있습니다. Redis의 SETNX
명령어를 이용하면 쉽게 구현할 수 있습니다.
2단계 커밋 시뮬레이션:
만일 Redis와 RDBMS 간의 일관성을 높이고 싶다면 2단계 커밋을 시뮬레이션하는 방법도 고려해 볼 수 있습니다. 이는 일부 실패 시 복구 롤백 로직을 미리 구현해 두어 실패에 대응하는 것을 의미합니다.
복제와 확인 전략:
이벤트 ID 저장이 실패했을 경우를 대비하여, 이벤트 ID를 다른 저장소에도 복제하는 방식으로 실패 검증을 강화할 수 있습니다.
이런 접근법들은 시스템의 요구사항에 따라 다양하게 조정될 수 있습니다. 아래 유사한 문제 및 해결 방법을 다룬 링크도 참고해 보세요:
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.