EDB Postgres Distributed(PGD)로 간단하게 클러스터링 및 복제 구성하기
작성자: Phil Eaton
2025년 9월 10일
이제 EDB Postgres Distributed (PGD)용 새로운 CLI를 사용할 수 있습니다. 이 CLI를 사용하면 PGD 노드 클러스터를 간편하게 만들 수 있습니다. PGD 노드는 PGD 메타데이터를 가진 Postgres 인스턴스로, 서로 연결되어 DDL(스키마)과 DML(데이터)을 논리적 복제로 동기화합니다.
PGD의 철학은 클라우드 네이티브적입니다. 어떤 노드에 문제가 생겨도 삭제한 후 다시 생성하면 놓친 데이터를 모두 자동으로 재동기화합니다.
이 글에서는 AWS에서 세 개의 PGD 노드로 구성된 클러스터를 만드는 간단한 수동 방법을 살펴봅니다. 완전한 프로덕션 환경을 위한 설정은 아니지만, PGD를 시작하는 데 도움이 될 수 있습니다. 클러스터를 구성한 후에는 복제와 노드 삭제 및 재생성 과정도 테스트합니다.
3개의 EC2 인스턴스 생성
먼저 Ubuntu 24.04 t3.micro EC2 인스턴스 세 개를 생성하고 각 인스턴스에 8GB 디스크를 할당합니다. 동일한 보안 그룹에 배치합니다. 인스턴스가 생성되면 보안 그룹을 수정하여 이 보안 그룹 내부에서 오는 모든 TCP 인바운드 연결을 허용합니다.
각 노드에서의 설정
1) 구독 토큰 설정
무료 EDB 계정에 로그인하거나 계정을 등록한 후 구독 토큰을 가져옵니다. 토큰을 환경 변수로 설정합니다.
export EDB_SUBSCRIPTION_TOKEN=whatever-it-is
2) 저장소 추가
PGD와 EDB Postgres Extended(EDB의 Postgres 배포판)용 저장소를 설정합니다.
curl -1sLf "https://downloads.enterprisedb.com/$EDB_SUBSCRIPTION_TOKEN/postgres_distributed/setup.deb.sh" | sudo -E bash
curl -1sLf "https://downloads.enterprisedb.com/$EDB_SUBSCRIPTION_TOKEN/enterprise/setup.deb.sh" | sudo -E bash
3) 패키지 설치
sudo apt-get update -y
sudo apt-get install -y edb-pgd6-expanded-pgextended17
postgres 사용자로 전환
sudo su postgres
cd ~
각 노드를 프라이빗 IP 주소로 식별합니다. 예를 들어:
export NODE0="172.31.38.10"
export NODE1="172.31.35.26"
export NODE2="172.31.43.94"
추가로 아래 변수를 지정합니다.
export PGPASSWORD="some password" # 비밀번호는 반드시 변경
export PATH=$PATH:/usr/lib/edb-pge/17/bin/
$NODE0에서의 설정
pgd node node0 setup \
--dsn "host=$NODE0 dbname=pgddb user=postgres" \
--listen-addr "$NODE0,localhost" \
--initial-node-count 3 \
--pgdata $HOME/pgddb \
--log-file $HOME/postgres.logfile \
--group-name "pgd"
클러스터 레이아웃을 확인합니다.
$ pgd --dsn "host=$NODE0 dbname=pgddb user=postgres" nodes list
Node Name | Group Name | Node Kind | Join State | Node Status
-----------+------------+-----------+------------+-------------
node0 | pgd | data | ACTIVE | Up
헬스 체크를 확인합니다.
$ pgd --dsn 'host=localhost dbname=pgddb user=postgres' cluster show
# Summary
Group Name | Parent Group | Group Type | Node Name | Node Kind
------------+--------------+------------+-----------+-----------
pgd | | global | node0 | data
# Health
Check | Status | Details
-------------------+--------+-------------------------------------------------
Connections | Ok | All BDR nodes are accessible
Raft | Ok | Raft Consensus is working correctly
Replication Slots | Ok | All PGD replication slots are working correctly
Clock Drift | Ok | Clock drift is within permissible limit
Versions | Ok | All nodes are running the same PGD version
# Clock Drift
Reference Node | Node Name | Clock Drift
----------------+-----------+-------------
출력 결과에서 연결 상태, 합의(Raft), 복제 슬롯, 클럭 드리프트, 버전 등이 정상임을 확인할 수 있습니다.
$NODE1에서의 설정
두 번째 PGD 노드를 설정합니다. ($NODE1에 postgres 사용자로 로그인되어 있는지 확인하세요.)
pgd node "node1" setup \
--dsn "host=$NODE1 dbname=pgddb user=postgres" \
--listen-addr "$NODE1,localhost" \
--pgdata $HOME/pgddb \
--log-file $HOME/postgres.logfile \
--cluster-dsn "host=$NODE0 dbname=pgddb user=postgres" \
--cluster-name "pgd"
이제 $NODE0 또는 $NODE1에서 모든 노드를 확인할 수 있습니다.
$ pgd --dsn "host=$NODE0 dbname=pgddb user=postgres" nodes list
Node Name | Group Name | Node Kind | Join State | Node Status
-----------+------------+-----------+------------+-------------
node0 | pgd | data | ACTIVE | Up
node1 | pgd | data | ACTIVE | Up
$NODE2에서의 설정
세 번째 PGD 노드를 설정합니다. ($NODE2에 postgres 사용자로 로그인되어 있는지 확인하세요.)
pgd node "node2" setup \
--dsn "host=$NODE2 dbname=pgddb user=postgres" \
--listen-addr "$NODE2,localhost" \
--pgdata $HOME/pgddb \
--log-file $HOME/postgres.logfile \
--cluster-dsn "host=$NODE0 dbname=pgddb user=postgres" \
--cluster-name "pgd"
이제 클러스터 내 어느 노드에서든 pgd nodes list 명령을 실행하면 세 개의 노드가 모두 표시됩니다.
$ pgd --dsn "host=$NODE0 dbname=pgddb user=postgres" nodes list
Node Name | Group Name | Node Kind | Join State | Node Status
-----------+------------+-----------+------------+-------------
node0 | pgd | data | ACTIVE | Up
node1 | pgd | data | ACTIVE | Up
node2 | pgd | data | ACTIVE | Up
DDL과 DML 복제
클러스터 구성이 끝났으니 이제 PGD를 사용해봅니다. $NODE0에 orders 테이블을 만들고 백만 개의 행을 삽입합니다.
DSN을 사용하기 때문에 어디에서 실행하든 실제로는 $NODE0에서 동작하게 됩니다.
$ psql "host=$NODE0 dbname=pgddb user=postgres" -c "
BEGIN;
DROP TABLE IF EXISTS orders;
CREATE TABLE orders (
customer_id INT,
order_id BIGSERIAL,
amount_pennies BIGINT,
PRIMARY KEY (customer_id, order_id)
);
INSERT INTO orders (customer_id, amount_pennies)
SELECT
random() * 9 + 1,
random() * 100000 + 1
FROM
generate_series(1, 1_000_000);
COMMIT;"
출력:
$ psql "host=$NODE0 dbname=pgddb user=postgres" -c "SELECT count(1) FROM orders"
count
---------
1000000
(1 row)
$ psql "host=$NODE1 dbname=pgddb user=postgres" -c "SELECT count(1) FROM orders"
count
---------
1000000
(1 row)
$ psql "host=$NODE2 dbname=pgddb user=postgres" -c "SELECT count(1) FROM orders"
count
---------
1000000
(1 row)테이블이 모든 노드에 생성되었고 데이터도 복제되었습니다.
$NODE2 제거 및 재생성
예를 들어 $NODE2에 문제가 생겨 다시 프로비저닝해야 한다고 가정해봅시다. 먼저 클러스터에 이 노드를 제거하도록 알립니다.
$ pgd --dsn 'host=$NODE0 dbname=pgddb user=postgres' node node2 part
Starting a part node operation for node: node2
This may take some time, please wait...
NOTICE: node node2 has been removed from the BDR group
이제 $NODE2에서 Postgres를 중지하고 데이터 디렉토리를 삭제한 뒤, 위에서 사용했던 pgd node setup 명령을 다시 실행합니다.
$ pg_ctl -D $HOME/pgddb -l $HOME/postgres.logfile stop
waiting for server to shut down.... done
server stopped
$ rm -rf $HOME/postgres.logfile $HOME/pgddb
먼저 클러스터 상태를 조회하여 이 노드가 제거된 것을 확인합니다.
$ pgd --dsn "host=$NODE0 dbname=pgddb user=postgres" nodes list
Node Name | Group Name | Node Kind | Join State | Node Status
-----------+------------+-----------+------------+-------------
node0 | pgd | data | ACTIVE | Up
node1 | pgd | data | ACTIVE | Up
이제 $NODE2를 다시 빌드합니다.
$ pgd node "node2" setup \
--dsn "host=$NODE2 dbname=pgddb user=postgres" \
--listen-addr "$NODE2,localhost" \
--pgdata $HOME/pgddb \
--log-file $HOME/postgres.logfile \
--cluster-dsn "host=$NODE0 dbname=pgddb user=postgres" \
--cluster-name "pgd"
다시 노드 목록을 확인합니다.
$ pgd --dsn "host=$NODE0 dbname=pgddb user=postgres" nodes list
Node Name | Group Name | Node Kind | Join State | Node Status
-----------+------------+-----------+------------+-------------
node0 | pgd | data | ACTIVE | Up
node1 | pgd | data | ACTIVE | Up
node2 | pgd | data | ACTIVE | Up
노드가 다시 클러스터에 합류했습니다. 재생성하기 전 클러스터에 있던 테이블과 데이터도 모두 복구되었습니다.
$ psql "host=$NODE2 dbname=pgddb user=postgres" -c "SELECT count(1) FROM orders"
count
---------
1000000
(1 row)
롤링 업그레이드 활용
참고로 이 재생성 과정을 클러스터 롤링 업그레이드에도 사용할 수 있습니다.
- 클러스터에서 노드 하나를 제거
- 더 최신 버전의 Postgres와 PGD를 가진 새 노드를 프로비저닝
- 새 노드를 클러스터에 조인
이 과정을 모든 노드에 반복하면 클러스터 전체가 최신 버전의 Postgres와 PGD로 업그레이드됩니다.
메일: salesinquiry@enterprisedb.com