Postgres 17 vs 18 벤치마킹

Benchmarking Postgres 17 vs 18 — PlanetScale

작성자
Ruby Weekly
발행일
2025년 10월 14일

핵심 요약

  • 1 Postgres 18의 새로운 I/O 설정(worker, io_uring)은 버전 17 대비 성능 개선을 가져왔지만, 로컬 NVMe 디스크 환경에서 가장 큰 이점을 보였습니다.
  • 2 네트워크 연결 스토리지(EBS)에서는 Postgres 18의 `sync` 및 `worker` 모드가 17 및 `io_uring`보다 우수했으며, `io_method=worker`가 새로운 기본값으로 좋은 선택임을 입증했습니다.
  • 3 `io_uring`은 특정 고병렬 I/O 시나리오(예: NVMe 디스크의 50개 연결, `--range_size=10000`)에서 다른 옵션을 능가하는 유일한 경우를 보여주며 잠재력을 드러냈습니다.

도입

Postgres 18이 출시되면서 디스크 I/O 처리 방식에 대한 새로운 제어 옵션인 `io_method`가 도입되어 많은 기대를 모았습니다. 특히 `worker`와 `io_uring`은 각각 전용 백그라운드 워커 프로세스와 Linux io_uring 인터페이스를 활용하여 I/O 성능을 향상시킬 것으로 예상되었습니다. 본 벤치마크는 Postgres 17과 18의 이러한 새로운 I/O 처리 방식이 실제 성능에 어떤 영향을 미치는지 심층적으로 비교 분석하여, 과연 이러한 개선이 기대만큼 효과적인지 검증하는 것을 목표로 합니다.

벤치마크 설정 및 방법

본 벤치마크는 sysbench 도구의 oltp_read_only 워크로드를 사용하여 PostgreSQL 17 및 18의 성능을 비교했습니다. 데이터 크기는 약 300GB(100개 테이블에 각각 1,300만 행)로 설정되었으며, RAM(64GB)을 초과하여 상당한 디스크 I/O가 발생하도록 유도했습니다.

테스트는 다음 네 가지 AWS EC2 인스턴스 구성에서 진행되었습니다:

  • r7i.2xlarge (gp3 3,000 IOPS / 125 MB/s): 네트워크 연결 스토리지

  • r7i.2xlarge (gp3 10,000 IOPS / 500 MB/s): 네트워크 연결 스토리지 (향상된 성능)

  • r7i.2xlarge (io2 16,000 IOPS): 네트워크 연결 스토리지 (고가, 고성능)

  • i7i.2xlarge (로컬 NVMe 300,000 IOPS): 고속 로컬 NVMe 드라이브

각 인스턴스에서 PostgreSQL 17, 그리고 io_methodsync, worker, io_uring으로 설정된 PostgreSQL 18 버전에 대해 다음 6가지 시나리오를 5분씩 4회 반복하여 총 96가지 조합을 벤치마크했습니다:

  • 단일 연결 및 --range_size = 100

  • 10개 연결 및 --range_size = 100

  • 50개 연결 및 --range_size = 100

  • 단일 연결 및 --range_size = 10,000

  • 10개 연결 및 --range_size = 10,000

  • 50개 연결 및 --range_size = 10,000

벤치마크 결과 분석

  1. 단일 연결 워크로드 (--range_size=100)
    • 네트워크 연결 스토리지(gp3, io2)에서는 Postgres 18의 syncworker 모드가 Postgres 17 및 18의 io_uring 모드보다 현저히 우수한 성능을 보였습니다. 이는 io_uring에 대한 초기 기대와는 다른 결과였습니다.
    • 로컬 NVMe 드라이브에서는 모든 옵션 간 성능 차이가 훨씬 적었습니다.
    • Postgres 18은 짧은 쿼리에 대한 직선 성능(straight-line performance)에서 크게 개선된 모습을 보였습니다.
  2. 단일 연결 워크로드 (--range_size=10000)
    • --range_size가 커지면서 더 많은 순차 I/O와 CPU 작업(집계)이 발생하여, 옵션 간의 성능 차이가 줄어들었습니다.
    • 로컬 디스크는 여전히 우위를 점했지만, Postgres 17과 18의 성능 격차는 작아졌습니다.
  3. 다중 연결 워크로드 (50개 연결, --range_size=100)
    • 높은 병렬성과 I/O 요구 사항이 증가함에 따라, EBS 기반 인스턴스에서는 I/OPS와 처리량이 명확한 병목 현상이었습니다. 이 경우 버전이나 I/O 설정의 차이는 크지 않았습니다.
    • 로컬 NVMe 인스턴스는 모든 EBS 기반 인스턴스를 압도적으로 능가했습니다.
    • Postgres 18의 syncworker 모드가 모든 EBS 기반 인스턴스에서 약간 더 나은 성능을 보였습니다.
  4. 다중 연결 워크로드 (50개 연결, --range_size=10000)
    • 이 시나리오에서는 벤치마크가 I/O 바운드에서 CPU 바운드로 전환되면서 로컬 디스크의 저지연 이점이 줄어들었습니다.
    • 주목할 점은 NVMe 인스턴스에서 io_uring이 다른 옵션들을 약간 능가하는 유일한 시나리오였다는 것입니다. 이는 io_uring이 특정 고병렬/고성능 I/O 환경에서 잠재력을 가질 수 있음을 시사합니다.
  5. io_uring의 성능 특성
    • 10개 연결 시나리오에서 io_uring은 낮은 동시성에서 다른 설정보다 훨씬 낮은 성능을 보였으나, 50개 연결에서는 그 차이가 줄어들었습니다. 이는 io_uring이 높은 I/O 동시성에서 더 효과적일 수 있음을 나타냅니다.

비용 효율성

  • 로컬 NVMe 디스크를 사용하는 i7i 인스턴스는 gp3 또는 io2 EBS 기반 인스턴스보다 훨씬 저렴한 비용으로 월등한 성능을 제공하여, 가격 대비 성능에서 명확한 승자로 나타났습니다.

io_uring이 기대에 못 미친 이유

Tomas Vondra의 분석에 따르면, io_uring이 항상 최적의 성능을 보이지 않는 몇 가지 이유가 있습니다:

  • 현재 인덱스 스캔은 비동기 I/O(AIO)를 사용하지 않습니다.

  • I/O가 백그라운드에서 발생하더라도 체크섬 및 메모리 복사 작업이 병목이 될 수 있습니다.

  • worker 방식은 단일 프로세스 관점에서 I/O에 더 나은 병렬성을 제공할 수 있습니다.

결론

Postgres 18은 새로운 `io_method` 옵션을 통해 I/O 성능 개선과 설정 유연성을 제공하며, 이는 개발팀의 훌륭한 성과입니다. 특히 로컬 NVMe 디스크는 저지연 및 고성능 I/O 환경을 제공하여 모든 구성에서 압도적인 성능을 보였습니다. `io_method=worker`는 새로운 기본값으로 좋은 선택이며, 특정 커널 인터페이스에 의존하지 않으면서 `io_uring`과 유사한 비동기적 이점을 제공합니다. `io_uring`은 특정 고병렬 I/O 워크로드에서 잠재력을 보였지만, 모든 시나리오에서 최적의 성능을 보장하지는 않았습니다. 결국, 최적의 I/O 구성은 워크로드의 특성과 인프라 환경에 따라 달라지므로, 단 하나의 정답은 없습니다.

댓글 0

로그인이 필요합니다

댓글을 작성하거나 대화에 참여하려면 로그인이 필요합니다.

로그인 하러 가기

아직 댓글이 없습니다

첫 번째 댓글을 작성해보세요!