일관성은 저장소 전체에 붙이는 한 단어의 등급이 아니라 연산 이력과 기능별 사용자 약속입니다. 같은 값을 읽었는지보다 호출과 응답 사이에 어떤 순서를 허용하는지, 분할 중 확정·보류·거절을 무엇으로 셀지, 복구 뒤 충돌을 어떻게 설명할지를 먼저 명세해야 합니다.
마지막 좌석 표시와 판매 확정의 요구 분리
화면의 잔여 좌석 수가 잠시 늦는 것은 허용할 수 있어도 마지막 한 좌석에 두 구매를 확정하면 안 됩니다. 표시 조회는 캐시를 쓰되 확정은 권위 상태에서 조건 검사·차감을 한 원자 연산으로 처리할 수 있습니다. 개별 GET·SET이 선형화 가능해도 그 사이 앱 계산은 하나의 원자 거래가 아닙니다.
선형화 가능성은 각 연산이 호출과 응답 사이 한 시점에 실행된 것처럼 설명되며 비중첩 연산의 실시간 선후를 존중하는 성질입니다. 직렬화 가능한 transaction은 어떤 직렬 순서와 같은 결과를 요구하고, 엄격한 직렬화는 실제 완료·후속 호출 순서까지 존중합니다. 용어의 범위·제품 API를 확인합니다.
상태를 available=1로 시작해 두 요청 A와 B가 모두 같은 값을 읽고 각각 1을 차감하는 순서를 따라가면, 읽기와 쓰기를 따로 수행한 설계는 최종값을 0으로 만들면서도 두 성공을 기록할 수 있습니다. 조건부 원자 갱신이나 권위 서비스의 단일 연산은 “현재 값 확인”과 “권리 확정”을 같은 선형화 지점으로 묶어 이 반례를 막습니다.
겹친 읽기와 완료 뒤 읽기의 이력 차이
초기 x=0에서 write(1)이 시간 1에 시작해 3에 성공했고 read가 4에 시작해 5에 0을 반환하면 순서에 맞는 설명이 없습니다. 반면 read가 2에 시작해 write와 겹쳤다면 write 앞에 놓아 0을 설명할 수 있습니다.
| 이력 | 가능한 순차 설명 | 판정 예 |
|---|---|---|
| write 성공 뒤 read=0 | write를 read 뒤로 놓을 수 없음 | 위반 |
| write와 read가 겹치고 read=0 | read→write 가능 | 허용될 수 있음 |
| write timeout 뒤 read=1 | write가 적용됐을 수 있음 | timeout을 미실행으로 제외하면 안 됨 |
검사에는 연산 ID·client ID·호출/응답·입력/출력·초기 상태·성공/확실 실패/불확정을 기록합니다. timeout은 가능한 적용·미적용 결과를 모델에 포함합니다. 서로 다른 서버의 부정확한 wall clock만으로 비중첩 순서를 만들어서는 안 되고 client 관측·인과 제약·측정 오차를 고려합니다.
그림을 글로 읽기
- write(1) 성공 응답
- 그 뒤 read 호출
- read=0이면 초기값 역행
- write(1) 성공 응답 → 그 뒤 read 호출: 실시간 선후
- 그 뒤 read 호출 → read=0이면 초기값 역행: 순차 명세와 비교
유한 이력의 checker 통과는 모든 실행의 증명이 아니지만 실패 이력은 재현 가능한 반례가 됩니다. 분리 가능한 키만 독립 검사하고, 여러 키 불변식이면 나누어 검사해 문제를 숨기지 않습니다.
CAP의 분할 중 선택과 가용성 계약
통신이 갈라진 동안 강한 최신 순서를 유지하면서 모든 비고장 노드가 요청 명세에 맞는 완료를 계속 제공하는 두 목표를 동시에 달성할 수 없는 상황이 있습니다. 안전한 좌석 확정을 위해 권위를 확인 못 하는 쪽은 대기·거절하고, 병합 가능한 통계는 잠정 지역 수락을 택할 수 있습니다.
오류를 즉시 반환했다고 CAP의 가용성을 충족하는 것은 아닙니다. 잠정 접수도 원래 요청이 최종 구매 확정을 요구했다면 같은 성공이 아닙니다. 기능의 명세를 바꿨다는 사실과 사용자에게 보류 상태를 명확히 알려야 합니다. 최종 일관성은 변경이 멈추고 전달·복구가 진행되면 수렴한다는 조건부 약속이지 보편적인 몇 초 상한이 아닙니다.
기능별 SLO와 안전한 거절의 사용자 영향
좌석 확정 거절은 중복 판매를 막는 올바른 정책일 수 있지만 유효한 사용자가 구매를 완료하지 못한 가용성 영향은 지표에서 사라지지 않습니다. 성공·정상 비즈니스 거절·권위 불확실 보류·장애를 구분하고 기능별 분모·기한을 명시합니다.
좋아요는 지역 수락 지연·수렴 지연·정정량·중복을 따로 봅니다. 분할 뒤 LWW로 한 값을 고르면 화면이 수렴해도 사용자의 한 변경을 잃었을 수 있습니다. 이미 확정 성공한 권리·결제를 조용히 삭제하지 말고 조정 원장·보상·차액·수동 대사·사용자 안내를 남깁니다. 지역별 사전 재고 권리를 나누는 방식은 일부 진행을 가능하게 하지만 전역 공유 자원을 사전 분배한 다른 계약입니다.
R+W>N의 집합 교집합과 선형화 한계
N=3, R=2, W=2라면 고정된 replica 집합에서 완료한 쓰기 2곳과 읽기 2곳이 적어도 한 곳에서 겹칩니다. 그러나 그 교집합에서 어떤 버전을 선택할지, 동시 쓰기·부분 실패·stale 응답·구성 변경을 어떻게 처리할지는 별도 규칙입니다. 예를 들어 쓰기가 일부 replica에만 남은 채 응답이 끊기면 첫 읽기는 그 값을 보고 다음 읽기는 못 볼 수 있으므로, read-back과 repair가 어느 시점에 무엇을 다시 기록하는지까지 정해야 합니다.
sloppy quorum처럼 장애 시 실제 참여 집합이 바뀌는 방식에서는, 쓰기 집합과 읽기 집합이 고정되어 겹친다는 출발점이 더는 성립하지 않습니다. 여러 replica가 서로 다른 값을 갖고 가장 큰 wall timestamp만 고르면, clock skew 때문에 실제 순서와 무관하게 한 값이 더 최신처럼 선택되어 다른 변경을 덮을 수 있습니다.
read repair는 이번 읽기에서 발견한 stale replica만 고치므로 읽히지 않은 키까지 정리하지 못하고, anti-entropy·복구 경로와 repair 부하·삭제·충돌 정책을 따로 운영해야 합니다.
분할 복구 뒤 값과 사용자 약속 대조
격리 테스트에서 leader 고립·동시 구매·읽기 역행·부분 쓰기·지연 replica·다중 지역 복구를 실행하고 호출 이력을 명세와 비교합니다. 이벤트 ID·원본 version·인과 관계·외부 성공을 보존해 중복·손실을 대사합니다.
현재 작업에서는 실제 분산 저장소나 선형화 checker를 실행하지 않았습니다. 본문은 관찰 계약과 반례의 설명이며 CAP 라벨 하나로 제품 전체 보장을 판정하지 않습니다.