Active-Active 데이터베이스의 Strings와 Bitfields

Active-Active 데이터베이스의 Strings와 Bitfields (Strings and bitfields in Active-Active databases)

Active-Active 데이터베이스에서 문자열(Strings)과 비트필드(Bitfields)를 어떻게 다루는지 설명하는 페이지예요. 문자열이야 단순하다고 생각할 수 있지만, 여러 지역이 같은 키에 동시에 쓰면 "어느 값이 진짜지?" 하는 문제가 생겨요. Active-Active에서는 이 충돌을 어떻게 해결하는지 정리해 드릴게요.

출처: Redis 공식 문서 — Strings and bitfields in Active-Active databases

기본 지원

Active-Active 데이터베이스는 문자열(Strings)과 비트필드(Bitfields)를 모두 지원해요. 두 데이터 구조의 변경 사항은 Active-Active 멤버 데이터베이스 사이에 복제돼요.

참고: Active-Active bitfield 지원은 RS 버전 6.0.20부터 추가됐어요.

복제 시맨틱 (Replication semantics)

문자열 카운터(아래에서 설명)를 제외하면, 문자열과 비트필드는 "last write wins"(마지막 쓰기 승리) 방식으로 복제돼요. 그 이유는 문자열과 비트필드가 사실상 바이너리 객체이기 때문이에요. 리스트, 셋, 해시와 달리, 문자열이나 비트필드에 대한 특정 연산의 충돌 해결 시맨틱이 정의되어 있지 않거든요.

"last write wins"는 어떻게 동작할까?

모든 문자열·비트필드 연산의 메타데이터에 wall-clock 타임스탬프(OS 시간) 가 저장돼요. 복제 syncer가 연산 순서를 판단할 수 없으면, 가장 최신 타임스탬프를 가진 값이 이겨요. Active-Active 데이터베이스에서 OS 시간으로 충돌을 해결하는 유일한 경우가 바로 이거예요.

아래는 같은 키에 대한 더 늦은 시각(t2)의 업데이트가 t1의 업데이트를 이기는 예시예요.

시점 Region 1 Region 2
t1 SET text "a"
t2 SET text "b"
t3 — Sync — — Sync —
t4 SET text "c"
t5 — Sync — — Sync —
t6 SET text "d"

문자열 카운터 지원

문자열을 카운터로 쓸 때(예: INCR 또는 INCRBY 명령)에는 충돌이 의미론적으로(semantically) 해결돼요.

충돌 쓰기가 발생하면, 카운터는 각 동기화 시점에 모든 멤버 Active-Active 데이터베이스의 카운터 연산을 누적해요.

아래는 두 멤버 사이에서 카운터 값이 어떻게 동기화되는지 보여주는 예시예요. 동기화 때마다 카운터 값은 각 사이트의 증가(increment)/감소(decrement)를 누적해서, 동시 쓰기 상황에서도 정확한 카운터를 유지해요.

시점 Region 1 Region 2
t1 INCRBY counter 7
t2 INCRBY counter 3
t3 GET counter => 7 GET counter => 3
t4 — Sync — — Sync —
t5 GET counter => 10 GET counter => 10
t6 DECRBY counter 3
t7 INCRBY counter 6
t8 — Sync — — Sync —
t9 GET counter => 13 GET counter => 13

참고: Active-Active 데이터베이스는 59비트 카운터를 지원해요. 이 제한은 동시 연산에서 카운터가 오버플로(overflow)되는 것을 막기 위한 것이에요.

더 알아보기 (Learn more)