CRDT의 우아한 수학적 뿌리와 실제 사용에서 드러나는 함정들을 개괄하고, 장단점과 프로그래밍 관점의 논점을 개인적 견해와 함께 소개합니다.
2025년 5월 21일 • 4분 읽기

앞으로 며칠 동안 CRDT: Convergent Conflict-free Replicated Data Types(충돌 없는 복제 데이터 타입)에 관한 여러 관찰을 연달아 올리려 합니다. 이는 _조정이 필요 없는 분산 프로그래밍_에 도움이 되도록 고안된 자료구조들로, 제가 무척 관심을 갖고 있는 주제입니다. 개발자(또는 언어/컴파일러)가 전역 클라우드를 순차 컴퓨터만큼 느리게 만드는 조정 메커니즘 없이, 중요한 방식으로 _안전_하고 정확한 분산 프로그램을 어떻게 제공할 수 있을까요?
간단히 말해, 제 생각에 CRDT는 우아한 핵심 위에 세워졌지만, 많은 개발자—그리고 연구자들—를 오도하는 누수성(leaky) 추상화를 제공합니다. CRDT의 아이디어와 문제를 이해하는 것은 이 영역으로 들어가는 훌륭한 길입니다. 이 글에서는 개요를 제공하고, 연재는 더 깊이 나아갈 것입니다.
먼저, 제가 매우 매력적이라고 느끼는 우아한 부분부터:
깊은 뿌리: CRDT는 _반격자(semilattice)_에 기반합니다. 반격자는 join 연산자를 가지는 단순하고 추상적인 수학 구조로, 이 연산자는 _결합법칙, 교환법칙, 멱등성_을 만족합니다. 이를 복제 데이터 타입에 이용하자는 생각은 적어도 Baquero와 Moura의 1997년 작업까지 거슬러 올라갑니다. 이분들은 더 많은 인용을 받아 마땅합니다! (이를 알려준 Conor Power에게 HT. 그는 CRDT로 유명한 Marc Shapiro에게 배웠다고 합니다.)
대수를 더!: 현대 대수를 분산 시스템과 데이터베이스 시스템의 정확성 보장을 위한 빌딩 블록으로 사용하는 것은 이 분야에 훌륭한 방향이며, 최근 들어 이런 작업이 점점 더 많아지고 있습니다. (예를 들어 몇 해 전의 시몬스 연구소 모임을 보세요.) 이 반격자/CRDT 계열의 작업은 이른 시기에 등장했으며, 우아하고 이해하기 쉽습니다. 멋진 stuff.
안타깝게도 일반적인 CRDT 논의에서는 몇 가지 핵심 문제가 나타납니다:
정확성에서의 이탈. 사람들이 반격자라는 토대에서 멀어질수록, 올바른 수학적 기준에서 길을 잃을 수 있습니다. 이는 전적으로 피할 수 있고, 대부분의 전문가들은 여기에서 버그를 피하는 방법을 알지만, 논의가 불필요하게 미묘해지곤 합니다… 사람들을 혼란스럽게 만드는 방식으로요.
사용 시 안전하지 않음. 반격자 대수에는 단 하나의 연산자, 즉 join만 있습니다. 특히 읽기 또는 _검사_에 대응하는 연산자는 없습니다. 사실 문헌에 기술된 CRDT는 읽는 쪽에게 절대 어떠한 보장도 제공하지 않기 때문에, “제대로 된” CRDT 구현은 읽기를 허용하지 말아야 합니다! 즉, 올바른 CRDT란 완전히 쓸모없는 이론적 객체라는 뜻입니다. 그럼에도 사람들은 CRDT를 사용하면서, 필연적으로 안전하지 않거나 비결정적인 방식으로 읽거나 검사합니다. 더 나쁜 것은, 많은 개발자들이 CRDT로부터 유용한 정확성 보장을 _받고 있다고 생각한다는 점_인데, 실제로는 그렇지 않습니다! CRDT로 안전하게 할 수 있는 유일한 일은 그것을 들여다보지 않는 것입니다.
프로그래밍 가능성의 문제. _읽을 수 없는 데이터 타입_인 CRDT는 유용한 프로그램으로 안전하게 조합될 수 없습니다. 그렇다면 실제로 우리는 그것을 어떻게 사용할 수 있을까요? 이상적으로는 CRDT 빌딩 블록을 올바르게 합성할 수 있는 _언어_가 필요합니다. 이는 LVars, Bloom^L, Lasp, Gallifrey 같은 DSL에서 연구되어 왔습니다. 이런 아이디어를 개발자들이 익숙하게 느끼는 틀로 전달하려면 아직 할 일이 남아 있으며, 이는 우리가 Rust용으로 만드는 Hydro 라이브러리의 목표 중 하나이기도 합니다.
그래서… 실용적인 관점에서 저는 CRDT의 열혈 팬은 아닙니다. 하지만 핵심 아이디어는 정말 아름답고, 함정들은 개발자와 연구자 모두가 이해하는 데 매우 흥미롭고 교육적이라고 생각합니다. 수년간 CRDT에 관해 작업해 온 분들께 큰 존경을 표합니다. 그들이 만들어낸 것과 제기한 도전 모두에 대해요.
저는 수년간 학생들과 함께 CRDT에 대한 제 불편함을 풀어가며 많은 것을 배웠고, 다음 몇 편의 글에서 그 과정에서 배운 것들을 드러내고 요약하려 합니다. 이로 인해 여러분이 코드에서 CRDT를 더 쓰고 싶어질지, 덜 쓰고 싶어질지는 각자 판단하시겠지만, 결정과 그에 따른 휴리스틱이 더 잘 정보에 기반하길 바랍니다.