본문으로 건너뛰기
2.1 전체 구조

2.1 전체 구조

Patroni 클러스터는 세 종류의 구성 요소로 이루어진다. PostgreSQL이 도는 각 노드에는 Patroni 데몬이 함께 상주하고, 클러스터 바깥에는 상태를 공유하는 DCS(Distributed Configuration Store)가 있으며, 각 데몬은 REST API 서버를 열어 서로를 조회한다. failover, 설정 전파, split brain 방지까지 Patroni의 모든 동작은 이 세 요소의 상호작용으로 설명된다.

구성 요소 배치

    flowchart TD
  subgraph N1["노드 1 (primary)"]
    A1["Patroni 데몬"]
    D1["PostgreSQL"]
    A1 -->|"기동/정지"| D1
  end
  subgraph N2["노드 2 (replica)"]
    A2["Patroni 데몬"]
    D2["PostgreSQL"]
    A2 -->|"기동/정지"| D2
  end
  DCS["DCS<br/>(etcd, Consul 등)"]
  A1 -->|"leader lock 갱신"| DCS
  A2 -->|"leader key 감시"| DCS
  A1 <-->|"REST API 조회"| A2
  D1 -.->|"streaming replication"| D2
  

노드가 셋이든 다섯이든 그림은 같은 패턴으로 확장된다. 모든 노드는 자기 PostgreSQL을 관리하는 Patroni 데몬을 하나씩 가지며, 클러스터 차원의 합의는 전부 DCS를 거친다.

노드 안: Patroni 데몬과 PostgreSQL

Patroni 데몬은 같은 노드의 PostgreSQL 인스턴스를 관리한다. 여기서 관리는 추상적인 감시가 아니다. 공식 FAQ에 따르면 Patroni는 pg_ctl, postgres 같은 PostgreSQL 바이너리를 직접 실행해 인스턴스의 기동과 정지를 수행한다. replica를 primary로 promote하는 것도, 죽은 인스턴스를 다시 기동하는 것도 Patroni 데몬의 일이다.

이 구조에서 나오는 규칙이 하나 있다. PostgreSQL을 기동하고 정지하는 주체는 클러스터에서 Patroni 하나여야 한다. 공식 FAQ는 systemd의 postgresql.service 같은 다른 관리 주체를 반드시(MUST) 비활성화하라고 명시한다.

# 배포판이 설치한 PostgreSQL systemd unit은 꺼 둔다
systemctl disable --now postgresql.service
systemd가 PostgreSQL을 자동 재기동하도록 남겨 두면, Patroni가 의도적으로 내린 인스턴스(demote 과정의 정지 등)를 systemd가 되살리는 식으로 두 관리 주체가 충돌한다. Patroni 배포 시 가장 먼저 점검할 항목이다.

클러스터 바깥: DCS

DCS는 클러스터의 상태를 저장하는 공유 저장소다. 현재 leader인 멤버의 이름을 담는 leader lock을 비롯해, 클러스터 설정과 각 멤버의 상태가 여기에 기록된다. Patroni는 leader 선출과 split brain 방지에 필요한 합의를 자체 구현하지 않고 etcd, Consul, ZooKeeper, Kubernetes API 같은 외부 저장소에 맡긴다. 백엔드별 특성과 선택 기준은 Part III. DCS 백엔드에서 다루고, 어떤 키가 저장되는지는 2.3 DCS에 저장되는 것들에 정리했다.

DCS 경로를 결정하는 식별자는 patroni.yml의 최상위 설정 세 개다.

scope: demo          # 클러스터 이름 (전 노드 동일)
namespace: /service  # DCS 경로 프리픽스 (기본값 /service)
name: node1          # 멤버 이름 (노드마다 유일)

노드 사이: REST API

각 Patroni 데몬은 REST API 서버를 함께 연다. 용도는 크게 세 갈래다. 첫째, 노드 상태 조회다. leader lock이 만료되어 leader race가 열리면 각 노드는 다른 노드의 GET /patroni 엔드포인트를 호출해 상대 상태를 확인한다. 둘째, 외부 헬스체크다. HAProxy 같은 로드밸런서가 어느 노드가 primary인지 판별하는 데 쓴다. 셋째, 구성 변경의 창구다. DCS에 저장되는 dynamic configuration은 REST API로도 변경 가능하다. 엔드포인트 전체 목록과 보안은 Part VIII. REST API에서 다룬다.

DCS가 응답하지 않는 비상 상황에서 primary가 멤버들에게 직접 생존을 확인받는 failsafe mode 역시 이 REST API 위에서 동작한다. 상세는 2.5 DCS 장애와 failsafe mode 참고.

정리

각 노드의 Patroni 데몬이 PostgreSQL 바이너리를 직접 실행해 인스턴스의 생애를 전담하고, 클러스터 차원의 판단은 DCS에 저장된 상태를 근거로 내린다. 노드끼리는 REST API로 서로의 상태를 조회한다. PostgreSQL을 건드리는 관리 주체를 Patroni 하나로 좁히는 것이 이 구조가 성립하는 전제 조건이다.