List functional requirements for the system (Ask the chat bot for hints if stuck.)...
List non-functional requirements for the system...
Estimate the scale of the system you are going to design...
Define what APIs are expected from the system...
Used by mobile/desktop/laptop apps and web browser to grab all content metadata from a user's account in dropbox server.
GET dropbox.api.com/1/contents
Request Header : [
Authorization = Bearer <Oauth Token>
]
Response: 200 OK
Response Body: { an array of ContentMetadata }
Used by mobile/desktop/laptop apps to indicate that a file upload is going to be initiated. The client will start using POST Chunk API for uploading chunks of file.
POST dropbox.api.com/1/contents
Request Header : [
Authorization = Bearer <Oauth Token>
]
Request Body: { ContentMetadata }
Response : 200
Response Header: [SessionId = ZZZwweee...]
Response body: { ContentMetadata }
Used by mobile/desktop/laptop apps to upload file content in parts. Dropbox server assembles the chunk to a final content
POST dropbox.api.com/1/contents/chunks
Request Header : [
Content-Type = application/octetstream
Authorization = Bearer <Oauth Token>
SessionId = ZZZwweee...
]
Request Body: { ChunkMetadata + bytestream }
Response : 200
Response body: { ChunkMetadata }
Used by mobile/desktop/laptop apps to upload file content in parts. Dropbox server assembles the chunk to a final content
POST dropbox.api.com/1/contents/chunks
Request Header : [
Authorization = Bearer <Oauth Token>
SessionId = ZZZwweee...
]
Request Body: { ContentMetadata }
Response : 200
Response body: { ContentMetadata }
Used by mobile/desktop/laptop apps to get all chunk metadata for a content from dropbox server
GET dropbox.api.com/1/contents?content={contentId}
Request Header : [
Authorization = Bearer <Oauth Token>
]
Response : 200 OK
Response Body: { A list of ChunkContent }
TBD - or browsers to upload a file in its complete form
Defining the system data model early on will clarify how data will flow among different components of the system. Also you could draw an ER diagram using the diagramming tool to enhance your design...
You should identify enough components that are needed to solve the actual problem from end to end. Also remember to draw a block diagram using the diagramming tool to augment your design. If you are unfamiliar with the tool, you can simply describe your design to the chat bot and ask it to generate a starter diagram for you to modify...
A file is size can be max 50GB. The file is sliced into chunks of 4MB to 16MB. The native app computes hash (XXH3 or BLAKE3) and prepares metadata for each chunk. The metadata. This metadata consists of
{
chunkId: 1,
sequence: 1,
filename: "rocks.txt",
offsetStart: 0,
offsetend: 123456,
createdOn: <timestamp>,
lastUpdatedOn: <timestamp>,
ownerId: "1234",
checksum: ZZZeeewww...
location: "path in dropbox file server"
}
When a file is changed in another device, the native app in the device prepares #1 or #2 above and pushes the full file or delta chunks of the file to the dropbox server. A Server Side Event is pushed from dropbox server to the devices to initiate a call home on changes. The native client reaches out to dropbox with a last sync timestamp. The changes post this timestamp are returned in the form of metadata. The client compares these metadata with local metadata cache and downloads the required chunks which are modified in the dropbox server and updates the local files accordingly. The updates might result in file delete, merge, add operations.
Here the user login to account using a browser, the browser lists the home drive and recently accessed files. The dropbox web application lists files and folder and users can navigate/search the files
There are cases where a same file is modified in multiple devices which results in conflict and uploaded at once. For instance there are two devices modifying the file, Client A & Client B. Client A commits the file first and dropbox server updates the chunks modified by Client A and update the file version to Version + 1. That is now Client B has N - 1 version. In this case, if Client B updated different chunks in the file than the Client A, dropbox will merge the changes and produces a new version N + 1. However if both clients modifies the same content chunk then Client B will be notified that a version is updated and would require to download the latest & merge. A separate copy of Client B's file is made at dropbox server named `copy-of-xxxx` filename, by keeping Client B's changes.
The case here is both devices or two different users updating the same file at the same time. If both parties are updating different chunks then dropbox server will merge the file and produce a new version. However if the same chunk is modified by both parties then the last write wins. However the version is updated for each commit. This means the user can see the history of changes
Files are stored in Data nodes spread across regions. This means the chunks of each file are stored in different physical server. For instance, a file is divided into 10 chunks, each chunk is stored in different storage servers in encrypted form.
When the file is divided into 10 block (chunks) a 6 parity blocks are added to it, making it 10, 6 erasure coding. This is better than replication where each block is copied to 3 or more storage servers (30 chunks altogether). This incurs huge storage for 400M users or 35PB of data.
Erasure coding helps in keeping 6 parities for 10 blocks of data making it 16 blocks of data. We can recover or reconstruct data even if lose 6 nodes (assuming each block is stored in different storage servers). The worst case is losing 7+ nodes, in which case the file is lost and cannot be recovered. Its important to store these chunks in different storage nodes. Altogether in this case atleast we need 16 server nodes.
A storage monitoring service that looks for disk health, node health, partition healths and publishes a message. The message might indicate a disk failure or chunk failure
A chunk repair service picks up the message and acts on it by looking at degraded chunks and repair them by reconstructing and placing the chunks in same or different storage nodes. It reads the chunk metadata from Chunk coordinator service and tries to repair the chunks. This is part of health and wellness monitoring job that picks up the chunks to repair.
User A shares a file/folder with User B, this creates an entry into the Sharing table in database with file id, target userid, permissions (read/write/both), timestamp, userid who shared, expiration time if set etc . User A creates a pre-signed url for the file/folder and shares it with User B. The user B should have a dropbox account to view the file, when User B logins to dropbox under the "Shared with Me" tab, they will see the shared files. The sharing metadata will have the entry than the content metadata table in the database. When the file is shared the file is loaded onto the CDN nearest to the target user(s). This helps in downloading/reading file faster.
Explain how the request flows from end to end in your high level design. Also you could draw a sequence diagram using the diagramming tool to enhance your explanation...
When the client decides to upload a content, the client makes a call to `start` upload API, this returns a session key with a time expiry period, lets say 48hrs. Client presents this session key in every chunk upload request and the final `finish` API. Only when the client invokes `finish` method with all the chunks , dropbox server considers that the content upload is complete and available for read/write, until then the content metadata indicates the upload in progress to the user that started upload.
The client always cache the chunks of the file and its metadata plus the progress of upload. This is verified periodically by invoking the chunk metadata api from dropbox which returns what dropbox received so far. In case of a failure while uploading chunk or the device goes out of network or shutdown the local cache in the client is updated with the status of upload for the chunk. When client is online the background process downloads the latest chunk metadata for the content and compares with local cache and retry to upload the chunk accordingly. In case the client device is offline and session is expired,
Dig deeper into 2-3 components and explain in detail how they work. For example, how well does each component scale? Any relevant algorithm or data structure you like to use for a component? Also you could draw a diagram using the diagramming tool to enhance your design...
Explain any trade offs you have made and why you made certain tech choices...
Try to discuss as many failure scenarios/bottlenecks as possible.
Kubernetes ensures resilience and fault tolerance through self-healing, declarative management and distributed orchestration. Kubernetes checks "whats is desired vs whats the status right now" This means the failures on,
There can be scenarios where the clients lose network connection and ends up partial chunks. The chunk monitoring jobs looks for these partial chunks, however this introduces database I/O to remove those chunks from filesystem and update the chunk metadata. Partial chunk is identified by checksum comparison of what is mentioned in the request header and what is received in the dropbox server. Such chunk upload API operation results in error and asks client to retry.
The chunk are verified for its correctness, if found the chunks are corrupted then the repair job works to correct chunks by recreating from the parity chunks.
What are some future improvements you would make? How would you mitigate the failure scenario(s) you described above?