서버리스 외부 스토리지 동기화 트레이드오프

#serverless#google-drive#github-actions#sync#architecture
• • •

TL;DR: 서버리스 환경은 상태와 지속성을 갖지 않으므로, 외부 스토리지 동기화는 변경 감지와 상태 관리 책임을 외부 시스템으로 오프로딩해야 하며, 이때 실시간성 대 운영 복잡성, API 접근 대 로컬 마운트 접근의 선택이 주요 트레이드오프다.

서버리스 환경(예: Vercel, AWS Lambda)에서 외부 스토리지(예: Google Drive, S3)의 변경 사항을 감지하고 애플리케이션 코드 저장소와 동기화하는 작업은 환경의 고유한 제약으로 인해 몇 가지 설계적 선택을 요구한다. 핵심 제약은 ephemeral 파일 시스템, 제한된 실행 시간, 그리고 로컬 마운트된 스토리지 접근 불가다. 이는 동기화 흐름을 '변경 감지 → 콘텐츠 획득 → 저장소 반영'의 단계로 분해할 때 각 단계마다 다른 접근법을 강제한다.

변경 감지 메커니즘 선택은 실시간성과 운영 부담 사이의 트레이드오프를 만든다. 외부 스토리지의 공식 webhook(예: Google Drive changes.watch)을 사용하면 거의 실시간으로 알림을 받을 수 있지만, webhook 채널은 일정 기간(예: 1주일) 후 만료되어 주기적인 갱신 작업이 필요하다. 이 갱신 작업 자체를 서버리스 함수에 맡기면 또 다른 cron-like 트리거가 필요해져 운영 복잡성이 증가한다. 반면, GitHub Actions의 schedule 이벤트나 클라우드 cron 서비스를 이용한 주기적 폴링은 구현이 단순하고 채널 관리 부담이 없지만, 변경 발생과 동기화 실행 사이에 지연이 발생한다. 문서 동기화와 같은 비실시간적 사용 사례에서는 폴링 방식이 종합적으로 더 낮은 운영 비용을 가진다.

콘텐츠 획득 단계에서는 로컬 마운트 접근클라우드 API 접근의 근본적 차이가 나타난다. 서버리스 함수는 호스트 머신의 로컬 파일 시스템(예: Google Drive Desktop이 마운트한 폴더)에 접근할 수 없다. 따라서 기존의 로컬 스크립트(rsync 또는 파일 복사) 방식은 서버리스 환경에서 동작하지 않는다. 대신 외부 스토리지의 공식 API(예: Google Drive API)를 통해 파일 메타데이터와 내용을 직접 다운로드해야 한다. 이 전환은 단순한 접근법 변경을 넘어, API 인증(Service Account 또는 OAuth), 요율 제한(Rate Limit) 처리, 그리고 바이너리 에셋(이미지) 다운로드 전략까지 함께 고려해야 함을 의미한다.

동기화 상태 관리는 서버리스의 stateless 특성과 충돌한다. 효율적인 증분 동기화를 위해서는 마지막으로 처리한 변경 지점(예: Google Drive의 startPageToken)을 영구적으로 저장해야 한다. 이 상태를 서버리스 함수의 임시 환경에 저장하면 다음 실행 시 분실된다. 해결책은 상태 저장소를 외부로 두는 것이다: 1) 동기화 대상이 되는 Git 저장소 내부에 상태 파일을 커밋하는 방식, 2) 외부 데이터베이스나 키-값 저장소를 사용하는 방식. Git 저장소 내부에 상태를 저장하는 방식은 동기화 작업 자체가 Git 커밋을 수행하는 경우 특히 자연스럽다. 상태 파일을 커밋하면, 다음 동기화 실행 시 해당 파일을 읽어 마지막 지점부터 이어서 작업할 수 있다.

Git 작업(커밋, 푸시) 자체를 서버리스 함수 내에서 수행하는 것은 가능하지만 권장되지 않는다. 함수 실행 환경에 Git 클라이언트를 설치하고, 충분한 디스크 공간을 확보하며, 네트워크 타임아웃 내에 푸시를 완료해야 하는 부담이 있다. 더 견고한 패턴은 Git 작업을 그에 특화된 환경으로 오프로딩하는 것이다. 가장 일반적인 방법은 GitHub Actions를 활용하는 것이다. 즉, 서버리스 함수(또는 webhook 수신기)는 변경 감지만 하고, 실제 동기화 및 Git 커밋/푸시 작업을 트리거하는 repository_dispatch 이벤트를 발생시킨다. 혹은, 앞서 설명한 폴링 방식을 채택한다면 GitHub Actions 워크플로우가 cron으로 실행되어 변경 감지, 콘텐츠 획득, Git 작업을 모두 한곳에서 처리하도록 통합할 수 있다. 이렇게 하면 Git 운영에 최적화된 환경을 활용하고, 서버리스 함수의 제약에서 벗어날 수 있다.

Google Drive를 진실의 원천(Source of Truth)으로 사용하는 블로그 콘텐츠 동기화 사례에서, 최종적으로 채택 가능한 아키텍처는 GitHub Actions의 schedule 이벤트를 통해 Drive API로 변경을 폴링하고, 변경된 Markdown 파일을 애플리케이션 저장소의 해당 디렉토리(docs/blog, docs/note)에 쓰며, 변경 사항이 있으면 자동으로 커밋하고 푸시하는 방식이다. 이 방식은 webhook 채널 관리가 필요 없으며, Git 작업을 가장 자연스러운 환경에서 수행하고, 서버리스 런타임의 제약을 완전히 회피한다.

관련 항목

  • Google Drive Changes API
  • GitHub Actions Self-Hosted Runner
  • Idempotent Sync Pattern
  • Serverless State Management

Open questions

  • Google Drive API의 changes.list를 사용한 증분 동기화 시, 삭제된 파일을 어떻게 안정적으로 감지하고 저장소에서도 제거할 것인가?
  • Service Account를 사용해 Drive에 접근할 때, '내 드라이브'가 아닌 '공유 드라이브'의 특정 폴더만 접근 권한을 제한하는 최소 권한 정책은 어떻게 구성하는가?
published 10 days ago · last updated 10 days ago