Compute Engine 기반 PostgreSQL 클러스터의 고가용성을 위한 아키텍처

Last reviewed 2023-10-09 UTC
설명: Google Cloud에서 PostgreSQL 배포를 위한 고가용성(HA)을 제공하는 여러 아키텍처입니다.

이 문서에서는 Google Cloud 기반 PostgreSQL 배포에 고가용성(HA)을 제공하는 여러 아키텍처에 대해 설명합니다. HA는 기본 인프라 장애에 대한 시스템 복원력을 측정합니다. 이 문서에서 HA는 HA 아키텍처에 따라, PostgreSQL 클러스터의 단일 클라우드 리전 내 또는 여러 리전 간 가용성을 나타냅니다.

이 문서는 전반적인 시스템 업타임을 개선하여 PostgreSQL 데이터 계층 안정성을 높이는 방법을 알아보려는 데이터베이스 관리자, 클라우드 설계자, DevOps 엔지니어를 대상으로 합니다. 이 문서에서는 Compute Engine에서 PostgreSQL 실행과 관련된 개념을 설명합니다. 이 문서에서는 PostgreSQL용 Cloud SQL 사용에 관해 다루지 않습니다.

시스템 또는 애플리케이션에서 요청 또는 트랜잭션을 처리하기 위해 지속적인 상태가 필요한 경우, 데이터 지속성 레이어(데이터 계층)가 있어야 데이터 쿼리 또는 변형 요청을 성공적으로 처리할 수 있어야 합니다. 데이터 계층에 다운타임이 발생하면 시스템 또는 애플리케이션에서 필요한 작업을 수행할 수 없게 됩니다.

시스템의 서비스 수준 목표(SLO)에 따라 더 높은 가용성을 제공하는 아키텍처가 필요할 수 있습니다. HA를 확보하는 방법에는 여러 가지가 있지만 일반적으로 중복 인프라를 프로비저닝하면 애플리케이션에서 신속하게 액세스할 수 있습니다.

이 문서에서는 다음 주제에 대해 설명합니다.

  • HA 데이터베이스 개념과 관련된 용어의 정의
  • HA PostgreSQL 토폴로지의 옵션
  • 각 아키텍처 옵션에서 고려해야 할 사항을 이해하는 데 도움이 되는 상황 정보

용어

다음은 이 문서의 범위를 벗어나므로 다루지는 않지만 이해에 도움이 되는 업계 표준의 용어와 개념입니다.

복제
쓰기 트랜잭션(INSERT, UPDATE 또는 DELETE)과 스키마 변경사항(데이터 정의 언어(DDL))이 안정적으로 캡처되고 로깅된 후 아키텍처의 모든 다운스트림 데이터베이스 복제본 노드에 순차적으로 적용될 때 사용되는 프로세스입니다.
기본 노드
지속 데이터의 최신 상태가 포함된 읽기를 제공하는 노드입니다. 모든 데이터베이스 쓰기는 기본 노드로 전달되어야 합니다.
복제본(보조) 노드
기본 데이터베이스 노드의 온라인 사본입니다. 기본 노드의 변경사항이 동기적 또는 비동기적으로 복제본 노드에 복제됩니다. 복제본 노드에서 읽을 수도 있으며 이 경우 복제 지연으로 인해 데이터가 약간 지연될 수 있습니다.
복제 지연
로그 시퀀스 넘버(LSN), 트랜잭션 ID, 시간으로 표시되는 측정 값입니다. 복제 지연은 변경 작업이 기본 노드에 적용될 때와 비교하여, 복제본에 적용될 때 사이의 차이점을 보여줍니다.
지속적 보관처리
데이터베이스가 순차적 트랜잭션을 파일에 계속 저장하는 증분 백업입니다.
미리 쓰기 로그(WAL)
미리 쓰기 로그(WAL)는 실제로 파일이 변경되기 전에 데이터 파일의 변경사항을 기록하는 로그 파일입니다. WAL은 서버 충돌 시 데이터 무결성과 쓰기 내구성을 보장하는 표준 방법입니다.
WAL 레코드
데이터베이스에 적용된 트랜잭션의 레코드입니다. WAL 레코드는 데이터 파일의 페이지 수준 변경사항을 설명하는 일련의 레코드로 형식이 지정되고 저장됩니다.
로그 시퀀스 번호(LSN)
트랜잭션은 WAL 파일에 추가되는 WAL 레코드를 만듭니다. 삽입이 발생하는 위치를 로그 시퀀스 번호(LSN)라고 합니다. 16진수 숫자 두 개를 슬래시로 분리한 64비트 정수(XXXXXXXX/YYZZZZZZ)입니다. 'Z'는 WAL 파일의 오프셋 위치를 나타냅니다.
세그먼트 파일
구성한 파일 크기에 따라 가능한 한 많은 WAL 레코드를 포함하는 파일입니다. 세그먼트 파일은 단조 증가하는 파일 이름을 사용하며 기본 파일 크기가 16MB입니다.
동기 복제
클라이언트에 대해 커밋을 확인하기 전 복제본 트랜잭션 로그에 데이터가 기록되었는지 확인하기 위해 기본 서버가 복제본을 기다리는 복제 형식입니다. 스트리밍 복제를 실행할 때 PostgreSQL synchronous_commit 옵션을 사용하여 일관성 보증을 구성할 수 있습니다.
비동기 복제
클라이언트에 대해 커밋을 확인하기 전 트랜잭션이 성공적으로 수신되었는지 확인하기 위해 기본 서버가 복제본을 기다리지 않는 복제 형식입니다. 비동기 복제는 동기 복제에 비해 지연 시간이 낮습니다. 하지만 기본 비정상 종료 및 커밋된 트랜잭션이 복제본에 전달되지 않을 경우 데이터 손실 가능성이 있습니다. 비동기 복제는 파일 기반 로그 전달 또는 스트리밍 복제를 사용하는 PostgreSQL의 기본 복제 모드입니다.
파일 기반 로그 전달
기본 데이터베이스 서버에서 복제본으로 WAL 세그먼트 파일을 전송하는 PostgreSQL의 복제 방법입니다. 기본 서버는 지속적인 아카이브 모드로 작동하며, 각 대기 서비스는 WAL 파일을 읽기 위해 지속적인 복구 모드로 작동합니다. 이 복제는 비동기적입니다.
스트리밍 복제
복제본이 기본 데이터베이스 서버에 연결되어 지속적으로 일련의 변경사항을 수신하는 복제 방법입니다. 업데이트가 스트림을 통해 전달되므로 이 방법은 기본 인스턴스를 로그 전달 복제 방법보다 더 최신 상태로 유지합니다. 복제는 기본적으로 비동기식이지만 동기 복제를 구성할 수도 있습니다.
물리적 스트리밍 복제
변경사항을 복제본으로 전송하는 복제 방법입니다. 이 방법은 디스크 블록 주소 및 바이트 간 변경사항의 형태로 물리적 데이터 변경사항을 포함하는 WAL 레코드를 사용합니다.
논리적 스트리밍 복제
복제 ID(기본 키)에 따라 변경사항을 캡처하는 복제 방법으로, 데이터 복제 방식을 물리적 복제보다 더 세부적으로 제어할 수 있습니다. PostgreSQL 논리 복제에 대한 제한 때문에 논리적 스트리밍 복제를 위해서는 HA 설정을 위한 특별한 구성이 필요합니다. 이 가이드에서는 표준 물리적 복제를 설명하고 논리 복제는 설명하지 않습니다.
uptime
리소스가 작동하고 요청에 대한 응답을 제공할 수 있는 시간의 비율입니다.
장애 감지
인프라 장애가 발생했는지 식별하는 프로세스입니다.
failover
백업 또는 대기 인프라(이 경우에는 복제본 노드)를 기본 인프라로 승격하는 프로세스입니다. 장애 조치 중에는 복제본 노드가 기본 노드가 됩니다.
switchover
프로덕션 시스템에서 수동 장애 조치를 실행하는 프로세스입니다. 전환은 시스템이 제대로 작동하는지 테스트하거나 유지보수를 위해 현재 기본 노드를 클러스터에서 가져옵니다.
복구 시간 목표(RTO)
데이터 계층 장애 조치 프로세스가 완료될 때까지 실제 경과 시간입니다. RTO는 비즈니스 관점에서 허용되는 시간에 따라 달라집니다.
복구 지점 목표(RPO)
장애 조치의 결과로 유지해야 할 데이터 계층의 데이터 손실 규모입니다(실제 경과 시간). RPO는 비즈니스 관점에서 허용되는 데이터 손실 규모에 따라 다릅니다.
대체
장애 조치의 원인이 된 조건을 시정한 후에 이전 기본 노드를 복구하는 프로세스입니다.
자가 복구
인간 운영자의 외부 작업 없이 문제를 해결하는 시스템 기능입니다.
네트워크 파티션
아키텍처의 두 노드(예: 기본 노드 및 복제본 노드)가 네트워크를 통해 서로 통신할 수 없는 조건입니다.
분할 브레인
두 노드가 동시에 기본 노드로 간주될 때 발생하는 조건입니다.
노드 그룹
서비스를 제공하는 컴퓨팅 리소스의 집합입니다. 이 문서에서 서비스는 데이터 지속성 계층입니다.
감시 또는 쿼럼 노드
분할 브레인 조건이 발생할 때 노드 그룹이 수행할 작업을 결정하는 데 유용한 별도의 컴퓨팅 리소스입니다.
기본 또는 리더 선택
감시 노드를 포함한 피어 인식 노드 그룹이 어떤 노드를 기본 노드로 설정해야 하는지 결정하는 프로세스입니다.

HA 아키텍처를 고려해야 하는 경우

HA 아키텍처는 단일 노드 데이터베이스 설정보다 향상된 데이터 계층 다운타임 방지 기능을 제공합니다. 비즈니스 사용 사례에 가장 적합한 옵션을 선택하려면 다운타임의 허용 범위와 다양한 아키텍처 각각의 단점을 이해해야 합니다.

워크로드 및 서비스의 안정성 요구사항을 충족하기 위해 향상된 데이터 계층 업타임을 제공하려면 HA 아키텍처를 사용합니다. 어느 정도의 다운타임이 허용되는 환경의 경우 HA 아키텍처는 불필요한 비용과 복잡성을 야기할 수 있습니다. 예를 들어 개발 또는 테스트 환경은 높은 데이터베이스 계층 가용성을 필요로 합니다.

HA 요구사항 고려

다음은 비즈니스에 적합한 PostgreSQL HA 옵션을 결정하는 데 도움이 되는 몇 가지 질문입니다.

  • 달성하려는 가용성 수준이 어떻게 되나요? 단일 영역 장애 발생 시에만 서비스를 계속 작동할 수 있는 옵션이 필요한가요? 아니면 전체 리전 장애 발생 시에 서비스를 계속 작동할 수 있는 옵션이 필요한가요? 일부 HA 옵션은 특정 리전으로 제한되지만, 다른 옵션은 멀티 리전에 적용될 수 있습니다.
  • 어떤 서비스나 고객이 데이터 계층을 사용하고 있으며, 데이터 지속성 계층에 다운타임이 발생할 경우 비즈니스 비용이 얼마나 들까요? 시스템을 가끔 사용해야 하는 내부 고객에게만 제공되는 서비스의 경우 고객을 지속적으로 지원하는 최종 고객용 서비스보다 가용성 요구사항이 낮을 수 있습니다.
  • 작업 예산은 어느 정도인가요? HA를 제공하려면 인프라 및 스토리지 비용이 증가할 가능성이 높으므로 비용은 중요한 고려사항입니다.
  • 프로세스는 얼마나 자동화해야 하며 얼마나 빨리 장애 조치해야 하나요? (RTO가 어떻게 되나요?) HA 옵션은 시스템이 장애 조치를 수행한 후 고객에게 서비스를 제공하기까지 걸리는 시간에 따라 달라집니다.
  • 장애 조치로 인한 데이터 손실을 감당할 수 있나요? (RPO가 어떻게 되나요?) HA 토폴로지는 분산 특성으로 인해 커밋 지연 시간과 장애로 인한 데이터 손실 위험 사이에 상충 관계가 있습니다.

HA 작동 방식

이 섹션에서는 PostgreSQL HA 아키텍처를 기반으로 하는 스트리밍 및 동기 스트리밍 복제를 설명합니다.

스트리밍 복제

스트리밍 복제는 복제본이 기본 서버에 연결하고 지속적으로 WAL 레코드 스트림을 수신하는 복제 방법입니다. 로그 전달 복제와 비교할 때 스트리밍 복제는 복제본이 기본 서버와 더 최신 상태로 유지될 수 있게 해줍니다. PostgreSQL은 버전 9부터 시작하여 기본 제공되는 스트리밍 복제를 제공합니다. 많은 PostgreSQL HA 솔루션에는 기본 제공 스트리밍 복제를 사용하여 여러 PostgreSQL 복제본 노드가 기본 서버와 동기화된 상태로 유지될 수 있게 해주는 메커니즘을 제공합니다. 이러한 옵션 중 일부는 이 문서의 뒷부분에 있는 PostgreSQL HA 아키텍처 섹션에서 설명합니다.

각 복제본 노드에는 전용 컴퓨팅 및 스토리지 리소스가 필요합니다. 복제본 노드 인프라는 기본 서버와 독립적입니다. 복제본 노드를 핫 대기로 사용하여 읽기 전용 클라이언트 쿼리를 제공할 수 있습니다. 이 방법은 기본 서버와 하나 이상의 복제본 사이에 읽기 전용 쿼리 부하 분산을 허용합니다.

스트리밍 복제는 기본적으로 비동기식입니다. 기본 노드가 클라이언트에 대한 트랜잭션 커밋을 확인하기 전에 복제본의 확인을 기다리지 않습니다. 기본 노드가 트랜잭션을 확인한 후 복제본이 트랜잭션을 수신하기 전에 장애가 발생하면 비동기 복제로 인해 데이터가 손실될 수 있습니다. 복제본이 새 기본 노드로 승격되면 이러한 트랜잭션이 존재하지 않습니다.

동기 스트리밍 복제

하나 이상의 복제본을 동기 대기 노드로 선택하여 스트리밍 복제를 동기식으로 구성할 수 있습니다. 아키텍처를 동기식 복제로 구성하는 경우 복제본이 트랜잭션 지속성을 확인한 후에만 기본 노드가 트랜잭션 커밋을 확인합니다. 동기 스트리밍 복제는 트랜잭션 지연 시간이 길어지는 만큼 향상된 내구성을 제공합니다.

synchronous_commit 구성 옵션을 사용하면 트랜잭션에 대해 다음과 같은 점진적 복제본 내구성 보장을 구성할 수도 있습니다.

  • on [기본값]: 동기 대기 복제는 기본 노드에 확인을 보내기 전에 커밋된 트랜잭션을 WAL에 기록합니다. on 구성을 사용하면 기본 노드 및 모든 동기 대기 복제본에서 동시 스토리지 장애가 발생하는 경우에만 트랜잭션이 손실될 수 있습니다. 복제본이 WAL 레코드를 기록한 후에만 확인을 전송하므로 복제본을 쿼리하는 클라이언트는 해당 WAL 레코드가 복제본 데이터베이스에 적용될 때까지 변경사항을 확인할 수 없습니다.
  • remote_write: 동기적 대기 복제본은 OS 수준에서 WAL 레코드 수신을 확인하지만, WAL 레코드가 디스크에 작성되었는지 보장하지 않습니다. remote_write가 WAL가 기록되었는지 보장하지 않기 때문에 데이터가 기록되기 전 기본 및 대기 모두에 오류가 발생하면 트랜잭션이 손실될 수 있습니다. remote_writeon 옵션보다 내구성이 낮습니다.
  • remote_apply: 동기식 대기 복제본은 클라이언트에 대한 트랜잭션 커밋을 확인하기 전에 트랜잭션이 수신되고 데이터베이스에 적용되었는지 확인합니다. remote_apply 구성을 사용하면 트랜잭션이 복제본에 유지되며 클라이언트 쿼리 결과에 트랜잭션의 영향이 즉시 포함됩니다. remote_applyonremote_write보다 내구성과 일관성이 높습니다.

PostgreSQL HA 아키텍처

가장 기본적인 수준에서 데이터 계층 HA는 다음으로 구성됩니다.

  • 기본 노드의 장애 발생 여부를 식별하는 메커니즘
  • 복제본 노드가 기본 노드로 승격되는 경우 장애 조치를 수행하는 프로세스
  • 애플리케이션 요청이 새 기본 노드에 도달할 수 있도록 쿼리 라우팅을 변경하는 프로세스
  • 장애 조치 전 원래 용량의 기본 노드와 복제본 노드를 사용하여 원래 아키텍처로 대체할 수 있는 방법(선택사항)

다음 섹션은 다음 HA 아키텍처에 대한 개요를 제공합니다.

  • Patroni 템플릿
  • pg_auto_failover 확장 프로그램 및 서비스
  • 스테이트풀(Stateful) MIG 및 리전 영구 디스크

이러한 HA 솔루션은 인프라 또는 영역 장애가 발생하는 경우에 다운타임을 최소화합니다. 이러한 옵션 중에서 하나를 선택하여 비즈니스 요구사항에 따라 커밋 지연 시간과 내구성이 균형을 이루도록 할 수 있습니다.

HA 아키텍처의 주요 특성은 이후 장애 조치 또는 대체를 위해 새 대기 환경을 준비하는 데 필요한 시간과 수동 작업입니다. 그렇지 않으면 시스템이 한 가지 오류만 견딜 수 있고 서비스가 SLA 위반으로부터 보호를 받지 못합니다. 보호 인프라와 함께 수동 장애 조치 또는 전환을 수행할 수 있는 HA 아키텍처를 선택하는 것이 좋습니다.

Patroni 템플릿을 사용하는 HA

Patroni는 PostgreSQL HA 아키텍처를 구성, 배포, 운영하는 도구를 제공하는 성숙하고 안정적인 오픈소스(MIT 라이선스) 소프트웨어 템플릿입니다. Patroni는 분산 구성 저장소(DCS)에 유지되는 공유 클러스터 상태와 아키텍처 구성을 제공합니다. DCS를 구현하기 위한 옵션으로는 etcd, Consul, Apache ZooKeeper 또는 Kubernetes가 있습니다. 다음 다이어그램은 Patroni 클러스터의 주요 구성요소를 보여줍니다.

Patroni 클러스터는 PostgreSQL 노드, DCS, Patroni 에이전트 간에 상호작용합니다.

그림 1. Patroni 클러스터의 주요 구성요소 다이어그램

그림 1에서 부하 분산기는 PostgreSQL 노드를 향하며, DCS 및 Patroni 에이전트는 PostgreSQL 노드에서 작동합니다.

Patroni는 각 PostgreSQL 노드에서 에이전트 프로세스를 실행합니다. 에이전트 프로세스는 PostgreSQL 프로세스 및 데이터 노드 구성을 관리합니다. Patroni 에이전트는 DCS를 통해 다른 노드에 맞게 조정됩니다. 또한 Patroni 에이전트 프로세스는 각 노드에 대해 PostgreSQL 서비스 상태 및 구성을 확인하기 위해 쿼리할 수 있는 REST API를 제공합니다.

기본 노드는 클러스터 멤버십 역할을 어설션하기 위해 DCS의 리더 키를 정기적으로 업데이트합니다. 리더 키에는 TTL(수명)이 포함됩니다. 업데이트 없이 TTL이 경과하면 리더 키가 DCS에서 제거되고 후보 풀에서 새 기본 노드를 선택하는 리더 선택이 시작됩니다.

다음 다이어그램은 노드 A가 리더 잠금을 성공적으로 업데이트하는 정상 클러스터를 보여줍니다.

정상 클러스터 리더는 리더 후보가 감시하는 동안 리더 잠금을 업데이트합니다.

그림 2. 정상 클러스터의 다이어그램

그림 2는 노드 B와 노드 C가 감시하는 동안 노드 A가 리더 키를 성공적으로 업데이트하는 정상 클러스터를 보여줍니다.

장애 감지

Patroni 에이전트는 DCS에서 키를 업데이트하여 상태를 지속적으로 알립니다. 이와 동시에 PostgreSQL의 상태를 검증합니다. 에이전트는 문제가 감지되면 노드를 종료하여 자가 방어하거나 노드를 복제본으로 강등합니다. 다음 다이어그램과 같이 손상된 노드가 기본 노드이면 DCS의 리더 키가 만료되고 새 리더 선택이 수행됩니다.

손상된 클러스터는 기존 리더 키가 만료된 후 새 리더를 선택합니다.

그림 3. 손상된 클러스터의 다이어그램

그림 3은 손상된 클러스터를 보여줍니다. 다운된 기본 노드가 최근 DCS의 Leader 키를 업데이트하지 않았으며 리더가 아닌 복제본에는 리더 키가 만료되었다는 알림이 전송됩니다.

Linux 호스트에서 Patroni는 기본 노드에서 OS 수준 워치독도 실행합니다. 이 워치독은 Patroni 에이전트 프로세스에서 연결 유지 메시지를 수신합니다. 프로세스가 응답하지 않고 연결 유지가 전송되지 않으면 워치독이 호스트를 다시 시작합니다. 워치독은 에이전트 장애로 인해 DCS의 리더 키가 만료되고 다른 기본 노드(리더)가 선택되었는데 PostgreSQL 노드가 계속 기본 노드 역할을 하는 분할 브레인 조건을 방지하는 데 도움이 됩니다.

장애 조치 프로세스

리더 잠금이 DCS에서 만료되면 후보 복제본 노드가 리더 선택을 시작합니다. 복제본에서 누락된 리더 잠금이 검색되면 다른 복제본과 비교되는 해당 복제 위치를 확인합니다. 각 복제본은 다음 다이어그램에 표시된 대로 REST API를 사용하여 다른 복제본 노드의 WAL 로그 위치를 가져옵니다.

Patroni 장애 조치 프로세스 중에는 복제본이 WAL 로그에서 위치를 확인합니다.

그림 4. Patroni 장애 조치 프로세스의 다이어그램

그림 4는 WAL 로그 위치 쿼리 및 활성 복제본 노드의 해당 결과를 보여줍니다. 노드 A는 사용할 수 없고, 정상 노드 B 및 C가 서로 동일한 WAL 위치를 반환합니다.

최신 노드(또는 동일 위치에 있는 여러 노드)가 DCS에서 리더 잠금을 획득하기 위해 동시에 시도합니다. 하지만 하나의 노드만 DCS에서 리더 키를 만들 수 있습니다. 다음 다이어그램에 표시된 것처럼 리더 키를 성공적으로 만들기 위한 첫 번째 노드가 리더 경합의 승자입니다.

노드가 DCS에 리더 키를 만들고 새로운 기본 노드가 됩니다.

그림 5. 리더 경합 다이어그램

그림 5는 리더 경합을 보여줍니다. 두 리더 후보가 리더 잠금을 획득하려고 시도하지만 노드 2개 중 1개(노드 C)만 리더 키를 성공적으로 설정하고 경합에서 승리합니다.

리더로 선택된 복제본은 새로운 기본 노드로 자체 승격됩니다. 복제본이 자체 승격될 때부터 새 기본 노드가 DCS의 리더 키를 업데이트하여 리더 잠금을 유지하고 다른 노드가 복제본 역할을 합니다.

또한 Patroni는 전환을 실행하여 노드 장애 조치 프로세스를 테스트할 수 있는 patronictl 제어 도구를 제공합니다. 이 도구는 운영자가 프로덕션 환경에서 HA 설정을 테스트하는 데 도움이 됩니다.

쿼리 라우팅

각 노드에서 실행되는 Patroni 에이전트 프로세스는 현재 노드 역할(기본 또는 복제본)을 표시하는 REST API 엔드포인트를 노출합니다.

REST 엔드포인트 기본인 경우 HTTP 반환 코드 복제본인 경우 HTTP 반환 코드
/primary 200 503
/replica 503 200

특정 노드가 해당 역할을 변경할 경우 관련 상태 확인으로 해당 응답이 변경되기 때문에 부하 분산기 상태 확인이 이러한 엔드포인트를 사용하여 기본 및 복제본 노드에 트래픽 라우팅을 알릴 수 있습니다. Patroni 프로젝트는 HAProxy 부하 분산기에 대해 템플릿 구성을 제공합니다. 내부 패스 스루 네트워크 부하 분산기는 이러한 동일한 상태 점검을 사용하여 비슷한 기능을 제공할 수 있습니다.

대체 프로세스

노드 장애가 발생하면 클러스터의 성능이 저하됩니다. Patroni의 대체 프로세스는 장애 조치 후 HA 클러스터를 다시 정상 상태로 복원하는 데 도움이 됩니다. 대체 프로세스는 손상된 노드를 클러스터 복제본으로 자동 초기화하여 클러스터를 원래 상태로 되돌리는 작업을 관리합니다.

예를 들어 운영체제 또는 기본 인프라의 오류로 인해 노드가 다시 시작될 수 있습니다. 노드가 기본이고 다시 시작하는 데 리더 키 TTL보다 오래 걸리면 리더 선택이 트리거되고 새 기본 노드가 선택되고 승격됩니다. 비활성 기본 Patroni 프로세스가 시작되면 리더 잠금이 없는 것을 감지하고 자체를 복제본으로 자동으로 강등시키고, 해당 용량에 클러스터를 조인합니다.

발생 가능성이 낮지만 영역 오류와 같은 복구할 수 없는 노드 오류가 발생하면 새 노드를 시작해야 합니다. 데이터베이스 작업자가 새 노드를 수동으로 시작하거나, 사용자가 프로세스 자동화를 위한 최소 노드 수로 스테이트풀(Stateful) 리전 관리형 인스턴스 그룹(MIG)을 사용할 수 있습니다. 새 노드가 생성된 후 Patroni는 새 노드가 기존 클러스터의 일부인지 감지하고 자동으로 노드를 복제본을 초기화합니다.

pg_auto_failover 확장 프로그램 및 서비스를 사용하는 HA

pg_auto_failover는 적극적으로 개발 중인 오픈소스(PostgreSQL 라이선스) PostgreSQL 확장 프로그램입니다. pg_auto_failover는 기존 PostgreSQL 기능을 확장하여 HA 아키텍처를 구성합니다. pg_auto_failover는 PostgreSQL 이외의 종속 항목을 갖지 않습니다.

HA 아키텍처에 pg_auto_failover 확장 프로그램을 사용하려면 각각 확장 프로그램이 사용 설정되어 PostgreSQL을 실행하는 3개 이상의 노드가 필요합니다. 이러한 노드는 데이터베이스 그룹의 업타임에 영향을 주지 않고 오류가 발생할 수 있습니다. pg_auto_failover로 관리되는 노드 컬렉션을 구성이라고 부릅니다. 다음 다이어그램은 pg_auto_failover 아키텍처를 보여줍니다.

pg_auto_failover 아키텍처에는 노드 구성이 포함됩니다.

그림 6. pg_auto_failover 아키텍처의 다이어그램

그림 6은 두 가지 기본 구성요소인 Monitor 서비스와 Keeper 에이전트로 구성되는 pg_auto_failover 아키텍처를 보여줍니다. Keeper 및 Monitor는 모두 pg_auto_failover 확장 프로그램에 포함되어 있습니다.

Monitor 서비스

pg_auto_failover Monitor 서비스는 PostgreSQL 확장 프로그램으로 구현됩니다. 이 서비스는 Monitor 노드를 만들 때 pg_auto_failover 확장 프로그램이 사용 설정된 PostgreSQL 인스턴스를 시작합니다. Monitor는 구성의 전역 상태를 유지하고, 멤버 PostgreSQL 데이터 노드에서 상태 확인 상태를 가져오고, 유한 상태 머신(FSM)에서 설정한 규칙을 사용하여 그룹을 조정합니다. 상태 전환에 관한 FSM 규칙에 따라 Monitor는 승격, 강등, 구성 변경 같은 작업에 대한 지침을 그룹 노드에 전달합니다.

Keeper 에이전트

각 pg_auto_failover 데이터 노드에서 확장 프로그램이 Keeper 에이전트 프로세스를 시작합니다. 이 Keeper 프로세스는 PostgreSQL 서비스를 관찰하고 관리합니다. Keeper는 상태 업데이트를 Monitor 노드로 전송하고 Monitor가 응답으로 전송하는 작업을 수신 및 실행합니다.

기본적으로 pg_auto_failover는 모든 그룹 보조 데이터 노드를 동기 복제본으로 설정합니다. 커밋에 필요한 동기 복제본 수는 Monitor에 설정하는 number_sync_standby 구성을 기준으로 합니다.

장애 감지

기본 및 보조 데이터 노드의 Keeper 에이전트는 주기적으로 Monitor 노드에 연결하여 현재 상태를 알리고 실행할 작업이 있는지 확인합니다. 또한, Monitor 노드는 PostgreSQL 프로토콜(libpq) API 호출을 실행하고, pg_isready() PostgreSQL 클라이언트 애플리케이션을 시작하여 데이터 노드에 연결하여 상태 확인을 수행합니다. 일정 시간(기본적으로 30초) 후 이러한 작업이 모두 성공하지 못하면 Monitor 노드는 데이터 노드 오류가 발생했다고 결정합니다. PostgreSQL 구성 설정을 변경하여 모니터 시간 및 재시도 횟수를 맞춤설정할 수 있습니다. 자세한 내용은 장애 조치 및 내결함성을 참조하세요.

단일 노드 장애가 발생하면 다음 중 하나에 해당합니다.

  • 비정상 데이터 노드가 기본 노드인 경우 Monitor가 장애 조치를 시작합니다.
  • 비정상 데이터 노드가 보조 노드이면 Monitor가 비정상 노드의 동기 복제를 사용 중지합니다.
  • 장애 발생 노드가 Monitor 노드이면 자동 장애 조치를 수행할 수 없습니다. 이 단일 장애점을 방지하려면 올바른 모니터링 및 재해 복구가 설정되었는지 확인해야 합니다.

다음 다이어그램은 이전 목록에서 설명한 장애 시나리오와 구성 결과 상태를 보여줍니다.

기본, 보조, 모니터 노드 장애에 대한 pg_auto_failover 장애 시나리오

그림 7. pg_auto_failover 장애 시나리오 다이어그램

장애 조치 프로세스

그룹의 각 데이터베이스 노드에는 장애 조치 프로세스를 결정하는 다음 구성 옵션이 포함됩니다.

  • replication_quorum: 부울 옵션입니다. replication_quorumtrue로 설정되었으면 노드가 잠재적인 장애 조치 후보로 간주됩니다.
  • candidate_priority: 0~100까지의 정수 값입니다. candidate_priority에는 장애 조치 우선순위에 영향을 주기 위해 변경할 수 있는 기본값 50이 포함됩니다. 노드는 candidate_priority 값 기준의 잠재적 장애 조치 후보로 우선순위가 지정됩니다. 노드의 candidate_priority 값이 높을수록 우선순위가 높습니다. 장애 조치 프로세스에서는 모든 pg_auto_failover 구성에서 최소 2개 이상의 노드에 0이 아닌 후보 우선순위가 포함되어야 합니다.

기본 노드에 장애가 발생할 경우, 보조 노드는 활성 동기 복제가 있고 replication_quorum의 구성원일 경우 기본 노드로 승격 가능한 것으로 간주됩니다.

보조 노드는 다음의 점진적 기준에 따라 승격 대상으로 간주됩니다.

  • 후보 우선순위가 가장 높은 노드
  • Monitor에 가장 높은 WAL 로그 위치가 게시된 대기 노드
  • 최종 연장전으로 무작위 선택

장애 조치 후보는 WAL에서 가장 앞에 있는 LSN 위치를 게시하지 않은 경우의 지연 후보입니다. 이 시나리오에서 pg_auto_failover는 장애 조치 메커니즘에서 중간 단계를 조정합니다. 지연 후보는 가장 앞에 있는 LSN 위치를 포함하는 대기 노드에서 누락된 WAL 바이트를 가져옵니다. 그런 후 대기 노드가 승격됩니다. Postgres는 연속 복제에 따라 모든 대기가 다른 대기의 업스트림 노드로 작동할 수 있기 때문에 이러한 작업을 허용합니다.

쿼리 라우팅

pg_auto_failure는 서버 측 쿼리 라우팅 기능을 제공하지 않습니다. 대신 pg_auto_failure는 공식 PostgreSQL 클라이언트 드라이버 libpq를 사용하는 클라이언트 측 쿼리 라우팅을 사용합니다. 연결 URI를 정의할 때 이 드라이버는 해당 host 키워드에서 여러 호스트를 허용할 수 있습니다.

완전히 자동화된 장애 조치를 지원하려면 애플리케이션에서 사용하는 클라이언트 라이브러리가 libpq를 래핑하거나 아키텍처에 여러 호스트를 제공하는 기능을 구현해야 합니다.

대체 및 전환 프로세스

Keeper 프로세스가 장애 발생 노드를 다시 시작하거나 새 대체 노드를 시작하면 프로세스가 Monitor 노드를 확인하여 수행할 다음 작업을 결정합니다. 장애 발생 후 다시 시작된 노드가 이전에 기본 노드였는데 Monitor가 장애 조치 프로세스에 따라 이미 새 기본 인스턴스를 선택한 경우 Keeper는 이 비활성 기본 인스턴스를 보조 복제본으로 다시 초기화합니다.

pg_auto_failure는 전환을 실행하여 노드 장애 조치 프로세스를 테스트할 수 있게 해주는 pg_autoctl 도구를 제공합니다. 이 도구는 운영자가 프로덕션 환경에서 HA 설정을 테스트할 수 있게 해줄 뿐만 아니라, 장애 조치 후 HA 클러스터를 다시 정상 상태로 복원하도록 지원합니다.

스테이트풀(Stateful) MIG 및 리전 영구 디스크를 사용하는 HA

이 섹션에서는 다음 Google Cloud 구성요소를 사용하는 HA 접근 방식을 설명합니다.

  • 리전 영구 디스크 리전 영구 디스크를 사용할 때 데이터는 한 리전의 두 영역 간에 동기적으로 복제되므로, 스트리밍 복제를 사용할 필요가 없습니다. 하지만 HA는 한 리전에서 정확히 2개의 영역으로 제한됩니다.
  • 스테이트풀(Stateful) 관리형 인스턴스 그룹. 스테이트풀(Stateful) MIG 쌍은 하나의 기본 PostgreSQL 노드가 계속 실행되도록 하기 위한 컨트롤 플레인의 일부로 사용됩니다. 스테이트풀(Stateful) MIG가 새 인스턴스를 시작할 때 기존 리전 영구 디스크를 연결할 수 있습니다. 단일 시점에 두 MIG 중 하나만 실행 중인 인스턴스를 가집니다.
  • Cloud Storage. Cloud Storage 버킷의 객체에는 두 MIG 중 어떤 쪽에서 기본 데이터베이스 노드를 실행 중인지 및 어떤 MIG에 장애 조치 인스턴스를 만들어야 하는지를 나타내는 구성이 포함됩니다.
  • MIG 상태 확인 및 자동 복구. 상태 확인은 인스턴스 상태를 모니터링합니다. 실행 중인 노드가 비정상이 되면 상태 확인으로 자동 복구 프로세스가 시작됩니다.
  • 로깅. 자동 복구가 기본 노드를 중지하면 Logging에 항목이 기록됩니다. 필터를 사용하여 관련 로그 항목을 Pub/Sub 싱크 주제로 내보냅니다.
  • 이벤트 기반 Cloud Run Functions. Pub/Sub 메시지가 Cloud Run Functions를 트리거합니다. Cloud Run Functions는 Cloud Storage의 구성을 사용하여 각 스테이트풀(Stateful) MIG에 대해 수행할 작업을 결정합니다.
  • 내부 패스 스루 네트워크 부하 분산기. 부하 분산기는 그룹에서 현재 실행 중인 인스턴스에 대한 라우팅을 제공합니다. 따라서 인스턴스 재생성으로 인해 발생하는 인스턴스 IP 주소 변경이 클라이언트로부터 추상화됩니다.

다음 다이어그램은 스테이트풀(Stateful) MIG 및 리전 영구 디스크를 사용하는 HA 예시를 보여줍니다.

HA에 스테이트풀(Stateful MIG) 및 리전 영구 디스크가 사용됩니다.

그림 8. 스테이트풀(Stateful) MIG 및 리전 영구 디스크를 사용하는 HA의 다이어그램입니다.

그림 8은 클라이언트 트래픽을 제공하는 정상 상태의 기본 노드를 보여줍니다. 클라이언트는 내부 패스 스루 네트워크 부하 분산기의 고정 IP 주소에 연결됩니다. 부하 분산기는 현재 MIG의 일부로 실행 중인 VM으로 클라이언트 요청을 라우팅합니다. 데이터 볼륨은 마운트된 리전 영구 디스크에 저장됩니다.

이 접근 방식을 구현하려면 PostgreSQL을 사용하여 MIG의 인스턴스 템플릿으로 사용할 초기화 중 시작되는 VM 이미지를 만듭니다. 또한 노드에서 HTTP 기반 상태 확인(예: pgDoctor)을 구성해야 합니다. HTTP 기반 상태 확인은 부하 분산기 및 인스턴스 그룹이 모두 PostgreSQL 노드의 상태를 확인할 수 있게 해줍니다.

리전 영구 디스크

리전의 두 영역 간에 동기 데이터 복제를 제공하는 블록 스토리지 기기를 프로비저닝하려면 Compute Engine 리전 영구 디스크 스토리지 옵션을 사용하면 됩니다. 리전 영구 디스크는 PostgreSQL의 기본 제공 스트리밍 복제에 의존하지 않는 PostgreSQL HA 옵션을 구현하기 위한 기본 구성 요소를 제공할 수 있습니다.

인프라 장애 또는 영역 장애로 인해 기본 노드 VM 인스턴스를 사용할 수 없게 되면 리전 영구 디스크를 동일한 리전의 백업 영역에 있는 VM 인스턴스에 강제로 연결할 수 있습니다.

백업 영역의 VM 인스턴스에 리전 영구 디스크를 연결하려면 다음 중 하나를 수행하면 됩니다.

  • 백업 영역에서 콜드 대기 VM 인스턴스를 유지관리합니다. 콜드 대기 VM 인스턴스는 리전 영구 디스크가 마운트되지 않은 중지된 VM 인스턴스이지만 기본 노드 VM 인스턴스와 동일한 VM 인스턴스입니다. 오류가 발생하면 콜드 대기 VM이 시작되고 리전 영구 디스크가 마운트됩니다. 콜드 대기 인스턴스 및 기본 노드 인스턴스에는 동일한 데이터가 포함됩니다.
  • 동일한 인스턴스 템플릿을 사용하여 스테이트풀(Stateful) MIG 쌍을 만듭니다. MIG는 상태 확인을 제공하며 컨트롤 플레인의 일부로 작동합니다. 기본 노드가 실패하면 대상 MIG에 장애 조치 인스턴스가 선언적으로 생성됩니다. 대상 MIG는 Cloud Storage 객체에 정의됩니다. 인스턴스별 구성은 리전 영구 디스크를 연결하는 데 사용됩니다.

데이터 서비스 중단이 즉시 식별된 경우 강제 연결 작업은 일반적으로 1분 이내에 완료되므로 분 단위의 RTO를 구현할 수 있습니다.

기업에서 서비스 중단을 감지하고 알리며 장애 조치를 수동으로 수행하는 데 필요한 추가 다운타임을 허용할 수 있다면 강제 연결 프로세스를 자동화할 필요가 없습니다. RTO 허용 범위가 낮으면 감지 및 장애 조치 프로세스를 자동화할 수 있습니다. 또는 PostgreSQL용 Cloud SQL이 HA 방식의 완전 관리형 구현을 제공합니다.

오류 감지 및 장애 조치 프로세스

HA 접근 방식은 인스턴스 그룹의 자동 복구 기능을 사용하여 상태 확인을 사용해서 노드 상태를 모니터링합니다. 실패한 상태 확인이 있으면 기존 인스턴스가 비정상으로 간주되고 인스턴스가 중지됩니다. 이 중지는 Logging, Pub/Sub, 트리거된 Cloud Run Functions 함수를 사용한 장애 조치 프로세스를 시작합니다.

이 VM에 항상 리전 디스크가 마운트되어야 한다는 요구사항을 충족하기 위해 Cloud Run Functions는 두 MIG 중 하나를 구성하여 리전 영구 디스크가 있는 두 영역 중 하나에 인스턴스를 만듭니다. 노드가 실패하면 Cloud Storage에 유지된 상태에 따라 대체 영역에서 대체 인스턴스가 시작됩니다.

영역 오류 중 대체 인스턴스가 시작됩니다.

그림 9. MIG의 영역 오류 다이어그램

그림 9에서는 영역 A의 이전 기본 노드에 장애가 발생했고 Cloud Run Functions가 MIG B를 구성하여 영역 B에서 새 기본 인스턴스를 시작했습니다. 새 기본 노드의 상태를 모니터링하도록 장애 감지 메커니즘이 자동으로 구성됩니다.

쿼리 라우팅

내부 패스 스루 네트워크 부하 분산기는 클라이언트를 PostgreSQL 서비스를 실행 중인 인스턴스로 라우팅합니다. 부하 분산기는 인스턴스 그룹과 동일한 상태 확인을 사용하여 인스턴스를 사용해서 쿼리를 제공할 수 있는지 확인합니다. 다시 생성하는 중이기 때문에 노드를 사용할 수 없으면 연결이 실패합니다. 인스턴스가 백업된 후 상태 확인이 전달을 시작하고 새 연결이 사용 가능한 노드로 라우팅됩니다. 실행 노드가 하나만 있기 때문에 이 설정에는 읽기 전용 노드가 없습니다.

대체 프로세스

기본 하드웨어 문제로 인해 데이터베이스 노드의 상태 확인이 실패하면 다른 기본 인스턴스에서 노드가 다시 생성됩니다. 이 시점에서 아키텍처는 추가 단계 없이 원래 상태로 돌아갑니다. 하지만 영역 오류가 있으면 첫 번째 노드가 복구될 때까지 성능 저하된 상태로 설정이 계속 실행됩니다. 매우 드물지만 리전 영구 디스크 복제 및 스테이트풀(Stateful) MIG에 대해 구성된 영역 모두에 동시 오류가 발생하면 PostgreSQL 인스턴스가 복구될 수 없습니다. 이러한 서비스 중단 중에는 데이터베이스가 요청을 처리할 수 없습니다.

HA 옵션 간 비교

다음 표에서는 Patroni, pg_auto_failover, 스테이트풀(Stateful) MIG에서 리전 영구 디스크로 사용할 수 있는 HA 옵션을 비교합니다.

설정 및 아키텍처

Patroni pg_auto_failover 리전 영구 디스크가 있는 스테이트풀(Stateful) MIG

HA 아키텍처, DCS 설정 및 모니터링과 알림이 필요합니다. 데이터 노드의 에이전트 설정은 비교적 직관적입니다.

PostgreSQL 이외의 다른 외부 종속 항목은 필요하지 않습니다. 모니터 전용 노드가 필요합니다. 모니터 노드에 단일 장애점(SPOF)가 아님을 확인하기 위해 HA 및 DR이 필요합니다. Google Cloud 서비스로만 구성된 아키텍처입니다. 한 번에 하나의 활성 데이터베이스 노드만 실행합니다.

고가용성 구성

Patroni pg_auto_failover 리전 영구 디스크가 있는 스테이트풀(Stateful) MIG
극단적으로 구성 가능: 동기 및 비동기 복제를 모두 지원하고, 동기 및 비동기로 구성할 노드를 지정할 수 있습니다. 동기 노드의 자동 관리를 포함합니다. 여러 영역 및 멀티 리전 HA 설정을 허용합니다. DCS에 액세스할 수 있어야 합니다. Patroni와 유사: 매우 구성 가능합니다. 하지만 모니터가 단일 인스턴스로만 제공되기 때문에 모든 설정 유형에서 이 노드에 대한 액세스를 고려해야 합니다. 동기 복제를 사용하는 단일 리전의 두 영역으로 제한됩니다.

네트워크 파티션 처리 기능

Patroni pg_auto_failover 리전 영구 디스크가 있는 스테이트풀(Stateful) MIG
OS 수준 모니터를 통한 자가 방어로 분할 브레인을 방지합니다. DCS에 연결하지 못하면 기본 노드가 복제본으로 자체 강등되고 장애 조치가 트리거되어 가용성을 통한 내구성을 보장합니다. 기본 노드부터 모니터 노드, 복제본까지의 상태 확인 조합을 사용하여 네트워크 파티션을 감지하고 필요한 경우 자체 강등합니다. 해당 없음: 활성 PostgreSQL 노드가 한 번에 하나만 있기 때문에 네트워크 파티션이 없습니다.

클라이언트 구성

Patroni pg_auto_failover 리전 영구 디스크가 있는 스테이트풀(Stateful) MIG
부하 분산기에 연결되기 때문에 클라이언트에 투명합니다. 부하 분산기가 손쉽게 클라이언트 라이브러리를 향할 수 없기 때문에 클라이언트 라이브러리가 설정에서 여러 호스트 정의를 지원해야 합니다. 부하 분산기에 연결되기 때문에 클라이언트에 투명합니다.

PostgreSQL 노드 초기화 자동화, 구성 관리

Patroni pg_auto_failover 리전 영구 디스크가 있는 스테이트풀(Stateful) MIG
PostgreSQL 구성(patronictl edit-config) 관리 도구를 제공하고 클러스터에서 새 노드 또는 다시 시작된 노드를 자동으로 초기화합니다. pg_basebackup 또는 WALL-E 및 barman과 같은 다른 도구를 사용하여 노드를 초기화할 수 있습니다. 노드를 자동으로 초기화하지만 새 복제본 노드를 초기화할 때 pg_basebackup만 사용하도록 제한됩니다. 구성 관리는 pg_auto_failover 관련 구성으로 제한됩니다. 공유 디스크가 있는 스테이트풀(Stateful) 인스턴스 그룹은 PostgreSQL 노드 초기화가 필요하지 않습니다. 항상 노드가 하나만 실행되므로, 구성 관리가 단일 노드로 수행됩니다.

맞춤설정 가능성 및 기능 다양성

Patroni pg_auto_failover 리전 영구 디스크가 있는 스테이트풀(Stateful) MIG

강등 또는 승격과 같은 주요 단계에서 사용자가 정의할 수 있는 작업을 호출할 수 있도록 후크 인터페이스를 제공합니다.

다양한 유형의 DCS 지원, 다양한 복제본 초기화 방법, 다양한 PostgreSQL 구성 제공 방법과 같은 기능이 풍부한 구성을 지원합니다.

클러스터 간 마이그레이션을 쉽게 수행할 수 있도록 연결된 복제본 클러스터를 허용하는 대기 클러스터를 설정할 수 있습니다.

비교적 새로운 프로젝트이므로 제한적입니다. 해당 없음

성숙도

Patroni pg_auto_failover 리전 영구 디스크가 있는 스테이트풀(Stateful) MIG
프로젝트는 2015년부터 출시되었으며 Zalando 및 GitLab과 같은 대기업에서 프로덕션에 사용되고 있습니다. 2019년 초반에 발표된 비교적 새로운 프로젝트입니다. Google Cloud 제품의 일반 안정화 버전으로만 구성됩니다.

다음 단계