Aurora PostgreSQL의 병렬 쿼리 모범 사례 - Amazon Aurora

Aurora PostgreSQL의 병렬 쿼리 모범 사례

병렬 쿼리 실행은 PostgreSQL의 기능으로, 단일 SQL 쿼리를 더 작은 작업으로 나누어 여러 백그라운드 작업자 프로세스로 동시에 처리할 수 있습니다. PostgreSQL은 단일 백엔드 프로세스에서 쿼리를 완전히 실행하는 대신에 스캔, 조인, 집계 또는 정렬과 같은 쿼리 부분을 여러 CPU 코어에 분산할 수 있습니다. 리더 프로세스는 이 실행을 조정하고 병렬 작업자로부터 결과를 수집합니다.

그러나 대부분의 프로덕션 워크로드, 특히 동시성이 높은 OLTP 시스템의 경우 자동 병렬 쿼리 실행을 비활성화하는 것이 좋습니다. 병렬 처리는 분석 또는 보고 워크로드의 대규모 데이터 세트에 대한 쿼리를 가속화할 수 있지만, 사용량이 많은 프로덕션 환경에서는 이점을 능가하는 상당한 위험을 초래하는 경우가 자주 있습니다.

병렬 실행에도 상당한 오버헤드가 발생합니다. 각 병렬 작업자는 프로세스 포크(메모리 구조 복사 및 프로세스 상태 초기화) 및 인증(max_connections 제한에서 연결 슬롯 사용)이 필요한 전체 PostgreSQL 백엔드 프로세스입니다. 또한 각 작업자는 쿼리당 여러 작업자가 있는 정렬 및 해싱 작업의 work_mem을 포함하여 자체 메모리를 사용합니다. 메모리 사용량은 빠르게 증가합니다(예: 작업자 4명 × 쿼리당 64MB work_mem = 256MB). 따라서 병렬 쿼리는 단일 프로세스 쿼리보다 훨씬 더 많은 시스템 리소스를 사용할 수 있습니다. 제대로 조정하지 않으면 CPU 포화(여러 작업자가 사용 가능한 처리 용량을 초과함), 컨텍스트 전환 증가(운영 체제가 여러 작업자 프로세스 간에 빈번하게 전환되어 오버헤드가 발생하고 처리량이 감소함) 또는 연결 소진(각 병렬 작업자가 연결 슬롯을 사용하므로 작업자가 4명인 단일 쿼리는 총 5개의 연결(리더 1개 + 작업자 4개)을 사용하게 되며, 이는 높은 동시성으로 인해 연결 풀을 빠르게 소진시켜 새로운 클라이언트 연결을 차단하고 애플리케이션 오류를 유발할 수 있음)로 이어질 수 있습니다. 이러한 문제는 여러 쿼리가 동시에 병렬 실행을 시도할 수 있는 동시성이 높은 워크로드에서 특히 심각합니다.

PostgreSQL은 예상 비용을 기반으로 병렬 처리를 사용할지 여부를 결정합니다. 경우에 따라 플래너는 실제로는 이상적이지 않더라도 더 저렴한 것으로 보이는 경우 병렬 계획으로 자동 전환할 수 있습니다. 이는 인덱스 통계가 오래된 경우 또는 순차적 스캔이 인덱스 조회보다 더 매력적으로 보이도록 하는 경우에 발생할 수 있습니다. 이러한 동작 때문에 자동 병렬 실행 계획은 때때로 쿼리 성능이나 시스템 안정성에 회귀를 초래할 수 있습니다.

Aurora PostgreSQL에서 병렬 쿼리의 이점을 최대한 활용하려면 워크로드를 기반으로 병렬 쿼리를 테스트 및 조정하고, 시스템 영향을 모니터링하고, 쿼리 수준 제어를 위해 자동 병렬 계획 선택을 비활성화하는 것이 중요합니다.

구성 파라미터

PostgreSQL은 여러 파라미터를 사용하여 병렬 쿼리의 동작과 가용성을 제어합니다. 이를 이해하고 조정하는 것은 예측 가능한 성능을 달성하는 데 매우 중요합니다.

파라미터 설명 기본값
max_parallel_workers 총 실행할 수 있는 백그라운드 작업자 프로세스의 최대 수 GREATEST($DBInstanceVCPU/2,8)
max_parallel_workers_per_gather 쿼리 계획 노드당 최대 작업자 수(예: Gather당) 2
parallel_setup_cost 병렬 쿼리 인프라를 시작하기 위한 플래너 비용 추가 1000
parallel_tuple_cost 병렬 모드로 처리된 튜플당 비용(플래너 결정에 영향을 줌) 0.1
force_parallel_mode 플래너가 병렬 계획(off, on, regress)을 테스트하도록 강제 off

주요 고려 사항

  • max_parallel_workers는 병렬 작업자의 총 풀을 제어합니다. 너무 낮게 설정하면 일부 쿼리가 직렬 실행으로 돌아갈 수 있습니다.

  • max_parallel_workers_per_gather는 단일 쿼리가 사용할 수 있는 작업자 수에 영향을 줍니다. 값이 높을수록 동시성이 증가하지만 리소스 사용량도 증가합니다.

  • parallel_setup_costparallel_tuple_cost는 플래너의 비용 모델에 영향을 미칩니다. 이러한 값을 낮추면 병렬 계획을 선택할 가능성이 높아질 수 있습니다.

  • force_parallel_mode는 테스트에 유용하지만 필요한 경우가 아니라면 프로덕션 환경에서 사용해서는 안 됩니다.

참고

max_parallel_workers 파라미터의 기본값은 수식 GREATEST($DBInstanceVCPU/2, 8)를 사용하여 인스턴스 크기를 기반으로 동적으로 계산됩니다. 즉, vCPU가 많을수록 Aurora 인스턴스를 더 큰 컴퓨팅 크기로 확장하면 사용 가능한 최대 병렬 작업자 수가 자동으로 증가합니다. 따라서 이전에 직렬로 실행되었거나 병렬 처리가 제한된 쿼리는 스케일 업 작업 후 갑자기 더 많은 병렬 작업자를 활용하여 연결 사용량, CPU 사용률 및 메모리 소비가 예기치 않게 증가할 수 있습니다. 컴퓨팅 스케일링 이벤트 후에는 병렬 쿼리 동작을 모니터링하고 필요한 경우 max_parallel_workers_per_gather를 조정하여 예측 가능한 리소스 사용량을 유지하는 것이 중요합니다.

병렬 쿼리 사용량 식별

쿼리는 데이터 배포 또는 통계에 따라 병렬 계획으로 전환될 수 있습니다. 예제:

SELECT count(*) FROM customers WHERE last_login < now() - interval '6 months';

이 쿼리는 최근 데이터에 인덱스를 사용하지만 기록 데이터에 대한 병렬 순차 스캔으로 전환할 수 있습니다.

auto_explain 모듈을 로드하여 쿼리 실행 계획을 로깅할 수 있습니다. 자세히 알아보려면 AWS 지식 센터에서 쿼리 실행 계획 로깅에 관한 문서를 참조하세요.

Aurora PostgreSQL DB 인스턴스에서 쿼리 실행 계획을 모니터링하여 현재 데이터베이스 로드에 영향을 미치는 실행 계획을 감지하고, aurora_compute_plan_id 파라미터를 사용하여 시간 경과에 따른 실행 계획의 성능 통계를 추적할 수 있습니다. 자세한 내용은 Aurora PostgreSQL용 쿼리 실행 계획 및 피크 메모리 모니터링을 참조하세요.

병렬 쿼리 관련 대기 이벤트에 대한 CloudWatch Database Insights를 모니터링할 수 있습니다. 병렬 쿼리 관련 대기 이벤트에 대해 자세히 알아보려면 IPC:병렬 대기 이벤트를 살펴보세요.

PostgreSQL 버전 18에서는 pg_stat_databasepg_stat_statements의 새 열을 사용하여 병렬 작업자 활동을 모니터링할 수 있습니다.

  • parallel_workers_to_launch: 시작될 계획인 병렬 작업자 수

  • parallel_workers_launched: 실제로 시작된 병렬 작업자 수

이러한 지표는 계획된 병렬 처리와 실제 병렬 처리 간의 불일치를 식별하는 데 도움이 되며, 이는 리소스 제약 또는 구성 문제를 나타낼 수 있습니다. 다음 쿼리를 사용하여 병렬 실행을 모니터링합니다.

데이터베이스 수준 병렬 작업자 지표의 경우:

SELECT datname, parallel_workers_to_launch, parallel_workers_launched FROM pg_stat_database WHERE datname = current_database();

쿼리 수준 병렬 작업자 지표의 경우:

SELECT query, parallel_workers_to_launch, parallel_workers_launched FROM pg_stat_statements ORDER BY parallel_workers_launched;

병렬 처리를 제어하는 방법

쿼리 병렬 처리를 제어하는 방법에는 여러 가지가 있으며, 각 방법은 다양한 시나리오와 요구 사항에 맞게 설계되었습니다.

전역적으로 자동 병렬 처리를 비활성화하려면 파라미터 그룹을 수정하여 설정합니다.

max_parallel_workers_per_gather = 0;

영구 사용자별 설정의 경우 ALTER ROLE 명령은 특정 사용자의 향후 모든 세션에 적용되는 파라미터를 설정하는 방법을 제공합니다.

예제:

ALTER ROLE username SET max_parallel_workers_per_gather = 4;는 이 사용자가 데이터베이스에 연결할 때마다 필요한 경우 세션에서 이 병렬 작업자 설정을 사용하도록 합니다.

세션 수준 제어는 현재 데이터베이스 세션 기간 동안 파라미터를 수정하는 SET 명령을 사용하여 수행할 수 있습니다. 이는 다른 사용자나 향후 세션에 영향을 주지 않고 설정을 일시적으로 조정해야 할 때 특히 유용합니다. 일단 설정되면 이러한 파라미터는 명시적으로 재설정되거나 세션이 종료될 때까지 유효합니다. 명령은 간단합니다.

SET max_parallel_workers_per_gather = 4; -- Run your queries RESET max_parallel_workers_per_gather;

보다 세분화된 제어를 위해 SET LOCAL을 사용하면 단일 트랜잭션에 대한 파라미터를 수정할 수 있습니다. 이는 트랜잭션 내의 특정 쿼리 세트에 대한 설정을 조정해야 할 때 이상적이며, 그 이후에는 설정이 자동으로 이전 값으로 되돌아갑니다. 이 접근 방식은 동일한 세션 내의 다른 작업에 의도하지 않은 영향을 방지하는 데 도움이 됩니다.

쿼리 계획 관리(QPM) 활용

Aurora PostgreSQL에서 쿼리 계획 관리(QPM) 기능은 쿼리 계획 회귀를 유발할 수 있는 데이터베이스 환경 변경과 관계없이 계획 적응성과 안정성을 보장하도록 설계되었습니다. 자세한 내용은 Aurora PostgreSQL 쿼리 계획 관리 개요를 참조하세요. QPM은 최적화 프로그램에 대한 일부 제어 기능을 제공합니다. QPM에서 승인된 계획을 검토하여 현재 병렬 처리 설정과 일치하는지 확인하세요. 최적화되지 않은 병렬 실행을 강제 적용할 수 있는 오래된 계획을 업데이트하거나 제거하세요.

pg_hint_plan을 사용하여 계획을 수정할 수도 있습니다. 자세한 내용은 pg_hint_plan을 사용하여 계획 수정을 참조하세요. Parallel이라는 힌트를 사용하여 병렬 실행을 강제 적용할 수 있습니다. 자세한 내용은 Hints for parallel plans을 참조하세요.

병렬 쿼리 동작 진단

EXPLAIN (ANALYZE, VERBOSE)를 사용하여 쿼리가 병렬 실행을 사용했는지 확인합니다.

  • Gather, Gather Merge 또는 Parallel Seq Scan과 같은 노드를 찾습니다.

  • 병렬 처리가 있는 계획과 없는 계획을 비교합니다.

비교를 위해 병렬 처리를 일시적으로 비활성화하려면: 다음을 수행합니다.

SET max_parallel_workers_per_gather = 0; EXPLAIN ANALYZE <your_query>; RESET max_parallel_workers_per_gather;