시스템 아키텍트시스템 아키텍트

전 세계에 분산된 협업 편집 플랫폼에서 오프라인 우선 기능을 지원하고 중앙 집중식 조정 없이 강력한 최종 일관성을 보장하면서 1000만 명의 동시 사용자가 충돌 없는 복제 데이터 유형(CRDT) 구현을 어떻게 구조화합니까?

Hintsage AI 어시스턴트로 면접 통과

질문에 대한 답변.

이 규모에서 CRDT 기반 협업 시스템을 설계하려면, 운영을 직렬화하기 위해 중앙 권한이 필요한 전통적인 운영 변환(OT) 모델을 포기해야 합니다. 이러한 기존 접근 방식은 충돌 해결을 위해 조정 서버에 지속적인 연결을 요구하므로 진정한 오프라인 우선 기능을 근본적으로 방해합니다. 대신, 중앙 집중식 조정 또는 합의 프로토콜 없이 수렴을 보장하기 위해 교환 가능성, 결합성 및 항등성의 수학적 속성을 활용하는 상태 기반 CRDT(특히 RGA - 복제 가능 성장 배열)를 구현하십시오.

클라이언트가 전체 상태 스냅샷이 아닌 로컬 상태 간의 차이점만 교환하는 델타 상태 반엔트로피 프로토콜을 배포하십시오. 이 접근 방식은 나쁜 상태 기반 복제와 비교하여 동기화 중 대역폭 소비를 수십 배로 줄입니다. 물리적 타임스탬프와 논리적 카운터를 결합한 하이브리드 논리 시계(HLC)를 활용하여 인과관계를 설정하고 NTP에 대한 엄격한 의존성 없이 지역 간 시계 왜곡을 처리해야 합니다. 마지막으로 제거 마커로 인한 메모리 증가를 방지하면서 지연되거나 분할된 복제본에 대한 인과 추적을 유지하기 위해 세대 기반 가지 치기 방식을 사용한 톰스톤 가비지 수집을 구현하십시오.

실제 상황

우리 팀은 5만 개의 기업 팀을 지원하는 피그마와 유사한 디자인 도구를 위한 실시간 협업 엔진을 재구성하는 작업을 맡았습니다. 기존 시스템은 중앙 Node.js 서버를 통한 Redis pub/sub 및 WebSocket 연결을 사용하여 1만 명 이상의 사용자가 비행기에서 오프라인으로 편집하고 나서 동시에 다시 연결하려고 할 때 붕괴되었습니다. 이 급증으로 인해 되돌릴 수 없는 상태의 분기가 발생하고 문서가 영구적으로 손상되었으며, 48시간의 다운타임과 상당한 고객 이탈이 발생했습니다.

첫 번째로 검토한 것은 리스 잠금을 이용한 중앙 집중식 OT로, 오프라인에서 편집하기 전에 사용자가 문서 섹션에 대한 독점 잠금을 획득해야 합니다. 이 솔루션은 전통적인 데이터베이스와 유사한 강력한 일관성과 친숙한 ACID 의미를 제공한다고 약속했지만, 잠금 갱신을 위해 지속적인 연결이 필요하여 오프라인 우선 요구 사항을 완전히 위반하고 전체 제품을 네트워크 파편화 중에 사용 불가능하게 만드는 재앙적인 단일 실패 지점을 생성했습니다.

두 번째 후보 솔루션은 **벡터 시계를 사용한 최종 작성 승(Last-Write-Wins, LWW)**을 제안하여 AWS DynamoDB 타임스탬프를 이용해 충돌을 결정적으로 해결했습니다. 이 접근 방식은 진정한 오프라인 편집을 지원하고 기존 클라우드 인프라로 쉽게 구현할 수 있었지만, 동시 편집 중 재앙적인 데이터 손실을 초래했습니다. 두 디자이너가 오프라인에서 같은 구성 요소를 동시에 이동할 때, 마지막 동기화의 타임스탬프만 살아남아, 경고 없이 한 사용자의 작업을 전적으로 파기하여 협업의 본질을 침해했습니다.

결국 우리는 Yjs 라이브러리를 사용하는 상태 기반 CRDT를 선택하고 QUIC 프로토콜을 통해 전송되는 커스텀 델타 상태 동기화를 구현했습니다. 이 아키텍처 선택은 편집 중 중앙 집중식 조정의 필요성을 없애주었고, 네트워크 파편화 기간과 관계없이 수렴의 수학적 보장을 제공하며, 인터넷 연결 없이 동일한 LAN의 사용자 간 P2P 동기화도 지원합니다. 우리는 전체 상태 전송과 비교하여 동기화 페이로드를 94% 줄이기 위해 머클 트리 델타 인코딩을 구현하여 문서 이력의 암호학적 무결성을 유지했습니다.

생산 트래픽이 지속된 지 6개월 후, 시스템은 전체 지역에 영향을 미치는 72시간 Cloudflare 중단을 성공적으로 처리했으며, 사용자는 오프라인으로 계속 편집하고 연결 재설정 시 데이터 손실 없이 원활하게 병합되었습니다. 문서 로드 시간은 충돌 해결을 위한 서버 왕복 시간 제거로 인해 4.2초에서 180밀리초로 개선되었습니다. 인프라 비용은 조정 오버헤드 제거 및 강력한 중앙 집중식 컴퓨팅 인스턴스 대신 엣지 캐싱을 사용할 수 있게 됨으로써 60% 감소했습니다.

후보자들이 자주 놓치는 점

CRDT는 사용자가 콘텐츠를 삭제할 때 톰스톤의 무한 성장을 어떻게 처리하며 안전한 제거를 트리거하는 것은 무엇입니까?

대부분의 후보자는 삭제가 메모리에서 즉시 제거될 수 있다고 가정하지만, CRDT는 인과 관계를 추적하고 병합 시 삭제된 데이터가 부활하는 것을 방지하기 위해 톰스톤이 필요합니다. 솔루션은 벡터 시계 비교를 사용하여 인과 안정성 감지를 구현합니다. 노드가 특정 타임스탬프까지 모든 다른 복제본이 삭제를 확인했다고 관찰하면, 해당 톰스톤은 안정된 것으로 간주되어 제거될 수 있습니다. 여러분은 설정 가능한 유효 기간이 지난 후 톰스톤이 제거될 수 있도록 표시된 세대 기반 가비지 수집을 배포해야 하며, 인과 컷이 지연 복제본이 수렴을 위해 톰스톤이 필요하지 않음을 증명할 때만 물리적으로 삭제됩니다. 이 메커니즘이 없으면, 6개월 전의 단 하나의 오프라인 장치가 재연결 시 오래된 삭제 데이터를 부활시킬 수 있어 영구 삭제와 개인 정보 보호 준수에 대한 사용자 기대를 위반할 수 있습니다.

네트워크 요구 사항에 대한 상태 기반 CRDT와 작업 기반 CRDT 간의 근본적인 차이점은 무엇이며, 대역폭 제약이 있는 모바일 환경에서 하나를 선택하는 이유는 무엇입니까?

Op 기반 CRDTApache Kafka 또는 RabbitMQ와 같은 전송 계층에서 정확하게 한 번 전달 및 인과 브로드캐스트 보장을 요구하므로 메시지가 손실되거나 경고 없이 중복될 수 있는 불안정한 모바일 네트워크에 적합하지 않습니다. 상태 기반 CRDT는 메시지 중복 및 임의 지연을 허용하지만 전통적으로 전체 문서 상태를 전송해야 하므로 셀룰러 네트워크에서 대형 디자인 파일에 대해 비용이 과도하게 높습니다. 진보된 솔루션은 마지막 성공적인 동기화 이후에만 변화를 전송하는 델타 상태 CRDT를 사용하여 상태 기반 접근 방식의 네트워크 강인성과 op 기반 접근 방식의 효율성을 결합합니다. 모바일 맥락에서는 Exponential Backoff Delta SyncBloom Filters를 구현하여 이미 본 업데이트를 다시 보내지 않도록 하여 전체 상태 동기화에 비해 모바일 데이터 사용량을 99% 줄이면서 오프라인 우선 기능을 유지합니다.

두 사용자가 동시에 같은 커서 위치에 텍스트를 삽입할 때, 어떻게 '교차 삽입 이상'을 방지하며, 그들의 편집이 무작위로 섞이지 않고 연속적인 블록으로 표시되도록 보장합니까?

표준 LWW나 간단한 카운터 기반 CRDT는 ''helo'' 문제를 일으켜 교차 위치에 "hi"와 "bye"를 동시에 삽입하면 "hbyeio"라는 이해할 수 없는 문자열이 됩니다. 해결책은 복제 가능 성장 배열(RGA) 또는 Woot 알고리즘을 사용하여 노드 ID와 논리적 타임스탬프를 기반으로 각 문자의 전역 고유 식별자(GUID)를 할당하고, 총 순서를 설정하는 결정론적 동점 규칙을 적용해야 합니다. 삽입할 때는 번호 인덱스가 아닌 특정 이전 ID에 새 요소를 연결하여 서로 독립적인 분기가 결정론적으로 병합되도록 하는 연결 리스트 구조를 생성합니다. 또한 GUID 오버헤드가 문서 크기를 지배하지 않도록 런 길이 인코딩 최적화를 구현하여 텍스트 문서의 경우 일반적으로 20% 미만의 메타데이터 오버헤드를 달성하면서 동시에 편집의 의도를 유지하는 직관적인 병합 의미를 보존해야 합니다.