Workspace IndexAlgorithms › Day 55

Multi-Paxos and Flexible Paxos — The Freedom in Quorum Design TODO

Algorithms · Day 55 / 100 · D. Distributed Systems & Consensus (Day 52-68)

Concept

Basic Paxos agrees on a single value through two phases, prepare and accept, each requiring a majority quorum's response. Multi-Paxos, when agreeing on a sequence of instances, has a stable leader secure the prepare phase once up front rather than repeating it per instance, so in the steady state a value is decided in a single accept round. It was traditionally believed that all quorums had to pairwise intersect, but Flexible Paxos showed the condition actually required for safety is only that the phase-1 quorum and the phase-2 quorum intersect — that is, only |Q1| + |Q2| > N is needed, with no requirement that Q1's intersect each other or Q2's intersect each other. This freedom makes it possible to shrink the write quorum to lower steady-state latency while enlarging the leader-election quorum instead, turning quorum size into a dial that trades off steady-state performance against failure-recovery availability.

The latency and fault tolerance of a consensus system are mostly decided by quorum-size choices, and holding onto the "always a majority" intuition alone means missing that room to tune. It's also where the "why is the normal path 1 RTT" answer for leader-based protocols comes from.

Code & Formula

# Multi-Paxos·Flexible Paxos — 정족수 설계의 자유도.
# 안전성 조건은 |Q1| + |Q2| > N 뿐이며, Q1(prepare)과 Q2(accept)가 같은 크기일 필요는 없다.

from itertools import combinations

N = 5  # 전체 노드 수

def quorums_intersect_safely(q1_size, q2_size, n=N):
    """모든 가능한 Q1, Q2 조합이 항상 겹치는지 직접 확인 (|Q1|+|Q2|>N과 동치)"""
    nodes = set(range(n))
    for q1 in combinations(nodes, q1_size):
        for q2 in combinations(nodes, q2_size):
            if not (set(q1) & set(q2)):
                return False
    return True

print(f"N={N} 노드 클러스터에서 (Q1=prepare 정족수, Q2=accept 정족수) 조합별 안전성:\n")
for q1_size, q2_size in [(3, 3), (4, 2), (2, 4), (2, 2), (3, 2)]:
    condition_holds = q1_size + q2_size > N
    actually_safe = quorums_intersect_safely(q1_size, q2_size)
    assert condition_holds == actually_safe, "조건식과 실제 검증이 불일치"
    label = "SAFE" if actually_safe else "UNSAFE (충돌 가능)"
    print(f"  Q1={q1_size}, Q2={q2_size}: |Q1|+|Q2|={q1_size+q2_size} > N={N} ? "
          f"{condition_holds} -> {label}")

print("\n(4,2): accept 정족수를 2로 줄이면 정상 경로 지연은 낮아지지만")
print("        prepare(리더 선출) 정족수를 4로 키워야 안전성이 유지된다 — 트레이드오프의 손잡이.")

Exercise

With N=5 nodes, set (Q1, Q2) to (3,3), (4,2), and (2,4), and tabulate the steady-state latency, how many simultaneous failures each tolerates, and whether leader replacement is possible for each, to find where the safety condition breaks.

Practical Connection

Blockchain consensus and sequencer HA setups also have their confirmation latency and availability jointly decided by "how many node responses do we wait for," so this quorum-design intuition transfers directly.

If you study this on a given day, add a note link and a ✅ to this line in the source curriculum (docs/knowledge/dev-100-curriculum.md) and this spot will lead straight to the note body. You can also write directly on this page — but regenerating overwrites it, so it's safer to keep anything you want to save as markdown under docs/algorithms/.


한국어

Multi-Paxos·Flexible Paxos TODO

Algorithms · Day 55 / 100 · D. 분산시스템·합의 (Day 52–68)

정족수 설계의 자유도

개념

기본 Paxos는 하나의 값을 합의하는 데 prepare와 accept 두 단계를 거치며, 각 단계마다 과반 정족수의 응답이 필요하다. Multi-Paxos는 연속된 여러 인스턴스를 합의할 때 안정적인 리더가 prepare 단계를 인스턴스마다 반복하지 않고 한 번에 미리 확보해 두어, 정상 상태에서는 accept 한 라운드만으로 값을 확정한다. 전통적으로는 모든 정족수가 서로 교차해야 한다고 여겨졌지만, Flexible Paxos는 안전성에 실제로 필요한 조건이 1단계 정족수와 2단계 정족수가 교차하는 것뿐임을 보였다. 즉 |Q1| + |Q2| > N만 만족하면 되고, Q1끼리 또는 Q2끼리는 교차하지 않아도 된다. 이 자유도 덕분에 쓰기 정족수를 줄여 정상 경로 지연을 낮추고 대신 리더 선출 정족수를 키우는 식의 설계가 가능해지며, 결국 정상 상태 성능과 장애 복구 가용성 사이를 조율하는 손잡이가 된다.

합의 시스템의 지연과 장애 내성은 대부분 정족수 크기 선택에서 결정되는데, '무조건 과반'이라는 통념만 갖고 있으면 그 조정 여지를 놓친다. 리더 기반 프로토콜의 정상 경로가 왜 1 RTT인지도 여기서 나온다.

코드 · 수식

# Multi-Paxos·Flexible Paxos — 정족수 설계의 자유도.
# 안전성 조건은 |Q1| + |Q2| > N 뿐이며, Q1(prepare)과 Q2(accept)가 같은 크기일 필요는 없다.

from itertools import combinations

N = 5  # 전체 노드 수

def quorums_intersect_safely(q1_size, q2_size, n=N):
    """모든 가능한 Q1, Q2 조합이 항상 겹치는지 직접 확인 (|Q1|+|Q2|>N과 동치)"""
    nodes = set(range(n))
    for q1 in combinations(nodes, q1_size):
        for q2 in combinations(nodes, q2_size):
            if not (set(q1) & set(q2)):
                return False
    return True

print(f"N={N} 노드 클러스터에서 (Q1=prepare 정족수, Q2=accept 정족수) 조합별 안전성:\n")
for q1_size, q2_size in [(3, 3), (4, 2), (2, 4), (2, 2), (3, 2)]:
    condition_holds = q1_size + q2_size > N
    actually_safe = quorums_intersect_safely(q1_size, q2_size)
    assert condition_holds == actually_safe, "조건식과 실제 검증이 불일치"
    label = "SAFE" if actually_safe else "UNSAFE (충돌 가능)"
    print(f"  Q1={q1_size}, Q2={q2_size}: |Q1|+|Q2|={q1_size+q2_size} > N={N} ? "
          f"{condition_holds} -> {label}")

print("\n(4,2): accept 정족수를 2로 줄이면 정상 경로 지연은 낮아지지만")
print("        prepare(리더 선출) 정족수를 4로 키워야 안전성이 유지된다 — 트레이드오프의 손잡이.")

연습

노드 수 N=5에서 (Q1, Q2)를 (3,3), (4,2), (2,4)로 두고 각각 정상 경로 지연과 동시 장애 몇 대까지 버티는지, 리더 교체가 가능한지를 표로 정리해 안전성 조건이 깨지는 조합을 찾아보라.

실무 · Verex 연결

블록체인 합의나 시퀀서 HA 구성에서도 '몇 노드 응답을 기다릴 것인가'가 확정 지연과 가용성을 동시에 결정하므로, 정족수 설계 감각이 그대로 이전된다.

공부한 날 원본 커리큘럼(docs/knowledge/dev-100-curriculum.md)의 이 줄에 노트 링크와 ✅ 를 붙이면, 이 자리는 노트 본문으로 바로 이어집니다. 노트 없이 이 페이지에 바로 적어도 됩니다 — 다만 다시 생성하면 덮어쓰이므로, 남길 글은 docs/algorithms/ 의 마크다운으로 쓰는 편이 안전합니다.

← 54. Raft 심화56. 비잔틴 정족수(3f+1)와 PBFT →