모든 글

아웃박스 폴링을 바꾸기 전에 측정하라

현실적인 부하로 아웃박스 폴링을 검증하고, 로그 테일링을 도입하기 전에 더 단순한 애플리케이션 전달 방식을 검토한다.

출처 및 AI 안내: 이 글은 제미니의 개발실무 유튜브를 기반으로 작성되었습니다. gpt-5.6-sol 모델을 사용해 생성·편집했습니다.

트랜잭셔널 아웃박스를 폴링하다 보면 불편한 질문이 생긴다. 스케줄된 배치가 여는 DB 커넥션과 락이 이미 성능 문제가 된 것일까, 아니면 전달 방식을 바꾸는 일이 필요 이상의 복잡성을 더할까?

패턴의 이름만으로는 답을 낼 수 없다. 먼저 서비스가 실제로 겪을 트래픽 모양으로 현재 구조를 측정해야 한다. 그다음 폴링 구현이 DB 자원을 필요한 시간보다 오래 붙잡고 있는지 살펴봐야 한다. 로그 테일링도 선택지이지만, 폴링이 비효율적으로 들린다는 이유만으로 자동 선택할 다음 단계는 아니다.

‘충분히 안전하다’를 부하 테스트로 정의하라

대규모 트래픽이 발생하지 않는 서비스라면 현재 폴링 방식으로도 괜찮을 수 있다. 여기서 중요한 말은 ‘수 있다’이다. 괜찮다는 판단에는 검증 가능한 경계가 필요하다.

현재 트래픽 수준을 100이라고 놓아 보자. 우선 그 수준에서 테스트하고, 예시로 세 배인 300까지 튀었을 때도 확인한다. 정확히 몇 배인지는 서비스의 성질보다 중요하지 않다. 큰 스포츠 행사에 따라 사용량이 늘어나는 서비스와 온라인 크리에이터의 소개 직후 갑자기 유입이 몰리는 서비스의 곡선은 다르다. 트래픽이 점진적으로 자라는지, 알려진 행사에 맞춰 늘어나는지, 갑작스럽게 튀는지부터 이해해야 한다.

테스트 결과는 현재 설계가 어느 정도 부하를 견디며 어디서 흔들리는지 알려줘야 한다. 장애가 난 뒤에야 한계를 알아내는 방식은 바람직하지 않다. 그렇다고 모든 미래 문제를 미리 풀 필요도 없다. 가능한 성장세와 급증을 모델링해 시험하고, 근거가 바뀔 때 아키텍처를 확장하면 된다.

폴러가 실제로 무엇을 붙잡는지 확인하라

“폴링하는 동안 DB 커넥션이 열려 있다”는 말 안에는 서로 다른 구현이 숨어 있을 수 있다. 작업을 실제 단계로 나눠 보자.

  1. 처리할 이벤트를 읽는다.
  2. 이벤트를 분산하거나 전달한다.
  3. 처리 결과를 갱신한다.

DB 커넥션은 읽기와 갱신에 필요하다. 이벤트 전달 자체에 DB 작업이 없다면 그 구간까지 커넥션을 열어 둘 필요는 없을 수 있다. 전체 방식을 교체하기 전에 트랜잭션과 커넥션의 경계를 확인하고, 필요한 만큼으로 줄일 수 있는지 살펴봐야 한다.

락도 마찬가지다. 하나의 스케줄 배치가 모든 작업을 직렬로 처리한다면 병렬로 나눌 수 있는지 검토해 볼 수 있다. 병렬화가 모든 락 문제를 해결한다는 뜻은 아니다. 병목이 아웃박스 패턴 자체에서 생기는지, 현재 워커의 구성에서 생기는지 먼저 확인하자는 이야기다.

즉시 전달하고 배치로 복구하는 흐름을 검토하라

규모가 작은 시스템이라면 애플리케이션 수준에서 더 단순한 변형을 만들 수도 있다. API 요청을 받은 스레드에서 이벤트를 DB에 저장하고 트랜잭션을 끝낸다. 이어서 비동기 스레드로 이벤트를 넘겨 바로 전달한다. 전달에 성공하면 저장된 이벤트의 상태를 갱신한다. 모든 이벤트를 배치가 처리하게 두는 대신, 실패한 전달을 처리할 배치만 남기는 방식이다.

이렇게 하면 폴링의 역할이 달라진다. 배치는 유일한 전달 경로가 아니라 복구 경로가 된다.

  1. 요청 트랜잭션이 이벤트를 기록한다.
  2. 비동기 경로가 즉시 전달을 시도한다.
  3. 성공하면 상태를 갱신한다.
  4. 배치는 성공하지 못한 이벤트를 다시 처리한다.

이 구조는 검토할 후보이지 모든 시스템에 적용할 처방이 아니다. 처음 제기된 문제에는 여기서 보이지 않는 제약이 있을 수 있다. 각 팀은 자신의 애플리케이션에서 트랜잭션 경계, 전달 방식, 실패 처리와 부하를 다시 검증해야 한다.

근거가 생겼을 때 로그 테일링을 더하라

로그 테일링은 DB 로그를 읽어 이벤트를 옮기는 또 다른 방법이며, 중간에 별도 구성 요소가 필요할 수도 있다. 유효한 선택지가 될 수 있지만 팀이 검토하고 운영해야 할 개념과 세부 사항도 늘어난다. 직접 사용한 경험과 해당 서비스의 측정값 없이 언제 전환해야 한다는 보편적인 기준을 단정할 수는 없다.

따라서 기본 선택은 보수적이어야 한다. 현실적인 트래픽으로 폴링 경로를 측정한다. 커넥션과 락이 꼭 필요한 작업 범위에만 걸려 있는지 확인한다. 규모에 맞는다면 즉시 전달하고 배치로 복구하는 애플리케이션 수준의 흐름도 검토한다. 이 선택들이 테스트를 통과하지 못하거나 트래픽 패턴이 감당 범위를 벗어날 때, 더 복잡한 방식을 도입할 구체적인 근거가 생긴다.