# 보내는 쪽과 받는 쪽 사이의 ‘메시지 보관소’

Log Router가 만든 ‘GA4 데이터 도착’ 신호를 받아 두고 후속 처리자(Cloud Function)에게 전달하는 중간 보관소가 Pub/Sub입니다. 유튜브 채널 비유로 발행·구독 구조를 풀어 보고, Push/Pull 두 방식·실제 메시지 모양·비용까지 비개발자도 따라올 수 있게 정리합니다.

- 카테고리: BigQuery
- 소요 시간: 약 6분
- 난이도: 입문
- 업데이트: 2026.05.28
- 원문: /wiki/playbook/bigquery-checklist/what-is-pubsub

## 목차

- [왜 Pub/Sub이 필요한가](#why)
- [Pub/Sub을 한 문장으로 — ‘유튜브 채널 같은 구조’](#concept)
- [구성 요소 — 토픽·메시지·구독](#parts)
- [메시지 받는 두 가지 방식 — Push vs Pull](#modes)
- [GA4 자동화에서 실제로 받는 메시지](#ga4-message)
- [비용 — GA4 규모에선 사실상 0원](#cost)
- [자주 묻는 질문](#faq)

[**Log Router**](/wiki/playbook/bigquery-checklist/what-is-log-router)가 “GA4 데이터가 도착했다”는 신호 한 건을 만들었다고 해도, 그 신호를 받아 줄 누군가가 있어야 다음 동작이 일어납니다. 그런데 받는 쪽이 그 순간 항상 깨어 있을 거라는 보장이 없습니다. 이 ‘보내는 쪽과 받는 쪽이 시간을 맞추지 않아도 되게’ 중간에서 메시지를 보관·전달해 주는 서비스가 Google Cloud의 **Pub/Sub**입니다. 이 글은 Pub/Sub이 무엇인지, 왜 분석 자동화에 잘 맞는지를 비개발자도 따라올 수 있게 풀어 봅니다.

## 왜 Pub/Sub이 필요한가

Log Router가 만들어 낸 신호를 받아 다음 동작(평탄화 마트 갱신)을 시작하는 주체는 잠시 뒤 다룰 **Cloud Function**입니다. 그런데 Cloud Function은 ‘평소엔 꺼져 있다가, 부르면 잠깐 깨어나서 일하고 다시 꺼지는’ 식으로 동작합니다. Log Router가 신호를 보내는 순간 Cloud Function이 꺼져 있을 수도 있고, 잠깐 장애가 났을 수도 있습니다.

이때 필요한 것이 ‘**중간 보관소**’입니다.

- 보내는 쪽(Log Router)은 보관소에 신호 한 건을 넣어 두기만 합니다.
- 받는 쪽(Cloud Function)은 자기 사정에 맞춰 보관소에서 신호를 꺼내 옵니다.
- 받는 쪽이 잠깐 꺼져 있어도 신호는 보관소에 남아 있고, 깨어났을 때 안전하게 받을 수 있습니다.

이 ‘중간 보관소’의 표준 이름이 **메시지 큐(message queue)**이고, Google Cloud가 제공하는 매니지드 메시지 큐가 **Pub/Sub**입니다.

## Pub/Sub을 한 문장으로 — ‘유튜브 채널 같은 구조’

Pub/Sub은 ‘**발행(Publish) / 구독(Subscribe)**’의 줄임말이고, 동작 방식은 우리가 익숙한 **유튜브 채널**과 똑같습니다.

| 유튜브 | Pub/Sub | 의미 |
| --- | --- | --- |
| 채널 | **토픽(Topic)** | 메시지를 받아 두는 공간(이름으로 식별) |
| 새 영상 업로드 | **메시지 발행(Publish)** | 토픽에 한 건의 데이터를 넣음 |
| 채널 구독 | **구독(Subscription)** | 토픽의 메시지를 받아 가겠다는 약속 |
| 알림 받은 사람 | **구독자(Subscriber)** | 구독을 통해 메시지를 실제로 받아 처리하는 주체(예: Cloud Function) |

유튜브 채널의 운영자는 자기 영상을 누가 보고 있는지·몇 명이 구독했는지를 일일이 신경 쓰지 않고도 영상을 올립니다. 시청자도 채널 운영자가 누군지 모르고 영상을 받아 봅니다. Pub/Sub의 ‘보내는 쪽-받는 쪽 분리’도 이와 똑같습니다. 이 분리 덕분에 한쪽이 바뀌어도 다른 쪽에 영향이 없습니다.

> **팁**
>
> **왜 자동화에 잘 맞나** — “Log Router가 잘 만들고 보내기만 하면 된다 / Cloud Function은 받아서 자기 일만 하면 된다”는 명확한 역할 분리가 가능합니다. 또 받는 쪽이 잠깐 죽어도 메시지는 토픽에 남아 있어 신호 유실이 거의 없습니다.

## 구성 요소 — 토픽·메시지·구독

한 토픽에는 여러 구독을 함께 매달 수 있습니다. 즉 같은 메시지를 ‘분석 자동화용’과 ‘슬랙 알림용’ 두 개의 구독이 동시에 받아 갈 수도 있습니다. 라디오 채널 한 개를 여러 사람이 동시에 듣는 것과 같은 그림입니다.

- **토픽 1개 + 구독 1개** — 가장 단순한 모양. GA4 자동화의 기본 구성.
- **토픽 1개 + 구독 여러 개** — 같은 신호를 여러 후속 동작에 동시에 보낼 때(예: 마트 갱신 + 슬랙 알림).
- **같은 구독에 작업자 여러 명** — 메시지가 한 번씩만 분산 처리됨. 큐잉이 필요한 백엔드 작업에 자주 쓰는 패턴.

GA4 자동화에서는 ‘토픽 1개 + 구독 1개 + 구독자(Cloud Function) 1개’ 단순 구성으로 시작하면 충분합니다.

### Pub/Sub 페이지 둘러보기

Cloud Console > 좌측 메뉴 **Pub/Sub** > **주제(Topics)**로 들어가면 현재 프로젝트의 토픽 목록이 한눈에 펼쳐집니다. ‘이 안에 GA4 자동화용 토픽을 한 개 추가하는 게 우리가 할 일’ 이라고 보면 됩니다.

![Google Cloud Console Pub/Sub 주제 목록 화면. 좌측 사이드바에 Pub/Sub 섹션이 펼쳐져 있고 '개요·주제(선택됨)·구독·스냅샷·스키마' 메뉴가 나열되어 있다. 상단에는 hurdlers-web 프로젝트가 선택돼 있고 '주제 만들기·복사·삭제·태그' 버튼이 있다. 본문은 표 형태로 주제 ID·암호화 키·주제 이름·보관·수집 소스 컬럼이 있고, 'ga4-daily-export-complete'·'container-analysis-notes-v1'·'topic_meta_ads_insight' 등 6개의 주제가 활성 상태로 나열되어 있다. 우측에는 'Generate a Transform with AI'·'AI 추론 SMT로 Pub/Sub 메시지 보강' 같은 안내 카드가 보인다.](/wiki-assets/playbook/what-is-pubsub/01-topics-list.png)

> **화면 1.** Pub/Sub > 주제. 위 화면의 `ga4-daily-export-complete`가 ‘GA4 데이터 도착 신호를 받는 토픽’의 예시입니다. 좌측 상단 *+ 주제 만들기* 버튼으로 새 토픽을 추가합니다.

## 메시지 받는 두 가지 방식 — Push vs Pull

구독을 만들 때 ‘메시지를 어떻게 받을지’를 정합니다. 두 방식이 있고, 분석 자동화에서는 보통 **Push**를 씁니다.

| 방식 | 비유 | 동작 | 잘 맞는 곳 |
| --- | --- | --- | --- |
| **Push** | 택배 ‘배달’ | 메시지가 도착하면 Pub/Sub이 받는 쪽으로 즉시 전달 | Cloud Function·웹훅·외부 알림 |
| **Pull** | 택배 보관함 직접 확인 | 받는 쪽이 ‘메시지 있어?’를 주기적으로 물어 봄 | 장기 실행 작업자·백엔드 큐 워커 |

> **팁**
>
> **왜 Push가 GA4 자동화의 표준** — Cloud Function은 ‘메시지가 오면 깨어나서 잠깐 일하고 꺼지는’ 구조에 잘 맞습니다. 직접 폴링하는 Pull은 ‘평소엔 깨어 있어야 한다’는 전제가 있어 자동화 비용·구조가 복잡해집니다.

## GA4 자동화에서 실제로 받는 메시지

Log Router가 토픽에 발행하는 메시지의 본문은 ‘**원본 로그 한 건 그대로**’입니다. 메시지를 받아 본 Cloud Function이 다음 같은 JSON을 손에 쥡니다(중요한 부분만 발췌).

**실제로 도착하는 메시지(요약)**
```json
{
  "protoPayload": {
    "serviceName": "bigquery.googleapis.com",
    "resourceName": "projects/hurdlers-web/datasets/analytics_502771866/tables/events_20260527",
    "metadata": {
      "tableCreation": {
        "reason": "QUERY_DESTINATION_TABLE"
      }
    }
  },
  "timestamp": "2026-05-28T03:24:11.812Z"
}
```

이 JSON에서 우리가 보통 꺼내 쓰는 정보는 두 가지입니다.

- **새로 들어온 일별 테이블 이름** — `resourceName`의 끝부분 `events_YYYYMMDD`. 어느 날짜의 데이터가 들어왔는지를 알려 줍니다.
- **발생 시각** — `timestamp`. 신호가 만들어진 시점.

Cloud Function은 이 두 가지로 ‘오늘 들어왔으니 이 날짜 기준으로 평탄화 SQL을 한 번 돌리자’라는 판단을 내립니다. 자세한 코드 흐름은 **Cloud Function / Cloud Run이란? ** 글과 **GA4 export 시점에 예약쿼리 업데이트하는 방법** 글에서 이어집니다.

## 비용 — GA4 규모에선 사실상 0원

### Pub/Sub 매월 무료 한도

메시지 송수신량**첫 10 GB**

이후 단가(예시)**약 $40 / TB 송수신**

GA4 자동화의 실제 트래픽**하루 GA4 속성당 한 건, 한 건 약 1 KB 미만**

GA4 데이터 도착 신호는 GA4 속성당 하루 한 건 수준이라, 한 달 합산해도 무료 한도의 만분의 일도 못 채우는 규모입니다. 실질 청구액은 0원입니다.

비용보다 자주 신경 쓸 항목은 **메시지 보관 기간**입니다. 기본 7일이고 최대 31일까지 늘릴 수 있습니다. 받는 쪽이 그 안에 한 번도 메시지를 가져가지 못하면 보관소에서 자동 삭제되니, 자동화를 처음 만든 직후에는 ‘Cloud Function이 정말 메시지를 받는지’를 며칠 모니터링해 두는 게 안전합니다.

## 자주 묻는 질문

### Pub/Sub 메시지에는 GA4 분석 데이터 자체가 들어오나요?

아닙니다. ‘**BigQuery에 새 테이블이 생겼다**’는 메타 신호 한 건만 들어옵니다. 실제 데이터는 그대로 BigQuery에 있고, Pub/Sub은 ‘이제 마트 갱신을 돌릴 시점’이라는 트리거로만 쓰입니다.

### Cloud Function이 잠깐 꺼져 있으면 메시지가 사라지나요?

아닙니다. 기본 보관 기간(7일) 안에는 Pub/Sub이 메시지를 보관하고, 받는 쪽이 처리에 실패하면 자동으로 재시도합니다. 받는 쪽이 며칠 죽어 있어도 ‘한 번이라도 성공할 때까지’ 안전하게 보관해 줍니다.

### 여러 구독자가 같은 메시지를 받게 하려면?

같은 토픽에 **구독을 여러 개 만들면** 됩니다. 예: 구독 A는 마트 갱신용 Cloud Function에 Push, 구독 B는 슬랙 알림용 다른 서비스에 Push. 두 구독이 같은 메시지를 각각 한 번씩 받습니다(브로드캐스트). 한 구독에 작업자를 여러 개 붙이는 경우엔 메시지가 한 번씩만 분산 처리됩니다.

### 메시지가 두 번 도착할 수도 있나요?

Pub/Sub은 ‘**최소 한 번(at-least-once)**’ 도착을 보장합니다 — 즉 두 번 도착할 가능성이 있습니다. Cloud Function 쪽에서 ‘오늘 이 날짜의 마트를 이미 갱신했으면 건너뛴다’ 같은 안전장치를 두면 중복 처리로 인한 문제가 사라집니다.

### 테스트로 메시지를 한 번 직접 발행해 볼 수 있나요?

네. Cloud Console > Pub/Sub > 토픽 화면의 **‘메시지 게시’** 버튼으로 임의 본문을 직접 발행할 수 있습니다. 자동화를 만든 직후 ‘Cloud Function이 정말 깨어나는지’ 점검하는 가장 빠른 방법입니다.

### Cloud Tasks·Eventarc 같은 서비스와는 어떻게 다른가요?

Pub/Sub은 ‘**이벤트 브로드캐스트**’에 특화된 메시지 큐입니다. Cloud Tasks는 ‘이 시각에 정확히 한 번 실행해라’ 같은 작업 스케줄링에, Eventarc는 다양한 클라우드 이벤트를 한 자리에서 받아 라우팅하는 데 더 어울립니다. ‘발생 즉시 후속 동작 트리거’ 패턴이라면 Pub/Sub이 가장 단순하고 안정적입니다.

## Navigation

- [전체 플레이북 Markdown sitemap](/wiki/playbook/sitemap.md)

### BigQuery

- [BigQuery](/wiki/playbook/bigquery-checklist)
- [BigQuery 온보딩](/wiki/playbook/bigquery-checklist/bigquery-onboarding-guide)
- [BigQuery 인증 설정](/wiki/playbook/bigquery-checklist/how-to-set-up-bigquery-authentication)
- [BigQuery 데이터셋·테이블 설계](/wiki/playbook/bigquery-checklist/bigquery-dataset-and-table-design-guide)
- [BigQuery 쿼리·비용 제어](/wiki/playbook/bigquery-checklist/bigquery-query-and-cost-control-guide)
- [BigQuery 쓰기·MERGE·CDC](/wiki/playbook/bigquery-checklist/bigquery-data-write-and-cdc-guide)
- [BigQuery 코드 예제 모음](/wiki/playbook/bigquery-checklist/bigquery-code-examples)
- [BigQuery로 들어오는 GA4 데이터](/wiki/playbook/bigquery-checklist/what-is-ga4-data-in-bigquery)
- [BigQuery Studio 인터페이스 이해하기](/wiki/playbook/bigquery-checklist/what-is-bigquery-studio-interface)
- [BigQuery 예상 비용](/wiki/playbook/bigquery-checklist/how-to-estimate-bigquery-costs)
- [무료 버전(샌드박스) 해제해야 하는 이유](/wiki/playbook/bigquery-checklist/why-upgrade-from-bigquery-sandbox)
- [GA4 BigQuery 데이터를 왜 평탄화해야 하나](/wiki/playbook/bigquery-checklist/why-flatten-ga4-bigquery-data)
- [Log Router란?](/wiki/playbook/bigquery-checklist/what-is-log-router)
- [Pub/Sub이란?](/wiki/playbook/bigquery-checklist/what-is-pubsub) (현재 문서)
- [Cloud Functions이란?](/wiki/playbook/bigquery-checklist/what-is-cloud-function-and-run)
- [GA4 export 시점에 예약 쿼리 자동 실행하기](/wiki/playbook/bigquery-checklist/how-to-trigger-scheduled-query-on-ga4-export)
- [테이블 정의서는 왜 필요한가](/wiki/playbook/bigquery-checklist/why-table-definition-doc)
- [Event_Flat 테이블 이해하기](/wiki/playbook/bigquery-checklist/what-is-event-flat-table)
- [Item_Performance 테이블 이해하기](/wiki/playbook/bigquery-checklist/what-is-item-performance-table)
