Patreon이 팬아웃으로 알림 시스템을 확장한 방법

11 hours ago 4
  • 연간 수십억 건의 알림을 처리해 온 13년 된 시스템은 대형 크리에이터 한 명당 수백만 건을 생성하면서 타임아웃에 부딪혔고, Patreon은 수신자별 알림을 미리 생성하는 팬아웃 계층으로 이를 재설계함
  • 수신자 목록을 작은 배치로 나누고 인앱 피드·푸시·이메일을 독립적으로 처리하는 2단계 팬아웃을 적용해 수평 확장성과 채널 장애 격리를 확보함
  • 대형 크리에이터의 푸시·인앱 피드는 80%, 이메일은 55% 빨라졌으며, 청중이 4배 늘 때 종단 간 지연 증가율도 기존 186%에서 각각 33%와 60%로 낮아짐
  • Notification Factory와 단일 API send_fanout_notifications로 필터링·자격 검사·페이로드 생성을 표준화하고, 단계별 타이밍과 수신자별 결과를 추적해 운영과 디버깅을 단순화함
  • 10개 팀과 30명 이상의 엔지니어가 200개 넘는 알림을 이전했으며, AI 기반 초안 생성과 리더십이 정한 명확한 마감 시한이 반복 작업과 장기 병행 운영을 줄이는 데 기여함

대형 크리에이터가 드러낸 확장 한계

  • Patreon은 크리에이터가 게시물을 발행하거나 라이브스트림을 시작할 때 팬에게 연간 수십억 건의 알림을 보냄
  • 무료 멤버십 출시와 성장으로 크리에이터당 팬 수가 급증하면서, 2025년 초 대형 크리에이터를 중심으로 심각한 성능 병목이 드러남
  • 기존 게시물 알림은 하나의 비동기 작업이 전체 수신자를 가져와 사용자별 설정으로 필터링하고, 각 수신자의 페이로드를 생성한 뒤 인앱 피드·푸시·이메일 전달 시스템으로 넘기는 구조였음
  • 대형 크리에이터의 경우 단일 작업이 수백만 건의 알림 생성을 맡으면서 지속적으로 타임아웃이 발생했고, 대규모 청중에게 알림을 안정적으로 전달하기 어려워짐
  • 기존 흐름에는 두 가지 구조적 한계가 있었음
    • 수신자별 생성 비용이 하나의 비동기 작업에 집중돼 수평 확장이 불가능하고 처리량에 명확한 상한이 생김
    • 인앱 피드·푸시·이메일이 강하게 결합돼 한 채널의 실패가 다른 채널까지 막을 수 있었음
  • 여러 제품 팀이 고용량 알림마다 별도의 확장 방식을 만들면서 단기 문제는 해결했지만, 플랫폼 복잡도가 높아지고 개발·운영·디버깅은 어려워짐
  • 기존 전달 시스템은 유지하되 그 앞에 공통 팬아웃 계층을 배치해 수평 확장성, 채널 격리, 관측 가능성을 제공하기로 함

팬아웃 플랫폼의 여섯 가지 설계 조건

  • 새 계층은 큰 수신자 목록을 작은 배치로 분할하고, 수신자별 알림을 생성한 뒤 기존 인앱 피드·푸시·이메일 시스템으로 전달하도록 설계함
  • 플랫폼에는 다음 여섯 가지 요구사항을 적용함
    • 개발자 친화성: 고용량 알림마다 확장성과 신뢰성을 처음부터 해결할 필요가 없어야 하며, 사용 오류를 줄이면서 다양한 사례를 지원해야 함
    • 수평 확장성: 수신자 목록을 자동으로 작은 배치로 나눠 비동기로 처리해야 함
    • 채널 격리: 인앱 피드·푸시·이메일을 독립적으로 실행해 한 채널의 장애가 다른 채널로 전파되지 않아야 함
    • 우선순위 처리: 시간에 민감한 알림은 전용 큐와 워커 풀을 사용해 일반 알림과 분리해야 함
    • 관측 가능성: 필터링 및 전달 결과를 조사하고 알림 생명주기 전체의 지연 시간을 측정할 수 있어야 함
    • 확장 가능성: 수신자 목록 생성 같은 향후 기능을 또 다른 대규모 리팩터링 없이 추가할 수 있어야 함

Notification Factory로 비즈니스 로직 분리

  • 플랫폼 오케스트레이션과 알림별 비즈니스 로직을 분리하기 위해 Notification Factory 추상화를 도입함
  • 각 팩터리는 알림 처리의 청사진으로 다음 항목을 정의함
    • 처리 우선순위
    • 적용할 알림 설정
    • 수신자 필터링 방식
    • 알림별 자격 검사
    • 채널별 페이로드 생성 방식
  • 이 패턴은 Patreon의 자체 분산 작업 엔진을 기반으로 하며 여러 개념을 공유함
  • Notification 모델은 특정 알림에 고유하면서 모든 수신자가 공유하는 데이터를 담은 작업 인자를 정의함
  • 연결된 BaseNotificationFactory 하위 클래스는 작업 처리기로 동작하며, 수신자를 필터링하고 알림을 생성하는 설정과 메서드를 포함함
  • 직렬화된 알림 페이로드만 받는 팬아웃 작업이 실행할 비즈니스 로직을 찾을 수 있도록, 각 Notification 모델을 해당 팩터리 클래스에 매핑하는 레지스트리를 사용함
  • 다양한 알림 유형을 지원하는 동시에 흔한 구현 오류와 비효율적인 데이터 조회를 막아야 했음
    • Patreon에는 여러 사용자 레코드 유형과 필터링 방식이 있으므로 수신자 인터페이스는 일반화함
    • 사용자 설정과 알림별 자격 검사를 구현할 수 있는 명확한 훅을 제공함

단일 API와 2단계 팬아웃

  • 과거에는 채널마다 별도의 발송 API를 사용해 인앱 피드·푸시·이메일 흐름이 서로 달라질 수 있었고, 제품 팀도 너무 이른 시점부터 채널별 동작을 고려해야 했음
  • 재설계 후 진입점을 단일 API인 send_fanout_notifications 로 통합함
    • 호출 측은 알림 페이로드, 수신자 목록, 전달 지연 측정에 사용할 타임스탬프를 넘김
    • API는 해당 알림의 팩터리를 찾고 배치 크기와 우선순위를 결정한 뒤 채널별 작업을 독립적으로 분산함
    • 한 채널의 실패나 지연이 다른 채널을 막지 않음
  • 첫 번째 단계는 알림 생성 확장을 담당함
    • 전체 수신자 목록을 작은 배치로 분할함
    • 각 배치는 FanoutNotifications 작업이 처리함
    • 작업은 수신자를 필터링하고 알림별 자격 검사를 실행한 뒤 Notification Factory로 채널별 페이로드를 생성함
  • 두 번째 단계는 전달 인계 확장을 맡음
    • 생성된 알림을 인앱 피드·푸시·이메일 전용 전달 작업으로 다시 팬아웃함
  • 핵심인 FanoutNotifications 작업 처리기는 API와 기존 채널 전달 시스템 사이에 위치해, 하나의 거대한 작업을 독립적으로 처리할 수 있는 다수의 작은 작업으로 바꿈

수신자 단위 관측과 디버깅

  • 알림은 사용자가 설정을 비활성화했거나 자격 검사를 통과하지 못했거나 이메일 주소로 전달할 수 없는 경우 등 여러 이유로 실패하거나 건너뛸 수 있음
  • 기존 플랫폼에서는 특정 알림의 처리 결과를 확인하려면 여러 시스템의 로그와 데이터를 조합해야 했고, 포괄적인 수신자별 실행 추적도 없어 조사에 몇 시간이 걸릴 수 있었음
  • 새 플랫폼은 다음 질문에 답할 수 있도록 설계함
    • 알림 발송에 얼마나 걸렸는지
    • 최초 수신자 목록이 얼마나 컸는지
    • 몇 명이 어떤 이유로 필터링됐는지
    • 채널별로 몇 건이 성공적으로 발송됐는지
    • 특정 사용자가 특정 알림을 받거나 받지 않은 이유가 무엇인지
  • 플랫폼 전체로 전달되는 타이밍·로깅 데이터 모델을 도입함
    • 알림 흐름의 각 단계에서 타임스탬프를 기록함
    • 집계 결과와 수신자별 결과 모두에 대해 메트릭과 이벤트를 생성함
    • 개발자는 로깅 속성을 붙여 관련 엔티티를 실행 추적과 이벤트에 포함할 수 있음
  • 관측성, 경보, 대시보드, 디버깅 도구가 개선되면서 제품 엔지니어와 지원 팀이 플랫폼 엔지니어에게 의존하지 않고 더 많은 문제를 조사할 수 있게 됨

200개가 넘는 알림 마이그레이션

  • Notification Factory 패턴은 알림을 개발하고 유지하는 방식 자체를 바꿨기 때문에 단순한 코드 변환 도구(codemod) 만으로 이전할 수 없었음
  • 각 알림의 비즈니스 로직, 데이터 의존성, 자격 규칙, 채널별 동작을 그대로 보존해야 했음
  • 이전 문서와 모범적인 수작업 마이그레이션 PR을 바탕으로 AI 스킬을 구축함
    • 개발자는 /migrate-notif-fanout <notif_name>을 실행해 1차 마이그레이션 결과를 생성할 수 있었음
    • 알림 모델 생성, 팩터리 연결, 호출 지점 수정, 플랫폼 패턴 적용 같은 반복 작업에 효과적이었음
  • AI는 미묘한 비즈니스 로직을 놓치거나 환각을 일으키고 정리가 필요한 중복 코드를 만들 수 있어, 엔지니어의 판단을 대체하지 않았음
  • 200개가 넘는 알림을 마이그레이션했으며, AI 활용을 포함한 대규모 협업으로 남은 80%를 6주 만에 완료함

성능 개선과 제품 개발 효과

  • 수신자별 알림 생성을 수평 확장 가능한 작업으로 옮겨, 크리에이터 한 명당 수백만 건의 알림을 타임아웃 없이 안정적으로 생성할 수 있게 됨
  • 대형 크리에이터의 고용량 알림 성능이 크게 개선됨
    • 푸시와 인앱 피드 알림은 80% 빨라짐
    • 이메일 알림은 55% 빨라짐
    • 청중이 4배 늘 때 푸시·인앱 피드의 종단 간 지연은 33%, 이메일은 60% 증가함
    • 같은 조건에서 기존 플랫폼의 지연 증가율은 186%였음
  • 제품 팀은 고용량 알림마다 별도의 확장 솔루션을 설계할 필요가 없어졌고 개발 속도도 개선됨
  • 새 플랫폼은 2025년의 Lives, Quips, 대형 크리에이터 확보 같은 주요 출시를 지원함
  • 팬아웃 재설계가 없었다면 이들 출시는 기존 병목에 부딪혀 일회성 확장 솔루션을 만드는 데 추가 엔지니어링 시간이 필요했음
  • 단계별 타이밍 메트릭으로 시간이 소비되는 지점을 파악하고, 속도와 비용의 균형에 맞춰 인프라를 조정할 수 있게 됨

9개월 병행 운영과 조직 조율

  • 운영 중인 레거시 시스템을 변경하면서 여러 팀의 마이그레이션을 조율하는 일이 가장 어려운 부분이었음
  • 9개월 동안 두 알림 시스템을 병행 운영
    • 모든 플랫폼 변경이 기존 경로와 새 팬아웃 경로에 모두 호환돼야 했음
    • 버그와 장애가 발생할 수 있는 범위가 커졌고, 마이그레이션이 길어질수록 운영 위험도 늘어남
    • 호환성 문제로 소규모 장애가 몇 차례 발생해 빠르고 안전하게 이전을 끝낼 필요성이 커짐
  • 초기에는 각 제품 팀이 자체적으로 알림 마이그레이션의 우선순위를 정하는 상향식 방식을 택함
    • 6개월 동안 약 20% 를 이전하는 데 그침
    • 제품 로드맵과 다른 팀 우선순위에 밀리면서 진행 속도가 느려짐
  • 엔지니어링 리더십이 2026년 1분기 완료에 합의하고 명확한 마감 시한과 전사 우선순위를 부여한 뒤, 남은 마이그레이션을 6주 만에 완료함
  • 전체 작업에는 10개 팀과 30명 이상의 엔지니어가 참여함
    • Notion 추적기와 자동화로 진행 상황을 관리함
    • 이해관계자와 자주 소통하고 작업을 여러 팀에 분산함
    • 플랫폼 팀이 약 절반의 마이그레이션을 수행한 뒤 알림 소유 팀에 배포와 정리를 넘김
    • 알림이 많은 팀에 작업이 집중되지 않도록 부하를 분산함
  • 오피스 아워, 리더보드, 상품, 해피아워를 포함한 알림 마이그레이션 주간을 열어 진행을 가속하고 완료를 기념함
  • 전체 마감보다 2주 앞서 인계를 끝내는 완충 기간을 확보함
    • 추가 지원이 필요한 팀을 돕고 코드베이스에서 누락된 작업을 검색함
    • 마지막 점검에서 새로 필요한 마이그레이션 4개와 여러 미완료 항목을 찾아 일정에 작은 영향만 주고 마무리함

대규모 플랫폼 이전에서 얻은 교훈

  • 명시적 우선순위가 없으면 여러 팀에 걸친 마이그레이션은 각 팀의 로드맵과 경쟁하며 쉽게 뒤로 밀림
    • 확장 효과가 덜 뚜렷한 저용량 알림의 긴 꼬리 구간에서 특히 두드러짐
    • 리더십 합의, 공동 우선순위, 명확한 마감 시한이 합리적인 기간 안에 이전을 끝내는 데 중요했음
  • 플랫폼 작업은 API에서 끝나지 않음

    • 이전에는 다른 팀의 알림 질문과 전달 문제를 조사하는 일이 플랫폼 엔지니어 온콜 업무의 상당 부분을 차지했음
    • 관측성, 경보, 대시보드, 디버깅 도구를 함께 개선해야 제품 및 지원 팀이 독립적으로 조사할 수 있고 플랫폼 온콜 부담도 줄어듦
    • 현재 병목뿐 아니라 다음 병목도 고려해야 함
    • 한 번의 프로젝트로 모든 알림 확장 문제를 해결할 수는 없었음
    • 향후 기능을 수용할 수 있게 설계해 알림량이 증가할 때 또 다른 대규모 리팩터링이 필요할 가능성을 낮춤

다음 병목과 향후 계획

  • 알림 생성은 확장했지만 다음 병목은 수신자 목록 생성
  • 알림 대상이 계속 커지면 수백만 명의 수신자를 효율적으로 조회하는 일이 점점 더 중요해짐
  • 수신자 목록 생성을 Notification Factory에 포함해 플랫폼이 종단 간 알림 흐름을 더 많이 담당하도록 할 계획임
  • 알림 설정도 개발자와 팬 양쪽에서 개선할 예정임
    • 개발자는 새 설정을 더 쉽게 만들고 관리할 수 있도록 지원함
    • 팬은 알림 선호도를 더 쉽게 이해하고 제어할 수 있도록 개선함
Read Entire Article