SQS, RabbitMQ, Kafka는 잊으세요. 그냥 Postgres를 쓰세요.

BBetter Stack
컴퓨터/소프트웨어AI/미래기술

스크립트

00:00:00SQS, Kafka, RabbitMQ는 이제 치워버리세요. 이제 PGMQ를 사용해
00:00:05PostgreSQL 안에서 직접 대기열을 관리할 수 있으니까요. 벌써부터 확장성이 떨어질 거라고
00:00:11말하는 분들이 계실 겁니다. 하지만 실제로는 그렇지 않은 것이, Postgres는 수백만 개의 행과
00:00:15초당 수천 개의 요청을 거뜬히 처리할 수 있습니다. 따라서 인프라를 단순하게 유지하고 싶다면
00:00:20오늘 PGMQ를 활용해 대용량 분산 앱을 구축하는 방법을 살펴보겠습니다.
00:00:30자, 딴소리 말고 바로 데모로 들어가겠습니다. Docker로 프로젝트를 설정하고
00:00:34PGMQ를 설치했습니다. PGMQ는 두 가지 방식으로 사용할 수 있는데, SQL 전용 방식이거나
00:00:41Rust나 Python 같은 공식 클라이언트 라이브러리 중 하나를 선택하고, Ruby나 여러 가지
00:00:47TypeScript 지원 버전 같은 커뮤니티 라이브러리를 함께 쓰는 방식입니다. 어떤 언어를 쓸지
00:00:52의견이 절대 안 모일 테니, 이번 데모는 SQL 전용 옵션으로 진행하겠습니다. 먼저 새 대기열을 생성해 봅시다. select pgmq.create를 실행한 뒤
00:00:58대기열 이름을 전달합니다. 여기서 각 대기열은 저마다 하나의 테이블입니다. 데이터베이스를 직접 확인해보면
00:01:04새 테이블이 생성된 것을 볼 수 있습니다. 그런 다음 대기열 이름과 JSON 형태의 메시지를 지정하여
00:01:09대기열에 메시지를 보낼 수 있습니다. 선택적으로 지연 시간을 포함할 수도 있습니다. 메시지가 대기열에 들어가되
00:01:15예를 들어 5초 동안은 소비되지 않도록 하는 식이죠. 좋습니다, 이제 대기열에 메시지들이 들어갔습니다.
00:01:20한 번 소비해 보겠습니다. read 명령어로 가능합니다. 여기서 VT는 가시성 타임아웃(visibility timeout)을 의미하며,
00:01:26읽어 들인 메시지가 30초 동안 다른 프로세스에는 보이지 않게 잠긴다는 뜻입니다. 따라서 다른 프로세스가 가져갈 수 없습니다.
00:01:31이것이 바로 PGMQ가 정확히 한 번의 전달(exactly-once delivery)을 보장하는 방식입니다. quantity는 읽어올 메시지 개수입니다.
00:01:38지정된 시간 내에 메시지가 삭제되거나 보관되지 않으면, 메시지는 다시 보이게 됩니다. 그렇게 하려면
00:01:44대기열에서 삭제하고 아카이브 테이블에 추가하는 archive를 실행하거나, 단순히
00:01:49delete를 실행하면 됩니다. 예를 들어 여기서는 ID가 2인 메시지를 삭제합니다. 그리고 참고로, 이 내용이
00:01:54유용하셨다면 채널 구독을 통해 저희에게 큰 힘을 실어주세요. 최대한 많은 개발자들에게 도움이 되는
00:01:59무료 콘텐츠를 계속 만드는 데 큰 도움이 됩니다. 자, 그럼 PGMQ의 부하 테스트를 해보겠습니다. 먼저 10만 개의 행을
00:02:06대기열에 추가합니다. 대략 0.4초가 걸립니다. 이제 100개의 워커를 실행해 각자 10개씩 묶음으로 작업을 처리하게 하고
00:02:13전부를 읽는 데 얼마나 걸리는지 보겠습니다. 여기서 각 워커는 메시지를 읽고, 읽은 내용을 로그에 남긴 뒤
00:02:18삭제하는 역할만 합니다. 물론 실제로는 해당 데이터로 무언가를 처리해야 하겠지만요.
00:02:23여기서는 오직 PGMQ의 성능을 테스트하는 데만 집중하겠습니다. 총 9초가 걸렸습니다.
00:02:29각 워커는 초당 평균 111개의 메시지를 처리했습니다. 모두 합치면 초당 약 11,100개의 메시지입니다.
00:02:37실서비스 환경과 비슷하게 도커 컨테이너의 리소스를 의도적으로 CPU 2개, 메모리 2GB로 제한했습니다. 아까 말씀드렸듯이,
00:02:44클라이언트 라이브러리를 사용해서 PGMQ와 상호작용할 수도 있습니다.
00:02:49Prisma와 TypeScript를 사용하면 대기열을 생성하고, 메시지를 보내고, 메시지 배치를 읽을 수 있으며
00:02:55Python으로도 똑같이 구현할 수 있습니다. 따라서 추가적인 종속성을 원하지 않는다면, 정말로
00:03:01PGMQ를 통해 Postgres 안에서 대규모 대기열을 운영할 수 있습니다. 그리고 이 영상을 통해 다루듯, 기술 스택의
00:03:08가능한 많은 부분을 Postgres로 대체하며 훨씬 더 나아갈 수 있습니다.

핵심 요약

PGMQ는 별도의 외부 메시지 큐 시스템 없이 PostgreSQL 안에서 초당 1만 개 이상의 메시지를 처리하는 대규모 대기열을 구축한다.

하이라이트

  • PostgreSQL 내부에서 대기열을 관리하는 PGMQ는 수백만 개의 행과 초당 수천 개의 요청을 처리한다.

  • 10만 개의 행을 대기열에 추가하는 데 약 0.4초가 소요된다.

  • CPU 2개와 메모리 2GB로 제한된 환경에서 100개의 워커가 초당 총 11,100개의 메시지를 처리한다.

  • 가시성 타임아웃(visibility timeout) 기능을 통해 읽어 들인 메시지가 지정된 시간 동안 다른 프로세스에 보이지 않게 잠겨 정확히 한 번의 전달을 보장한다.

  • SQL 전용 방식뿐만 아니라 Rust, Python, TypeScript 등 다양한 클라이언트 라이브러리와 연동된다.

타임라인

PostgreSQL 기반 대기열 소개

  • PGMQ는 PostgreSQL 내부에서 대기열을 직접 관리한다.
  • 수백만 개의 행과 초당 수천 개의 요청을 처리할 수 있어 인프라가 단순해진다.

기존의 SQS, Kafka, RabbitMQ 같은 별도 인프라 대신 PostgreSQL을 활용해 대용량 분산 애플리케이션을 구축한다. Postgres는 수백만 행과 초당 수천 건의 요청을 원활하게 처리하여 확장성 문제를 해결한다.

SQL 전용 방식의 대기열 조작과 핵심 기능

  • 새로운 대기열은 각각 하나의 테이블로 생성된다.
  • 가시성 타임아웃(VT)은 메시지가 지정된 시간 동안 다른 프로세스에 노출되지 않도록 잠근다.

SQL 전용 방식을 통해 대기열 생성, 메시지 전송, 읽기, 삭제를 수행한다. 메시지 전송 시 지연 시간을 설정할 수 있으며, 가시성 타임아웃을 통해 중복 처리를 방지하고 정확히 한 번의 전달을 보장한다. 처리된 메시지는 아카이브 테이블로 이동시키거나 삭제할 수 있다.

부하 테스트 및 클라이언트 라이브러리 연동

  • 10만 개의 행을 대기열에 추가하는 데 0.4초가 걸린다.
  • 제한된 리소스 환경에서 100개의 워커가 초당 총 11,100개의 메시지를 처리한다.

CPU 2개와 메모리 2GB의 제한된 도커 환경에서 10만 개 행을 대상으로 부하 테스트를 진행한 결과, 총 9초 만에 처리를 완료했다. SQL 외에도 Prisma, TypeScript, Python 등 다양한 언어의 클라이언트 라이브러리를 지원하여 종속성을 최소화하며 대규모 대기열을 운영할 수 있다.

커뮤니티 글

아직 글이 없습니다. 이 영상에 대한 첫 번째 글을 작성해 보세요!

이 영상에 대해 글쓰기