충돌 없는 복제 데이터 유형
Conflict-free replicated data type분산 컴퓨팅에서 충돌 없는 복제 데이터 유형(CRDT)은 네트워크상의 여러 컴퓨터에 걸쳐 복제할 수 있는 데이터 구조로, 복제본을 독립적으로 동시에 업데이트할 수 있고, 복제본을 조정할 필요 없이 항상 수학적으로 해결할 수 있다.이업[1][2][3][4][5][6][7][8]
CRDT 개념은 2011년 마르크 샤피로, 누노 프레기사, 카를로스 바케로, 마렉 자위르스키에 의해 공식적으로 정의되었다.[9]개발은 처음에는 협업적인 텍스트 편집과 모바일 컴퓨팅에 의해 동기 부여되었다.CRDT는 온라인 채팅 시스템, 온라인 도박, 그리고 SoundCloud 오디오 배포 플랫폼에서도 사용되었다.NoSQL 분산 데이터베이스 Redis, Riak 및 Cosmos DB에는 CRDT 데이터 유형이 있다.
배경
복제본을 호스팅하는 컴퓨터 간의 조정 없이 동일한 데이터의 여러 복제본에 대한 동시 업데이트는 복제본 간의 불일치를 야기할 수 있으며, 일반적인 경우 이를 해결할 수 없을 수 있다.업데이트 간에 충돌이 있을 때 일관성 및 데이터 무결성을 복원하려면 업데이트의 일부 또는 전부를 완전히 또는 부분적으로 삭제해야 할 수 있다.
따라서 분산 컴퓨팅의 상당 부분은 복제된 데이터에 대한 동시 업데이트를 방지하는 방법에 초점을 맞추고 있다.그러나 또 다른 가능한 접근방식은 모든 동시 업데이트를 수행할 수 있는 낙관적 복제인데, 불일치가 생성될 수 있고, 결과는 나중에 병합되거나 "해결"된다.이 접근법에서, 복제본 간의 일관성은 결국 서로 다른 복제본의 "merges"를 통해 다시 설정된다.낙관적 복제가 일반적인 경우에는 작동하지 않을 수 있지만, 항상 수학적으로 데이터 구조의 서로 다른 복제본에 대한 동시 업데이트를 충돌 없이 병합하거나 해결할 수 있는 CRDT라는 데이터 구조의 중요하고 실제적으로 유용한 등급이 있다는 것이 밝혀졌다.따라서 CRDT는 낙관적 복제에 이상적이다.
예를 들어, 단방향 부울 이벤트 플래그는 사소한 CRDT: 1비트, 참 또는 거짓 값을 갖는 것이다.참이란 어떤 특정한 사건이 적어도 한 번은 일어났다는 것을 의미한다.거짓이란 사건이 일어나지 않았다는 뜻이다.일단 true로 설정되면 깃발은 다시 false로 설정될 수 없다.(사건이 발생한 경우, 발생하지 않을 수 없음)해결 방법은 "진정한 승리"로, 플래그가 참인 복제본(복제본이 이벤트를 관찰한 복제본)과 거짓인 복제본(복제본이 이벤트를 관찰하지 않은 복제본)을 병합할 때 해결된 결과는 참이다. 즉, 이벤트가 관찰된 경우).
CRDT 유형
CRDT에는 두 가지 접근방식이 있는데, 두 접근방식은 모두 강력한 궁극적 일관성을 제공할 수 있다: 운영 기반 CRDT와[10][11] 주 기반 CRDT이다.[12][13]
그 두 가지 대안은 이론적으로 동등하다. 하나는 다른 하나를 모방할 수 있기 때문이다.[1]그러나 실제적인 차이가 있다.주 기반의 CRDT는 설계와 구현이 더 간단하다. 통신 기판에서의 유일한 요구 사항은 일종의 가십 프로토콜이다.그들의 단점은 모든 CRDT의 전체 상태가 결국 다른 모든 복제본으로 전송되어야 한다는 것인데, 비용이 많이 들 수도 있다.이와는 대조적으로, 운영 기반 CRDT는 일반적으로 작은 업데이트 작업만 전송한다.그러나 운영 기반 CRDT는 통신 미들웨어로부터 보증을 요구한다. 즉, 다른 복제본으로 전송될 때 운영이 삭제되거나 중복되지 않으며, 그것들은 인과적 순서로 전달된다.[1]
작업 기반 CRDT
운영 기반 CRDT는 역방향 복제 데이터 유형 또는 CMRDT라고도 한다.CmRDT 복제본은 업데이트 작업만 전송하여 상태를 전파한다.예를 들어, 단일 정수의 CmRDT는 연산(+10) 또는 (-20)을 브로드캐스트할 수 있다.복제본은 업데이트를 수신하여 로컬로 적용한다.그 수술은 상쇄적이다.그러나, 그들이 반드시 빈약한 것은 아니다.따라서 통신 기반 구조는 복제의 모든 작업이 복제 없이 순서에 상관없이 다른 복제본으로 전달되도록 보장해야 한다.
순수 운영 기반 CRDT는[11] 메타데이터 크기를 줄이는 운영 기반 CRDT의 변종이다.
주 기반 CRDT
상태 기반 CRDT를 수렴 복제 데이터 유형 또는 CvRDT라고 한다.CmRDT와는 대조적으로 CvRDT는 다른 복제본으로 전체 로컬 상태를 전송하며, 여기서 상태는 상호 작용, 연관성 및 IDempotent여야 하는 함수에 의해 병합된다.병합 함수는 모든 복제 상태 쌍에 조인을 제공하므로 모든 상태의 집합이 반일격자를 형성한다.업데이트 함수는 반일률과 동일한 부분 순서 규칙에 따라 단조롭게 내부 상태를 증가시켜야 한다.
델타 주 CRDT[13][14](또는 단순히 델타 주 CRDT)는 최적화 상태 기반 CRDT로, 최근에 적용된 상태 변경사항이 전체 상태가 아닌 상태로 전파된다.
비교
CmRDTs는 복제본 간 작업 전송을 위한 프로토콜에 더 많은 요구사항을 두는 반면, 내부 상태의 크기에 비해 트랜잭션 수가 적을 때 CvRDT보다 대역폭을 적게 사용한다.그러나 CvRDT 병합 기능은 연관성이 있으므로, 일부 복제본의 상태와 병합하면 해당 복제본에 대한 모든 이전 업데이트가 생성된다.가십 프로토콜은 네트워크 사용을 줄이고 토폴로지 변경을 처리하는 동시에 CvRDT 상태를 다른 복제본으로 전파하는 데 효과적이다.
주 기반 CRDT의 스토리지 복잡성에 대한 일부 하한은[15] 알려져 있다.
알려진 CRDT
G-카운터(성장 전용
페이로드 정수[n] P 이니셜 [0,0, ...,0] 업데이트 증분()을 g = myId() P[g] := P[g] + 1 쿼리 값() : 정수 v let v = σi P[i] 비교(X, Y) : 부울 b let b = (∀i [0, n - 1] : X.P[i] ≤ Y.P[i] 병합 (X, Y) : 페이로드 Z let ∀i [0, n - 1] : Z.P[i] = 최대(X)P[i], Y.P[i]
이 CvRDT는 n개의 노드로 구성된 클러스터에 대해 카운터를 구현한다.클러스터의 각 노드에는 0에서 n - 1까지의 ID가 할당되며, myId()에 대한 호출을 통해 검색된다.따라서 각 노드에는 배열 P에 자체 슬롯이 할당되며, 이 슬롯은 로컬로 증가한다.업데이트는 백그라운드에서 전파되며, P에 있는 모든 요소의 최대()를 취함으로써 병합된다.비교 함수는 주에 대한 부분 순서를 나타내기 위해 포함되어 있다.병합 함수는 교호화, 연관성, 특이점이다.업데이트 기능은 비교 기능에 따라 단조롭게 내부 상태를 증가시킨다.그러므로 이것은 정확하게 정의된 CvRDT이며 강한 궁극적인 일관성을 제공할 것이다.CMRDT 등가 방송은 수신되는 대로 운영을 증가시킨다.[2]
PN 카운터(양극-음극 카운터)
payload integer[n] P, integer[n] N initial [0,0,...,0], [0,0,...,0] update increment() let g = myId() P[g] := P[g] + 1 update decrement() let g = myId() N[g] := N[g] + 1 query value() : integer v let v = Σi P[i] - Σi N[i] compare (X, Y) : boolean b let b = (∀i ∈ [0, n - 1] : X.P[i] ≤ Y.P[i] ∧ ∧ ∈ [0, n - 1] : X.N[i] ≤ Y.N[i] 병합 (X, Y) : 페이로드 Z let ∀i [0, n - 1] : Z.P[i] = 최대(X)P[i], Y.P[i]는 ∀i ∈ [0, n - 1] : Z로 한다.N[i] = 최대(X)N[i], Y.N[i]
CRDT 개발에서 공통적인 전략은 여러 CRDT를 결합하여 보다 복잡한 CRDT를 만드는 것이다. 이 경우, 두 개의 G-Counter를 결합하여 증분 및 감소 연산을 모두 지원하는 데이터 유형을 만든다."P" G-Counter는 증분을 카운트하고, "N" G-Counter는 감소를 카운트한다.PN-Counter 값은 P 카운터의 값에서 N 카운터의 값을 뺀 값이다.병합된 P 카운터를 두 개의 P-카운터의 병합으로 하고, 마찬가지로 N 카운터에 대해 병합하여 처리한다.CRDT의 내부 상태는 쿼리를 통해 노출된 외부 상태가 이전 값으로 돌아갈 수 있지만 단조롭게 증가해야 한다는 점에 유의하십시오.[2]
G-세트(성장 전용 세트)
페이로드 세트 A 초기 ∅ update add(element e) A :=A ∪ {e} 쿼리 조회(e) : 부울 b let b = (e e A) 비교(S, T) : 부울 b let b = (S)A ⊆ T.A) 병합 (S, T) : 페이로드 U let U.A = S.A ∪ T.A.
G-Set(그로우 전용 세트)는 추가만 허용하는 세트다.한 번 추가된 요소는 제거할 수 없다.두 G-세트의 합병이 그들의 결합이다.[2]
2P-세트(2상 세트)
payload set A, set R initial ∅, ∅ query lookup(element e) : boolean b let b = (e ∈ A ∧ e ∉ R) update add(element e) A := A ∪ {e} update remove(element e) pre lookup(e) R := R ∪ {e} compare (S, T) : boolean b let b = (S.A ⊆ T.A ∧ S.R ⊆ T.R) 병합 (S, T) : 페이로드 U let U.A = S.A ∪ T.A let U.R = S.R let T.R.
두 개의 G-세트(그로우 전용 세트)가 결합되어 2P 세트를 생성한다.제거 세트("텀브스톤 세트"라고 함)를 추가하면 원소를 추가하고 제거할 수 있다.일단 제거되면 요소를 다시 추가할 수 없다. 즉, 요소 e가 비석 집합에 있으면 해당 요소에 대해 쿼리는 다시는 True를 반환하지 않는다.2P 세트는 "제거-wins" 의미론을 사용하므로 제거(e)가 add(e)보다 우선한다.[2]
LWW-Element-Set (Last-Write-Wins-Element-Set)
LWW-Element-Set는 "추가 세트"와 "제거 세트"로 구성되며 각 요소에 대한 타임스탬프가 있다는 점에서 2P-Set와 유사하다.타임스탬프와 함께 요소를 추가 집합에 삽입하여 요소를 LWW-Element-Set에 추가한다.제거 세트에 타임스탬프를 다시 추가하여 LWW-Element-Set에서 요소를 제거한다.요소는 추가 집합에 있고 제거 집합에 없거나 제거 집합에 없지만 추가 집합의 최신 타임스탬프보다 이전 타임스탬프가 있는 경우 LWW-Element-Set의 멤버다.LWW-Element-Set의 두 복제본을 병합하는 것은 추가 세트와 제거 세트의 결합으로 이루어진다.타임스탬프가 같을 때 LWW-Element-Set의 "bias"가 작동한다.LWW-Element-Set는 추가 또는 제거에 치우칠 수 있다.LWW-Element-Set over 2P-Set의 장점은 2P-Set와 달리 LWW-Element-Set는 제거 후 요소를 다시 삽입할 수 있다는 점이다.[2]
OR-Set(Observed-Remove Set)
OR-Set은 LWW-Element-Set와 유사하지만 타임스탬프 대신 고유 태그를 사용한다.세트의 각 요소에 대해, 추가 태그 목록과 제거 태그 목록이 유지된다.요소는 새로운 고유 태그를 생성하여 요소의 추가 태그 목록에 추가함으로써 OR-Set에 삽입된다.요소의 추가 태그 목록에 있는 모든 태그를 요소의 제거 태그(톰브스톤) 목록에 추가함으로써 요소가 OR-Set에서 제거된다.두 개의 OR-Set를 병합하려면 각 요소에 대해 해당 추가 태그 목록을 두 개의 추가 태그 목록과 마찬가지로 두 개의 제거 태그 목록과 결합하도록 하십시오.요소는 추가 태그 리스트에서 제거 태그 리스트를 뺀 경우에만 세트의 멤버다.[2]묘비 세트를 유지할 필요가 없어지는 최적화가 가능하다. 이렇게 하면 묘비 세트의 잠재적으로 무한 성장을 피할 수 있다.최적화는 각 복제본에 대한 타임스탬프의 벡터를 유지함으로써 달성된다.[16]
시퀀스 CRDT
OT(Operational Transformation)의 대안으로 시퀀스, 목록 또는 순서 집합 CRDT를 사용하여 Collaborative 실시간 편집기를 작성할 수 있다.
알려진 시퀀스 CRDT로는 Treedoc,[5] RGA,[17] Woot,[4] Logoot,[18] LSEQ가 있다.[19] CRATE는[20] LSEQSplit(LSEQ의 확장형) 위에 구축된 분산형 실시간 편집기로 WebRTC를 사용하는 브라우저 네트워크에서 실행할 수 있다.LogootSplit은 시퀀스 CRDT의 메타데이터를 줄이기 위해 Logoot의 확장으로 제안되었으며, MUTER는 LogootSplit 알고리즘에 의존하는 온라인 웹 기반의 P2P 실시간 협업 편집기이다.
공개 소스를 포함한 산업용 시퀀스 CRDT는 최적화와 보다 현실적인 시험 방법론 때문에 학문적 구현을 능가하는 것으로 알려져 있다.[24]대표적인 예로 나무 대신 플레인 리스트(ala Kleppmann의 오토매지)를 사용하는 선구자인 Yjs CRDT가 있다.[25]
산업용
님버스 노트는 협업 편집에 Yjs CRDT를 사용하는 협업 노트필기 어플리케이션이다.[26]
Redis는 Redis 오픈 소스에 기반하고 완전하게 호환되는 글로벌 분산 데이터베이스를 구현하기 위해 CRDT를 사용하는 분산형 고가용성 확장형 메모리 내장 데이터베이스다.
Redis 위에 구현된 SoundCloud 스트림을 위한 LWW-element-set CRDT인 SoundCloud Open-sourceed Roshi.[27]
Riak은 CRDT를 기반으로 분산된 NoSQL 키 값 데이터 저장소 입니다.[28]리그 오브 레전드는 동시 사용자 750만 명, 초당 1만1000개의 메시지를 처리하는 게임 내 채팅 시스템에 리악 CRDT 구현을 사용한다.[29]Bet365는 Riak의 OR-Set 구현에 수백 메가바이트의 데이터를 저장한다.[30]
TomTom은 CRDT를 사용하여 사용자의 장치 간에 탐색 데이터를 동기화한다.[31]
Elixir에서 작성된 웹 프레임워크인 Phoenix는 버전 1.2에서 실시간 다중 노드 정보 공유를 지원하기 위해 CRDT를 사용한다.[32]
Facebook은 아폴로에서 대기 시간이 짧은 "규모에 맞는 일관성" 데이터베이스에 CRDT를 구현한다.[33]
Teletype for Atom은 CRDT를 채용하여 개발자가 팀원들과 업무 공간을 공유하고 실시간으로 코드로 협업할 수 있도록 한다.[34]
Haja Networks의 OrbitDB는 핵심 데이터 구조인 IPFS-Log에 운영 기반 CRDT를 사용한다.[35]
애플은 여러 기기 간 오프라인 편집을 동기화하기 위해 Notes 앱에 CRDT를 구현한다.[36]
수영은 지속적인 인텔리전스를 제공하는 분산형 실시간 스트리밍 애플리케이션을 실행하는 플랫폼이다.스트리밍 데이터 파이프라인을 구현하는 DAG의 다른 행위자에게 순수 OP 기반 CRDT 상태 업데이트를 스트리밍하는 스트리밍 행위자를 사용한다.
참조
- ^ a b c Shapiro, Marc; Preguiça, Nuno; Baquero, Carlos; Zawirski, Marek (2011). "Conflict-Free Replicated Data Types". Stabilization, Safety, and Security of Distributed Systems (PDF). Lecture Notes in Computer Science. Vol. 6976. Grenoble, France: Springer Berlin Heidelberg. pp. 386–400. doi:10.1007/978-3-642-24550-3_29. ISBN 978-3-642-24549-7.
- ^ a b c d e f g Shapiro, Marc; Preguiça, Nuno; Baquero, Carlos; Zawirski, Marek (13 January 2011). "A Comprehensive Study of Convergent and Commutative Replicated Data Types". Rr-7506.
- ^ Shapiro, Marc; Preguiça, Nuno (2007). "Designing a Commutative Replicated Data Type". Computing Research Repository (CoRR). abs/0710.1784. arXiv:0710.1784. Bibcode:2007arXiv0710.1784S.
- ^ a b Oster, Gérald; Urso, Pascal; Molli, Pascal; Imine, Abdessamad (2006). Proceedings of the 2006 20th anniversary conference on Computer supported cooperative work - CSCW '06. p. 259. CiteSeerX 10.1.1.554.3168. doi:10.1145/1180875.1180916. ISBN 978-1595932495. S2CID 14596943.
- ^ a b Letia, Mihai; Preguiça, Nuno; Shapiro, Marc (2009). "CRDTs: Consistency without Concurrency Control". Computing Research Repository (CoRR). abs/0907.0929. arXiv:0907.0929. Bibcode:2009arXiv0907.0929L.
- ^ Preguiça, Nuno; Marques, Joan Manuel; Shapiro, Marc; Letia, Mihai (June 2009), "A Commutative Replicated Data Type for Cooperative Editing" (PDF), Proc 29th IEEE International Conference on Distributed Computing Systems, Montreal, Quebec, Canada: IEEE Computer Society, pp. 395–403, doi:10.1109/ICDCS.2009.20, ISBN 978-0-7695-3659-0, S2CID 8956372
- ^ Baquero, Carlos; Moura, Francisco (1997), Specification of Convergent Abstract Data Types for Autonomous Mobile Computing, Universidade do Minho
- ^ Schneider, Fred (December 1990). "Implementing Fault-Tolerant Services Using the State Machine Approach: A Tutorial". ACM Computing Surveys. 22 (4): 299–319. doi:10.1145/98163.98167. S2CID 678818.
- ^ "Conflict-free Replicated Data Types" (PDF). inria.fr. July 19, 2011.
- ^ Letia, Mihai; Preguiça, Nuno; Shapiro, Marc (1 April 2010). "Consistency without Concurrency Control in Large, Dynamic Systems" (PDF). SIGOPS Oper. Syst. Rev. 44 (2): 29–34. doi:10.1145/1773912.1773921. S2CID 6255174.
- ^ a b Baquero, Carlos; Almeida, Paulo Sérgio; Shoker, Ali (2014-06-03). Magoutis, Kostas; Pietzuch, Peter (eds.). Making Operation-Based CRDTs Operation-Based. Lecture Notes in Computer Science. Springer Berlin Heidelberg. pp. 126–140. CiteSeerX 10.1.1.492.8742. doi:10.1007/978-3-662-43352-2_11. ISBN 9783662433515.
- ^ Baquero, Carlos; Moura, Francisco (1 October 1999). "Using Structural Characteristics for Autonomous Operation". SIGOPS Oper. Syst. Rev. 33 (4): 90–96. doi:10.1145/334598.334614. hdl:1822/34984. S2CID 13882850.
- ^ a b Almeida, Paulo Sérgio; Shoker, Ali; Baquero, Carlos (2015-05-13). Bouajjani, Ahmed; Fauconnier, Hugues (eds.). Efficient State-Based CRDTs by Delta-Mutation. Lecture Notes in Computer Science. Springer International Publishing. pp. 62–76. arXiv:1410.2803. doi:10.1007/978-3-319-26850-7_5. ISBN 9783319268491. S2CID 7852769.
- ^ Almeida, Paulo Sérgio; Shoker, Ali; Baquero, Carlos (2016-03-04). "Delta State Replicated Data Types". Journal of Parallel and Distributed Computing. 111: 162–173. arXiv:1603.01529. Bibcode:2016arXiv160301529S. doi:10.1016/j.jpdc.2017.08.003. S2CID 7990602.
- ^ Burckhardt, Sebastian; Gotsman, Alexey; Yang, Hongseok; Zawirski, Marek (23 January 2014). "Replicated Data Types: Specification, Verification, Optimality". Proceedings of the 41st ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages (PDF). pp. 271–284. doi:10.1145/2535838.2535848. ISBN 9781450325448. S2CID 15023909.
- ^ 아네트 비에니우사, 마렉 자위르스키, 누노 프레기사, 마르크 샤피로, 카를로스 바케로, 발터 베일가스, 세르지오 두아르테, "최적화된 갈등 없는 복제 세트"(2012) 아르시브:1210.3368
- ^ Roh, Huyn-Gul; Jeon, Myeongjae; Kim, Jin-Soo; Lee, Joonwon (2011). "Replicated Abstract Data Types: Building Blocks for Collaborative Applications". Journal of Parallel and Distributed Computing. 71 (2): 354–368. doi:10.1016/j.jpdc.2010.12.006.
- ^ Weiss, Stephane; Urso, Pascal; Molli, Pascal (2010). "Logoot-Undo: Distributed Collaborative Editing System on P2P Networks". IEEE Transactions on Parallel and Distributed Systems. 21 (8): 1162–1174. doi:10.1109/TPDS.2009.173. ISSN 1045-9219. S2CID 14172605.
- ^ Nédelec, Brice; Molli, Pascal; Mostefaoui, Achour; Desmontils, Emmanuel (2013). "LSEQ". LSEQ an adaptive structure for sequences in distributed collaborative editing (PDF). p. 37. doi:10.1145/2494266.2494278. ISBN 9781450317894. S2CID 9215663.
- ^ Nédelec, Brice; Molli, Pascal; Mostefaoui, Achour (2016). "CRATE: Writing Stories Together with our Browsers". Proceedings of the 25th International Conference Companion on World Wide Web. p. 231. doi:10.1145/2872518.2890539. S2CID 5096789. Archived from the original on 2020-01-01. Retrieved 2020-01-01.
- ^ André, Luc; Martin, Stéphane; Oster, Gérald; Ignat, Claudia-Lavinia (2013). "Supporting Adaptable Granularity of Changes for Massive-scale Collaborative Editing". Proceedings of the International Conference on Collaborative Computing: Networking, Applications and Worksharing – CollaborateCom 2013. pp. 50–59. doi:10.4108/icst.collaboratecom.2013.254123. ISBN 978-1-936968-92-3.
- ^ "MUTE". Coast Team. March 24, 2016.
- ^ Nicolas, Matthieu; Elvinger, Victorien; Oster, Gérald; Ignat, Claudia-Lavinia; Charoy, François (2017). "MUTE: A Peer-to-Peer Web-based Real-time Collaborative Editor". Proceedings of ECSCW Panels, Demos and Posters 2017. doi:10.18420/ecscw2017_p5.
- ^ Gentle, Seph. "Faster CRDTs: An Adventure in Optimization". josephg.com. Retrieved 1 August 2021.
- ^ "yjs/yjs: Shared data types for building collaborative software". GitHub.
- ^ "About CRDTs". Retrieved 2020-06-18.
- ^ Bourgon, Peter (9 May 2014). "Roshi: a CRDT system for timestamped events". SoundCloud.
- ^ "Introducing Riak 2.0: Data Types, Strong Consistency, Full-Text Search, and Much More". Basho Technologies, Inc. 29 October 2013.
- ^ Hoff, Todd (13 October 2014). "How League of Legends Scaled Chat to 70 Million Players - It Takes Lots of Minions". High Scalability.
- ^ Macklin, Dan. "bet365: Why bet365 chose Riak". Basho.
- ^ Ivanov, Dmitry. "Practical Demystification of CRDTs".
- ^ McCord, Chris. "What makes Phoenix Presence Special".
- ^ Mak, Sander. "Facebook Announces Apollo at QCon NY 2014".
- ^ "Code together in real time with Teletype for Atom". Atom.io. November 15, 2017.
- ^ "OrbitDB/ipfs-log on Github". Retrieved 2018-09-07.
- ^ "IOS Objective-C headers as derived from runtime introspection: NST/IOS-Runtime-Headers". 2019-07-25.
외부 링크
- CRDT에 대한 리소스 및 문서 모음
- Marc Shapiro의 "강력한 최종 일관성 및 충돌 없는 복제 데이터 유형"(CRDT에 대한 설명)
- Christopher Meiklejohn의 충돌 없는 복제 데이터 유형 읽기
- CAP 정리 및 CRDT: 12년 후 CAP. Eric Brewer에 의한 규칙의 변화