12.3 Citus 통합
Citus는 PostgreSQL을 여러 노드에 걸친 분산 데이터베이스로 확장하는 extension이다. coordinator가 쿼리를 받아 worker들의 shard로 분배하는 구조인데, coordinator와 worker 각각이 단일 장애점이 되므로 노드 그룹마다 HA가 필요하다. Patroni는 3.0부터 Citus 통합을 내장했다. 공식 문서의 표현을 빌리면 coordinator와 worker는 “physically different PostgreSQL/Patroni clusters that are just logically grouped together”, 즉 물리적으로는 서로 다른 Patroni 클러스터이고 논리적으로만 하나의 Citus 클러스터로 묶인다.
설정: citus 섹션 2키
patroni.yml에 넣을 것은 두 키뿐이다.
scope: demo
citus:
group: 0 # coordinator 는 0, worker 는 1, 2, 3, ...
database: citus # 전 노드에서 동일해야 함group은 이 노드가 속한 Citus 그룹의 정수 id다. coordinator가 0, worker 그룹이 1 이상을 쓴다. database는 citus extension을 만들 database 이름으로, coordinator와 worker 전부 같아야 하고 현재는 단일 database만 지원한다.
전제 조건은 다음과 같다.
- Citus 10.0 이상. 투명한 worker switchover와 재시작은 Citus 11.2 이상 권장
- superuser 자격증명이 coordinator와 모든 worker에서 동일
- worker에서 coordinator로의 REST API 접근 허용
scope가 전 그룹에서 동일- citus extension이 모든 노드에 설치
Patroni가 대신해 주는 것
citus 섹션이 있으면 Patroni가 Citus 운영에 필요한 배선을 자동으로 처리한다.
citus를shared_preload_libraries에 추가한다max_prepared_transactions가 설정되어 있지 않으면2 * max_connections로 잡는다 (Citus의 2PC 트랜잭션용)bootstrap.dcs.synchronous_mode를quorum으로 설정한다citus.local_hostname을 localhost에서 실제 접속 가능한 값으로 조정한다- superuser 자격증명을
pg_dist_authinfo에 넣어 노드 간 인증을 연결한다 - coordinator의 primary가 worker 그룹의 primary들을 자동 발견해
pg_dist_node에 등록한다 - worker 그룹에서 failover나 switchover가 나면
pg_dist_node를 갱신해 coordinator가 새 primary를 가리키게 한다
Citus에서 노드 명단의 정본은 coordinator의 pg_dist_node 테이블이다. 이 테이블 관리가 Patroni 손에 들어간다는 것이 통합의 실질이다. DBA가 worker 주소를 직접 등록하고 장애 때마다 고쳐 줄 필요가 없어진다.
pg_dist_authinfo의 인증 정보도 함께 걸려 있으므로 주의해서 진행한다. Patroni 4.0.0부터는 noloadbalance tag가 없는 Citus secondary 노드도 pg_dist_node에 등록되어, read-only 쿼리를 secondary로 보내는 구성에 쓰인다 (해당 GUC 설정 필요).worker switchover 흐름
분산 클러스터에서 까다로운 지점은 worker의 primary가 바뀌는 순간이다. coordinator가 구 primary로 쿼리를 계속 보내면 오류가 나므로, Patroni는 coordinator의 해당 shard 트래픽을 잠시 멈췄다가 새 primary로 재개한다. 그 통지 수단이 citus_update_node()다.
flowchart TD
A["worker 구 primary<br/>switchover 시작"]
B["coordinator에 통지<br/>citus_update_node"]
C["coordinator가 해당<br/>worker 트래픽 일시정지"]
D["worker replica<br/>promote"]
E["새 primary 준비<br/>완료 통지"]
F["트래픽 재개<br/>(새 primary 주소)"]
A --> B --> C --> D --> E --> F
worker가 정지하기 전에 coordinator에 알리고, promote가 끝나 새 primary가 준비되면 다시 알려 멈춰 둔 트래픽을 흘려보낸다. 클라이언트 입장에서는 해당 shard 쿼리가 잠시 대기했다가 이어지는 모양이 된다.
patronictl에서의 Citus
patronictl list는 Citus 클러스터를 group 컬럼과 함께 한 화면에 보여 준다.
+ Citus cluster: demo ----------+----------------+---------+----+
| Group | Member | Host | Role | State | TL |
| 0 | coord1 | 172.27.0.10 | Replica | running | 1 |
| 0 | coord3 | 172.27.0.4 | Leader | running | 1 |
| 1 | work1-2 | 172.27.0.2 | Leader | running | 1 |patronictl 명령 대부분이 --group 옵션을 받아 특정 그룹만 대상으로 삼는다.
# worker 그룹 1 만 switchover
patronictl switchover demo --group 1
# coordinator 그룹의 설정만 편집
patronictl edit-config demo --group 0정리
citus.group(coordinator 0, worker 1 이상)과citus.database두 키로 Citus 통합이 켜진다. scope 동일, superuser 동일, Citus 10.0+(권장 11.2+)가 전제다.- Patroni는
shared_preload_libraries,max_prepared_transactions, quorum synchronous mode,pg_dist_authinfo,pg_dist_node를 자동 관리한다. - worker switchover는
citus_update_node()통지로 coordinator 트래픽을 일시정지했다가 새 primary로 재개하는 흐름으로 진행된다.