# Design Google Doc

## Design Google Doc

> [Conclave doc](https://conclave-team.github.io/conclave-site/) 写得不错。

> [Google Doc official blog](https://drive.googleblog.com/2010/09/whats-different-about-new-google-docs.html) 讲了 OT resolve conflict 的流程。写得不错。

> Ref: [Tech Dummies video](https://www.youtube.com/watch?v=2auwirNBvGg) 讲得非常非常一般。

***

## Requirements

### Functional requirements

* Users can edit / view the document. They can upload image, photos, videos
* Size of image or videos can range from 2MB-2GB
* 100 writers and edit at same time, 10,000 readers can see at same time.

### Non-functional requirements

* Every update should be available to other person within 3 secs.

***

## Traffic Estimation

* DAU: 50 M
* Storage:
  * daily: 50 M \* 1000 bytes = 50 TB
  * 5 years: 50 TB \* 365 \* 5 = 90000 TB
* bandwidth:
  * 50 TB / (24 \* 3600) = 600 MB / s

***

## High-level architecture

![](https://2407442552-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lpv9LvHzpublmUWisvz%2Fuploads%2Fgit-blob-b7483e00075fdca0b1111dfe60431c9273c0363f%2Fgoogle_doc.png?alt=media)

***

## Detailed Design

### Text editing

![](https://2407442552-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lpv9LvHzpublmUWisvz%2Fuploads%2Fgit-blob-28b9675fd9773a97179f0b23d5409889d546aea4%2F1.png?alt=media)

* text editing can be split into several operations
  * insert("c", 0)
  * delete(0)
  * update()
  * retain()

### Real-time communication

* we introduce a central relay server to facilitate the communication

![](https://2407442552-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lpv9LvHzpublmUWisvz%2Fuploads%2Fgit-blob-4a080fe289ecf62912c6216a80a32b7762198a4e%2F2.png?alt=media)

***

### Option 1: Operational Transformation (OT)

* Google Doc use OT
* if user 1 made changes and sent to user 2, OT will perform transformation to user2 to make it valid, vice versa
* Con: hard to implement

![](https://2407442552-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lpv9LvHzpublmUWisvz%2Fuploads%2Fgit-blob-0f43885e3f234652a45789bda26c1ad525f57f78%2F3.png?alt=media)

***

### Option 2: Conflict-Free Replicated Data Type (CRDT)

* CRDT is a version to strengthen and simplify OT

#### Globally Unique Characters

![](https://2407442552-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lpv9LvHzpublmUWisvz%2Fuploads%2Fgit-blob-5b7a725d8eeb6502a005d7d68bdebd490852ace7%2F4.png?alt=media)

* Each character object must be globally unique
* This is achieved by assigning `Site ID` and `Site Counter` properties whenever a new character is inserted. Since the `Site Counter` at each site increments whenever inserting or deleting a character, we ensure the global uniqueness of all characters.

#### Globally Ordered Characters

![](https://2407442552-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lpv9LvHzpublmUWisvz%2Fuploads%2Fgit-blob-88b0b63308eee91e43b4d573863d86d8b78ca600%2F5.png?alt=media)

![](https://2407442552-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lpv9LvHzpublmUWisvz%2Fuploads%2Fgit-blob-e0bfeefe1f66471aeba8559cf6a366cfa7940db9%2F6.png?alt=media)

![](https://2407442552-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lpv9LvHzpublmUWisvz%2Fuploads%2Fgit-blob-c38f168703ede5586cc6c5b2f8cf2dca63ac9e91%2F7.png?alt=media)

* We need all the characters to be globally ordered and consistent.
* That means that when a user inserts a character, it will be placed in the same position on every user’s copy of the shared document.
* We can use fractional indices as opposed to numerical indices.

***

### Option 3: Differential Synchronization

![](https://2407442552-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lpv9LvHzpublmUWisvz%2Fuploads%2Fgit-blob-5c06e7d8f4e1ac49b5ca7dc6fcf6c6493a090c6d%2F8.png?alt=media)

* just like use git diff to do patch
* 具体读 paper，放在了这个 folder 下面

***

### Limitation of a Central Relay Server

#### Limitations

* high latency between users with long distance

![](https://2407442552-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lpv9LvHzpublmUWisvz%2Fuploads%2Fgit-blob-11194267f471d0e5cd16e9568b56509008e9f0da%2F9.png?alt=media)

* costly to scale
* client-server model requires that users trust the server and anyone that has access to it with their data
* reliance on a central server creates a single point-of-failure

#### Solution: Peer-to-Peer Architecture

* This means that instead of relying on a server to relay operations, we can have our users perform that work for free (at least in terms of money).
* In other words, our users will be responsible for relaying operations to other users they’re connected to.

![](https://2407442552-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lpv9LvHzpublmUWisvz%2Fuploads%2Fgit-blob-b1c8b21249b4d660280f6b55fe27aff7eb3f7f9c%2F10.png?alt=media)

#### Protocol for peer-to-peer communication - WebRTC

![](https://2407442552-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lpv9LvHzpublmUWisvz%2Fuploads%2Fgit-blob-c8237e0c4f0ed408a6b1ea75f79a741d6049c303%2F11.png?alt=media)

![](https://2407442552-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lpv9LvHzpublmUWisvz%2Fuploads%2Fgit-blob-51177213c77c1290aa47ea6b197568b270533de9%2F12.png?alt=media)

* WebRTC is a protocol that was designed for real-time communication over peer-to-peer connections.
* While WebRTC enables our users to talk directly to one another, a small server is required to initiate those peer-to-peer connections in a process called “signaling”.

#### Version Vector for solving out-of-order message delivery

* Let’s say we have 3 peers collaborating on a document. Two of the peers are next to each other while the third is far away. Peer1 types an “A” and sends the operation out to both peers. Since Peer2 is nearby, it quickly receives the operation but decides it doesn’t like it and promptly deletes it.

![](https://2407442552-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lpv9LvHzpublmUWisvz%2Fuploads%2Fgit-blob-84d5e9d5c6f6ef5706da47dbaf95260b9f2b328f%2F13.png?alt=media)

![](https://2407442552-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lpv9LvHzpublmUWisvz%2Fuploads%2Fgit-blob-e4e6fdcffe642cb63962c52b183cbbe76d8df8ae%2F14.png?alt=media)

* Solution: Version Vector.
  * Whenever an operation is sent out, in addition to the character object and whether it’s an insertion or deletion, we also include the character’s `Site ID` and `Site Counter` value. The `SiteID` indicates who originally sent the operation, and the `Counter` indicates which operation number it is from that particular user.
  * When a peer receives a delete operation, it’s immediately placed in a `Deletion Buffer`. If it were an insert, we could just apply it immediately. But with deletes, we have to make sure the character has been inserted first.
  * After every operation (insert or delete), the deletion buffer is “processed” to check if the characters have been inserted yet. In this example, the character has a `SiteID` of 1 and Counter of 24.
  * After some more time, the insert operation finally arrives at Peer3, and its version vector is updated to reflect that it’s seen 24 operations from Peer1. Since we’ve received a new operation, we again process the deletion buffer. This time, when the deletion operation’s character is compared to the version vector, the delete operation can be removed from the buffer and applied.

![](https://2407442552-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lpv9LvHzpublmUWisvz%2Fuploads%2Fgit-blob-9bb0098748e33173c863123feb8a5d64df9123a1%2F15.png?alt=media)

![](https://2407442552-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lpv9LvHzpublmUWisvz%2Fuploads%2Fgit-blob-968eea21c73cff5b6ffa71f38b60445a010d1b8b%2F16.png?alt=media)
