본문으로 건너뛰기

2.2 HA 루프와 leader lock

Patroni 데몬의 시간은 loop_wait 초 단위로 흐릅니다. 데몬은 loop_wait 초마다 HA 체크 사이클을 한 바퀴 돌면서 자신의 상태를 DCS에 기록하고, 역할에 따라 leader lock을 갱신하거나 감시합니다. 장애 감지도, failover 개시도 이 루프의 반복 속에서 일어납니다.

사이클마다 일어나는 일​

모든 노드는 매 사이클 DCS의 member key를 갱신해 자신의 현재 정보를 기록합니다. 이 갱신은 클러스터 자동 관리를 멈추는 pause 상태에서도 계속되는, 루프의 가장 기본적인 동작입니다. 여기에 더해 각 노드는 상황을 점검하고 필요한 조치를 실행합니다. PostgreSQL이 정지해 있으면 다시 기동하고, leader lock 없이 primary로 돌고 있는 인스턴스를 발견하면 demote하며, primary가 없으면 replica 승격을 시도합니다.

leader의 사이클에는 일이 하나 더 있습니다. leader key의 lease 갱신입니다. leader key에는 ttl 초의 TTL이 걸려 있어서, leader가 제때 lease를 갱신하지 못하면 key는 결국 DCS에서 만료됩니다. replica는 반대편에서 이 leader key의 유효성을 감시합니다.

시간을 지배하는 세 파라미터​

루프의 리듬은 세 파라미터가 결정합니다. 셋 모두 dynamic configuration 전용이라 DCS의 config key로 클러스터 전체에 한 번에 적용됩니다.

파라미터기본값최소값의미
ttl3020leader lock 취득에 쓰는 TTL(초)
loop_wait101루프가 잠드는 시간(초)
retry_timeout103DCS와 PostgreSQL 연산 재시도 타임아웃(초)

ttl은 공식 문서가 "자동 failover 절차가 시작되기까지의 시간 길이로 생각하라"고 설명하는 값입니다. retry_timeout은 순단 필터 역할을 합니다. 이 값보다 짧은 DCS 장애나 네트워크 문제는 leader 강등을 유발하지 않습니다.

세 값은 독립적이지 않습니다. 공식 문서는 다음 제약식을 유지하라고 요구합니다.

loop_wait + 2 * retry_timeout <= ttl

사이클 대기 시간에 재시도 두 번의 여유를 더해도 TTL 안에 들어와야 한다는 뜻입니다. 이 식이 깨지면 정상 운영 중에도 lease 갱신이 TTL을 넘겨 의도치 않은 failover가 일어날 여지가 생깁니다. 변경은 patronictl edit-config로 합니다.

patronictl -c /etc/patroni.yml edit-config -s loop_wait=5
경고

ttl을 줄이면 leader 장애를 더 빨리 감지하지만, 그만큼 일시적인 DCS 지연이나 네트워크 순단에도 failover가 시작될 여지가 커집니다. 세 값을 조정할 때는 반드시 제약식을 다시 계산하고, retry_timeout이 감당할 순단의 길이를 함께 생각합니다.

leader key 만료와 leader race​

leader가 lease 갱신에 실패해 leader key가 만료되면, Patroni가 leader race라고 부르는 절차가 시작됩니다. 모든 노드가 자신이 leader 역할을 넘겨받기에 가장 적합한 후보인지 검사를 시작하고, 이 과정에서 다른 노드의 GET /patroni REST 엔드포인트를 호출해 서로의 상태를 비교합니다. follower가 election에 참여하려면 복제 지연이 maximum_lag_on_failover(바이트) 이내여야 합니다.

자신이 최적 후보라고 판단한 멤버들은 leader lock 취득을 시도하고, 가장 먼저 lock을 잡은 멤버가 스스로 promote해 read/write 노드가 됩니다. 후보 비교 기준과 promote 이후의 흐름, synchronous mode가 개입하는 경우는 Part VI. Failover와 Switchover에서 상세히 다룹니다.

정리​

  • 모든 노드는 loop_wait 초마다 사이클을 돌며 member key를 갱신하고, 상황에 따라 기동, demote, 승격 시도를 실행합니다.
  • leader는 ttl 초짜리 lease를 계속 연장합니다. 연장이 끊기면 key가 만료되고 leader race가 열립니다.
  • 세 파라미터는 loop_wait + 2 * retry_timeout <= ttl 제약식 안에서 함께 움직입니다.