이 페이지에서는 Pub/Sub에서 읽고 BigQuery에 쓰는 Dataflow 스트리밍 작업의 성능 특성을 설명합니다. 두 가지 유형의 스트리밍 파이프라인에 대한 벤치마크 테스트 결과를 제공합니다.
맵 전용 (메시지별 변환): 스트림에서 상태를 추적하거나 요소를 그룹화하지 않고 메시지별 변환을 수행하는 파이프라인입니다. 예로는 ETL, 필드 유효성 검사, 스키마 매핑이 있습니다.
창 집계 (
GroupByKey): 상태 저장 작업을 수행하고 키와 시간 창을 기반으로 데이터를 그룹화하는 파이프라인입니다. 예로는 이벤트 수 계산, 합계 계산, 사용자 세션 레코드 수집이 있습니다.
스트리밍 데이터 통합을 위한 대부분의 워크로드는 이 두 가지 카테고리에 속합니다. 파이프라인이 유사한 패턴을 따르는 경우 이러한 벤치마크를 사용하여 성능이 우수한 참조 구성에 대해 Dataflow 작업을 평가할 수 있습니다.
테스트 방법
벤치마크는 다음 리소스를 사용하여 수행되었습니다.
일정한 입력 부하가 있는 사전 프로비저닝된 Pub/Sub 주제. 메시지는 스트리밍 데이터 생성기 템플릿을 사용하여 생성되었습니다.
- 메시지 비율: 초당 약 1,000,000개의 메시지
- 입력 부하: 1GiB/초
- 메시지 형식: 고정 스키마가 있는 임의로 생성된 JSON 텍스트
- 메시지 크기: 메시지당 약 1KiB
표준 BigQuery 테이블.
BigQuery에 대한 Pub/Sub 템플릿을 기반으로 하는 Dataflow 스트리밍 파이프라인. 이러한 파이프라인은 최소한의 필수 파싱 및 스키마 매핑을 수행합니다. 커스텀 사용자 정의 함수 (UDF)는 사용되지 않았습니다.
수평 확장이 안정화되고 파이프라인이 안정적인 상태에 도달한 후 파이프라인은 약 하루 동안 실행되도록 허용되었으며, 그 후 결과가 수집되고 분석되었습니다.
Dataflow 파이프라인
두 가지 파이프라인 변형이 테스트되었습니다.
맵 전용 파이프라인. 이 파이프라인은 JSON 메시지의 간단한 매핑 및 변환을 수행합니다. 이 테스트에서는 BigQuery에 대한 Pub/Sub 템플릿 이 수정 없이 사용되었습니다.
- 시맨틱스: 파이프라인은 정확히 한 번 모드와 적어도 한 번 모드를 모두 사용하여 테스트되었습니다. 적어도 한 번 처리를 사용하면 처리량이 향상됩니다. 하지만 중복 레코드가 허용되거나 다운스트림 싱크에서 중복 삭제를 처리하는 경우에만 사용해야 합니다.
창 집계 파이프라인. 이 파이프라인은 고정 크기 창에서 특정 키별로 메시지를 그룹화하고 집계된 레코드를 BigQuery에 씁니다. 이 테스트에서는 BigQuery에 대한 Pub/Sub 템플릿을 기반으로 하는 커스텀 Apache Beam 파이프라인 이 사용되었습니다.
집계 로직: 고정된 겹치지 않는 1분 창마다 키가 동일한 메시지가 수집되어 단일 집계 레코드로 BigQuery에 작성되었습니다. 이러한 유형의 집계는 일반적으로 로그 처리에서 사용자의 활동과 같은 관련 이벤트를 다운스트림 분석을 위한 단일 레코드로 결합하는 데 사용됩니다.
키 동시 로드: 벤치마크는 균일하게 분포된 1,000,000개의 키를 사용했습니다.
시맨틱스: 파이프라인은 정확히 한 번 모드를 사용하여 테스트되었습니다. 집계에는 정확성을 보장하고 그룹 및 창 내에서 중복 집계를 방지하기 위해 정확히 한 번의 시맨틱스가 필요합니다.
작업 구성
다음 표에서는 Dataflow 작업이 구성된 방식을 보여줍니다.
| 설정 | 맵 전용, 정확히 한 번 | 맵 전용, 적어도 한 번 | 창 집계, 정확히 한 번 |
|---|---|---|---|
| 작업자 머신 유형 | n1-standard-2 |
n1-standard-2 |
n1-standard-2 |
| 작업자 머신 vCPU | 2 | 2 | 2 |
| 작업자 머신 RAM | 7.5 GiB | 7.5 GiB | 7.5 GiB |
| 작업자 머신 영구 디스크 | 표준 영구 디스크 (HDD), 30GB | 표준 영구 디스크 (HDD), 30GB | 표준 영구 디스크 (HDD), 30GB |
| 초기 작업자 | 70 | 30 | 180 |
| 최대 작업자 수 | 100 | 100 | 250 |
| Streaming Engine | 예 | 예 | 예 |
| 수평식 자동 확장 | 예 | 예 | 예 |
| 청구 모델 | 리소스 기반 청구 | 리소스 기반 청구 | 리소스 기반 청구 |
| Storage Write API (gRPC)가 사용 설정되었나요? | 예 | 예 | 예 |
| Storage Write API (gRPC) 스트림 | 200 | 해당 없음 | 500 |
| Storage Write API (gRPC) 트리거 빈도 | 5초 | 해당 없음 | 5초 |
BigQuery Storage Write API (gRPC)는 스트리밍 파이프라인에 권장됩니다. Storage Write API (gRPC)와 함께 정확히 한 번 모드를 사용하는 경우 다음 설정을 조정할 수 있습니다.
쓰기 스트림 수. 쓰기 단계에서 충분한 키 동시 로드를 보장하려면 BigQuery 쓰기 스트림 처리량을 적절한 수준으로 유지하면서 Storage Write API (gRPC) 스트림 수를 작업자 CPU 수보다 큰 값으로 설정합니다.
트리거 빈도. 한 자리 수의 초 값은 처리량이 많은 파이프라인에 적합합니다.
자세한 내용은 Dataflow에서 BigQuery로 쓰기를 참조하세요.
벤치마크 결과
이 섹션에서는 벤치마크 테스트 결과를 설명합니다.
처리량 및 리소스 사용량
다음 표에서는 파이프라인 처리량 및 리소스 사용량에 대한 테스트 결과를 보여줍니다.
| 결과 | 맵 전용, 정확히 한 번 | 맵 전용, 적어도 한 번 | 창 집계, 정확히 한 번 |
|---|---|---|---|
| 작업자당 입력 처리량 | 평균: 17MBps, n=3 | 평균: 21MBps, n=3 | 평균: 6MBps, n=3 |
| 모든 작업자의 평균 CPU 사용률 | 평균: 65%, n=3 | 평균: 69%, n=3 | 평균: 80%, n=3 |
| 워커 노드 수 | 평균: 57, n=3 | 평균: 48, n=3 | 평균: 169, n=3 |
| 시간당 Streaming Engine 컴퓨팅 단위 | 평균: 125, n=3 | 평균: 46, n=3 | 평균: 354, n=3 |
자동 확장 알고리즘은 대상 CPU 사용률 수준에 영향을 줄 수 있습니다. 대상 CPU 사용률을 높이거나 낮추려면 자동 확장 범위 또는 작업자 사용률 힌트를 설정하면 됩니다. 사용률 대상이 높을수록 비용이 절감될 수 있지만 특히 부하가 변동하는 경우 꼬리 지연 시간이 더 길어질 수 있습니다.
창 집계 파이프라인의 경우 집계 유형, 창 크기, 키 동시 로드가 리소스 사용량에 큰 영향을 미칠 수 있습니다.
지연 시간
다음 표에서는 파이프라인 지연 시간에 대한 벤치마크 결과를 보여줍니다.
| 총 스테이지 엔드 투 엔드 지연 시간 | 맵 전용, 정확히 한 번 | 맵 전용, 적어도 한 번 | 창 집계, 정확히 한 번 |
|---|---|---|---|
| P50 | 평균: 800ms, n=3 | 평균: 160ms, n=3 | 평균: 3,400ms, n=3 |
| P95 | 평균: 2,000ms, n=3 | 평균: 250ms, n=3 | 평균: 13,000ms, n=3 |
| P99 | 평균: 2,800ms, n=3 | 평균: 410ms, n=3 | 평균: 25,000ms, n=3 |
테스트에서는 3개의 장기 실행 테스트 실행에서 스테이지별 엔드 투 엔드 지연 시간
(job/streaming_engine/stage_end_to_end_latencies
측정항목)을 측정했습니다. 이 측정항목은 Streaming Engine이 각 파이프라인 스테이지에서 소비하는 시간을 측정합니다. 여기에는 다음과 같은 파이프라인의 모든 내부 단계가 포함됩니다.
- 처리를 위한 메시지 셔플링 및 대기열 처리
- 실제 처리 시간(예: 메시지를 행 객체로 변환)
- 영구 상태 쓰기 및 영구 상태를 쓰기 위해 대기열에 소요된 시간
또 다른 지연 시간 측정항목은 데이터 최신 상태입니다. 하지만 데이터 최신 상태는 사용자 정의 창 및 소스의 업스트림 지연과 같은 요인에 영향을 받습니다. 시스템 지연 시간은 부하가 걸린 파이프라인의 내부 처리 효율성과 상태에 대한 보다 객관적인 기준선을 제공합니다.
데이터는 실행당 약 하루 동안 측정되었으며, 안정적인 정상 상태 성능을 반영하기 위해 초기 시작 기간은 삭제되었습니다. 결과에는 추가 지연 시간을 유발하는 두 가지 요인이 표시됩니다.
정확히 한 번 모드. 정확히 한 번의 시맨틱스를 구현하려면 중복 삭제를 위해 결정적 셔플링 및 영구 상태 조회가 필요합니다. 적어도 한 번 모드는 이러한 단계를 우회하므로 훨씬 더 빠르게 실행됩니다.
창 집계. 창이 닫히기 전에 메시지를 완전히 셔플링하고 버퍼링하여 영구 상태에 써야 하므로 엔드 투 엔드 지연 시간이 늘어납니다.
여기에 표시된 벤치마크는 기준선을 나타냅니다. 지연 시간은 파이프라인 복잡성에 매우 민감합니다. 커스텀 UDF, 추가 변환, 복잡한 창 로직은 모두 지연 시간을 늘릴 수 있습니다. 합계 및 개수와 같은 간단하고 감소율이 높은 집계는 요소를 목록으로 수집하는 것과 같은 상태가 많은 작업보다 지연 시간이 짧은 경향이 있습니다.
예상 비용
Google Cloud 가격 계산기를 사용하여 다음과 같이 리소스 기반 청구로 자체의 유사한 파이프라인의 기준 비용을 추정할 수 있습니다.
- 가격 계산기를 엽니다.
- 합산하여 추정 을 클릭합니다.
- Dataflow를 선택합니다.
- 서비스 유형으로 'Dataflow Classic'을 선택합니다.
- 고급 설정 을 선택하여 전체 옵션 집합을 표시합니다.
- 작업이 실행되는 위치를 선택합니다.
- 작업 유형으로 "스트리밍"을 선택합니다.
- Streaming Engine 사용 설정 을 선택합니다.
- 작업 실행 시간, 워커 노드, 작업자 머신, 영구 디스크 스토리지에 대한 정보를 입력합니다.
- Streaming Engine 컴퓨팅 단위의 예상 개수를 입력합니다.
리소스 사용량과 비용은 입력 처리량에 따라 대략 선형적으로 확장되지만 작업자가 몇 명에 불과한 소규모 작업의 경우 총비용은 고정 비용이 지배합니다. 시작점으로 벤치마크 결과에서 워커 노드 수와 리소스 소비량을 추정할 수 있습니다.
예를 들어 입력 데이터 전송률이 100MiB/초인 정확히 한 번 모드에서 맵 전용 파이프라인을 실행한다고 가정해 보세요. 1GiB/초 파이프라인의 벤치마크 결과를 기반으로 다음과 같이 리소스 요구사항을 추정할 수 있습니다.
- 확장 계수: (100MiB/초) / (1GiB/초) = 0.1
- 예상 워커 노드: 작업자 57명 × 0.1 = 작업자 5.7명
- 시간당 예상 Streaming Engine 컴퓨팅 단위 수: 125 × 0.1 = 시간당 12.5개 단위
이 값은 초기 추정치로만 사용해야 합니다. 실제 처리량과 비용은 머신 유형, 메시지 크기 분포, 사용자 코드, 집계 유형, 키 동시 로드, 창 크기와 같은 요인에 따라 크게 달라질 수 있습니다. 자세한 내용은 Dataflow 비용 최적화 권장사항을 참조하세요.
테스트 파이프라인 실행
이 섹션에서는
gcloud dataflow flex-template run
명령어를 보여줍니다.
정확히 한 번 모드
gcloud dataflow flex-template run JOB_ID \
--template-file-gcs-location gs://dataflow-templates-us-central1/latest/flex/PubSub_to_BigQuery_Flex \
--enable-streaming-engine \
--num-workers 70 \
--max-workers 100 \
--parameters \
inputSubscription=projects/PROJECT_IDsubscriptions/SUBSCRIPTION_NAME,\
outputTableSpec=PROJECT_ID:DATASET.TABLE_NAME,\
useStorageWriteApi=true,\
numStorageWriteApiStreams=200 \
storageWriteApiTriggeringFrequencySec=5
적어도 한 번 모드
gcloud dataflow flex-template run JOB_ID \
--template-file-gcs-location gs://dataflow-templates-us-central1/latest/flex/PubSub_to_BigQuery_Flex \
--enable-streaming-engine \
--num-workers 30 \
--max-workers 100 \
--parameters \
inputSubscription=projects/PROJECT_ID/subscriptions/SUBSCRIPTION_NAME,\
outputTableSpec=PROJECT_ID:DATASET.TABLE_NAME,\
useStorageWriteApi=true \
--additional-experiments streaming_mode_at_least_once
다음을 바꿉니다.
JOB_ID: Dataflow 작업 IDPROJECT_ID: 프로젝트 IDSUBSCRIPTION_NAME: Pub/Sub 구독의 이름DATASET: BigQuery 데이터 세트의 이름TABLE_NAME: BigQuery 테이블의 이름
테스트 데이터 생성하기
테스트 데이터를 생성하려면 다음 명령어를 사용하여 스트리밍 데이터 생성기 템플릿을 실행합니다.
gcloud dataflow flex-template run JOB_ID \
--template-file-gcs-location gs://dataflow-templates-us-central1/latest/flex/Streaming_Data_Generator \
--num-workers 70 \
--max-workers 100 \
--parameters \
topic=projects/PROJECT_ID/topics/TOPIC_NAME,\
qps=1000000,\
maxNumWorkers=100,\
schemaLocation=SCHEMA_LOCATION
다음을 바꿉니다.
JOB_ID: Dataflow 작업 IDPROJECT_ID: 프로젝트 IDTOPIC_NAME: Pub/Sub 주제의 이름SCHEMA_LOCATION: Cloud Storage의 스키마 파일 경로
스트리밍 데이터 생성기 템플릿은 JSON 데이터 생성기 파일을 사용하여 메시지 스키마를 정의합니다. 벤치마크 테스트에서는 다음과 유사한 메시지 스키마를 사용했습니다.
{ "logStreamId": "{{integer(1000001,2000000)}}", "message": "{{alphaNumeric(962)}}" }
다음 단계
- Dataflow 작업 모니터링 인터페이스 사용
- Dataflow 비용 최적화 권장사항
- 느리거나 중단된 스트리밍 작업 문제 해결
- Pub/Sub에서 Dataflow로 읽기
- Dataflow에서 BigQuery로 쓰기