[GCP] Pubsub flow control

SangHun·2021년 10월 3일
0
post-thumbnail

GCP Pub/Sub은 GCP에서 여러 서비스들이 비동기적으로 통신할 수 있도록 해준다.

Publish와 Subscribe로 메시지를 주고 받는 message queue 방식의 서비스라고 보시면 된다.

Pub/Sub에는 여러 특징이 있는데, 그 중 하나가 flow control이다.

개념

매우매우 간단하게 설명하자면 아래와 같다.

Pub/Sub의 subscriber client가 메시지를 가져오는 주기나 한 번에 가져오는 메시지 수 등의 설정.

참고 : Python 코드에 한하여, Python pubsub api 문서를 읽어보는 것을 추천!

위 문서를 자세히 읽어보면 알겠지만, PubSub subscriber는 기본적으로 메시지를 한 번에 1000개씩 가져온다.

문제

publish가 많지 않은 서비스라면 subscription에 쌓인 메시지를 있는대로 가져오는 수준이다...

예시

시간이 오래걸리는 작업이 짧은 주기로 발행되고, 많은 수의 subscriber client가 이를 구독한다고 가정해보자.

Subscriber Client A, B, C

만약 메시지를 소비하는 속도가 발행하는 속도를 따라가지 못한다면 어느 순간부터 메시지가 쌓이게 된다.

메시지가 한움큼 쌓여있을 때, 먼저 subscription에 접근한 subscriber client가 쌓인 메시지 1000개까지 가져오게 된다.

  • 이 subscriber client는 1000개를 모두 처리할 때까지 다른 메시지를 받지 못하고

  • 다른 subscriber client들은 저 1000개의 메시지를 분산하여 처리하지 못하게 된다.

결국, 분산 처리를 위해 도입한 서비스가 분산 처리를 제대로 하지 못하는 불상사가 벌어진다...

해결

간단하게도, flow control을 직접 설정해주면 된다.

from google.cloud import pubsub_v1

flow_control = pubsub_v1.types.FlowControl(max_messages=1)	# Subscriber gets only 1 message at once
streaming_pull_future = subscriber.subscribe(
    subscription_path, callback=callback, flow_control=flow_control
)

Subscriber client에서의 실행시간이 긴 작업이라면 max_message를 아주 작은 수(>=1)로 설정해보자.

max_message를 어느정도로 설정해야할지 모르겠다면, 가장 좋은 방법은 직접 테스트 해서 알아보는 것이다.

테스트

이하 직접 진행했던 테스트에 대한 기록이다.

Test 1

구성

  • subscriber client 4개
  • 테스트 시간: 1시간
  • 0.2초 간격으로 publish

Flow control을 적용하지 않았을 때

pubsub에서 평균 대기 시간 2500~3080초

pubsub에서 최대 대기 시간 5800~6600초

max_message = 5

pubsub에서 평균 대기 시간 1800~1840초

pubsub에서 최대 대기 시간 3717~3723초

max_message = 3

pubsub에서 평균 대기 시간 1814~1823초

pubsub에서 최대 대기 시간 3683~3691초

max_message = 1

pubsub에서 평균 대기 시간 1898~1921초

pubsub에서 최대 대기 시간 약 3841초

Test 2

구성

  • subscriber client 4개
  • 테스트 시간: 30분
  • 0.4초 간격으로 publish

max_message = 5

pubsub에서 평균 대기 시간 329~338초

pubsub에서 최대 대기 시간 697~710초

max_message = 3


pubsub에서 평균 대기 시간 352~361초

pubsub에서 최대 대기 시간 738~749초

max_message = 1

pubsub에서 평균 대기 시간 430~455초

pubsub에서 최대 대기 시간 999~1003초

Test 3

구성

  • subscriber client 4개
  • 테스트 시간: 30분
  • 1초 간격으로 publish
  • subscriber가 sleep하는 시간을 설정

max_message = 5

pubsub에서 평균 대기 시간 695~774초

pubsub에서 최대 대기 시간 1531~1641초

max_message = 3

pubsub에서 평균 대기 시간 731~806초

pubsub에서 최대 대기 시간 1531~1628초

max_message = 1

pubsub에서 평균 대기 시간 770~827초

pubsub에서 최대 대기 시간 1727~1756초

Test 4

구성

  • subscriber client 4개
  • 테스트 시간: 5분
  • 1초 간격으로 publish
  • subscriber가 sleep하는 시간 설정

max_message = 5

pubsub에서 평균 대기 시간 152~201초

pubsub에서 최대 대기 시간 389~455초

max_message = 3

pubsub에서 평균 대기 시간 118~157초

pubsub에서 최대 대기 시간 323~339초

max_message = 1


pubsub에서 평균 대기 시간 159~191초

pubsub에서 최대 대기 시간 376~393초

Test 5 - Ideal situation

구성

  • Subscriber를 4개에서 8개로 증가
  • 테스트 시간: 30분
  • 2초 간격으로 publish
  • subscriber가 sleep하는 시간 설정

아래 그래프에는 검은 선과 빨간 선이 있다.
빨간 선은 가장 이상적으로 메시지들이 subscriber에게 소비되는 경우를 나타내고,
검은 선은 실제로 메시지들이 subscriber에 의해 소비되는 경우를 나타낸다.
검은 선이 빨간선보다 위로 올라가면 메시지가 원래 처리되어야 할 때보다 늦게 처리된 경우고,
아래로 내려가면 메시지가 원래 처리되어야 할 때보다 이르게 처리된 경우다.
즉, 검은 선이 위로가면 메시지가 새치기 당한 것이고 아래로 내려가면 새치기 한 것이다.

max_messages = 1

max_message = 3

subscriber 숫자가 충분히 많아서 message가 subscribtion에 쌓이지 않는 경우, max_messages = 1인 경우가 가장 효율적이다.

profile
개발괴발자

0개의 댓글