Understanding Dropbox System Design

Author

Reads 689

Engineer fixing core swith in data center room
Credit: pexels.com, Engineer fixing core swith in data center room

Dropbox's system design is built around a simple yet powerful concept: storing files in a distributed network of servers. This allows users to access their files from anywhere, at any time.

Dropbox's architecture is designed to handle a large number of users and files, with a focus on scalability and reliability. The system is built around a few key components, including the Dropbox client, the Dropbox server, and the storage nodes.

The Dropbox client is responsible for communicating with the Dropbox server and storing files locally on the user's device. The Dropbox server, on the other hand, is responsible for managing the storage nodes and handling requests from the client. Storage nodes are essentially large hard drives that store the actual file data.

Dropbox's storage nodes are distributed across multiple data centers, which helps to ensure that files are always available, even in the event of a data center failure. This is achieved through a process called replication, where multiple copies of each file are stored across different data centers.

System Components

Credit: youtube.com, Dropbox system design | Google drive system design | System design file share and upload

The system components are designed to optimize data exchange between the client and server. This is crucial for handling huge volumes of read and write data, where the ratio of read to write data remains almost the same.

The client is a desktop or mobile application that watches a user's workspace and synchronizes files with a remote server. It has four main responsibilities: watching for changes, uploading or downloading changes, handling conflicts, and updating file metadata.

Here are the main system components, each with a brief description:

  • Client Metadata Database: stores information about files, chunks, chunk versions, and file locations.
  • Chunker: splits big files into chunks of 4 MB and reconstructs the original file.
  • Watcher: monitors file changes in the workspace and notifies the Indexer.
  • Indexer: updates the Client Metadata Database and notifies the Synchronizer.
  • Synchronizer: communicates with Meta Service and Block service for updating metadata and modified chunks.

These components work together to optimize data exchange and reduce bandwidth usage. By breaking files into smaller chunks, the system can upload and download only the modified chunks, reducing the amount of bandwidth used.

Client Components

The client components play a crucial role in the system, responsible for monitoring user activities, uploading and downloading files, and handling conflicts.

The Watcher component is responsible for monitoring the sync folder for all activities performed by the user, such as creating, updating, or deleting files/folders. It gives notifications to the Indexer and Chunker if any action is performed in the files or folders.

Credit: youtube.com, When & Where to Add “use client” in React / Next.js (Client Components vs Server Components)

The Chunker component breaks the files into multiple small pieces called chunks and uploads them to the cloud storage with a unique id or hash of these chunks. To recreate the files, these chunks can be joined together.

The Indexer is responsible for updating the internal database when it receives the notification from the Watcher. It receives the URL of the chunks from the Chunker along with the hash and updates the file with modified chunks.

The Client Metadata Database stores information about different files in the workspace, file chunks, chunk version, and file location in the file system. This can be implemented using a lightweight database like SQLite.

Here's a breakdown of the client components:

  • Watcher: monitors the sync folder for user activities
  • Chunker: breaks files into chunks and uploads them to cloud storage
  • Indexer: updates the internal database with chunk information
  • Client Metadata Database: stores file information and chunk metadata

By optimizing the client components, we can reduce bandwidth usage, synchronization time, and storage space in the cloud.

Metadata Server

The metadata server is a crucial component of our system, responsible for storing and managing metadata. It's essentially a directory or index that guides the system on how to reconstruct files from their constituent blocks.

Credit: youtube.com, USENIX ATC '23 - SingularFS: A Billion-Scale Distributed File System Using a Single Metadata Server

Metadata is the information about a file that doesn't include its actual content, such as its name, path, and namespace. This information is vital for the system to function properly, as it allows the metadata server to map out the sequence of blocks that make up a complete file.

The metadata server is responsible for storing this metadata in a dedicated storage space, often managed by a specialized metadata server. This server acts as the system's directory, guiding it on how to piece together files from the blocks when necessary.

To interact with the metadata server, you can use a GET request with a specific path parameter, such as /get_metadata?path=/user/directory/example.txt. This request allows you to retrieve the metadata associated with a particular file.

Here are some key aspects of the metadata server:

  • Request Type: GET
  • Request Parameters: path (e.g., /get_metadata?path=/user/directory/example.txt)

By understanding how the metadata server works, you can better appreciate the complexity and sophistication of modern cloud storage systems. The metadata server plays a critical role in ensuring efficient, reliable, and organized storage for users.

Load Balancer (LB)

Credit: youtube.com, What is a Load Balancer?

A Load Balancer (LB) is a crucial component that can be added in two places in our system: between clients and Block servers, or between clients and Metadata servers.

Initially, a simple Round Robin approach can be adopted, distributing incoming requests equally among backend servers.

This approach is easy to implement and doesn't introduce any overhead, making it a great starting point.

However, a problem with Round Robin LB is that it won't take server load into consideration, so if a server is overloaded or slow, the LB will keep sending new requests to it.

A more intelligent LB solution can be placed that periodically queries backend servers about their load and adjusts traffic based on that.

Caching

Caching is a crucial component in our system, and it's used to reduce the number of hits to the Metadata DB. We're using an in-memory caching to achieve this, specifically Redis and Memcached.

This caching strategy is known as write-around caching, where we first check if the data exists in the cache before hitting the database. If it does, we return the value from the cache, bypassing a database trip. This approach significantly improves performance.

Credit: youtube.com, CPU Cache Explained - What is Cache Memory?

We're using the Least Recently Used (LRU) eviction policy for caching data, which allows us to discard the keys that are least recently fetched. This policy is particularly useful in our system, where we need to make room for newer, hotter chunks.

A cache for Block storage is also introduced to deal with hot files/chunks. We're using an off-the-shelf solution like Memcache to store whole chunks with their respective IDs/Hashes. This cache can hold a significant amount of data, with a high-end commercial server capable of storing up to 144GB of memory.

Here's a comparison of the two cache replacement policies:

The LRU policy is a reasonable choice for our system, especially when the cache is full and we need to replace a chunk with a newer/hotter one.

Data Management

Data management is a crucial aspect of the Dropbox architecture. Data deduplication is a technique used to eliminate duplicate copies of data, improving storage utilization.

Credit: youtube.com, Design Google Drive or Dropbox (Cloud File Sharing Service) | System Design Interview Prep

To implement deduplication, we can use either post-process or in-line deduplication. Post-process deduplication stores new chunks on the storage device first, then analyzes the data for duplication, while in-line deduplication calculates hashes in real-time as clients enter data.

The system uses metadata to organize and store information about files, including their name, path, and namespace. A namespace is a unique identifier used to differentiate files from different users or directories.

Metadata is sent to a dedicated storage space, managed by a metadata server, which acts as the system's directory or index. This server guides the system on how to piece together files from their constituent blocks.

The system's data management process involves dividing files into blocks, hashing them, and managing two distinct servers. This process ensures efficient, reliable, and organized storage for users.

Here are the main components of the data management system:

  • Each user must have at least one device.
  • Each device will have at least one object (file or folder).
  • Each object may have chunks, but only files can have chunks.
  • Each object may be shared with one or multiple users.

Why Cloud Storage?

Cloud storage services have become incredibly popular, and for good reason. They simplify the storage and exchange of digital resources among multiple devices.

Credit: youtube.com, What is Cloud Data Management?

The shift from using single personal computers to multiple devices with different platforms and operating systems is accountable for this huge popularity. This shift has made it necessary to access data from various geographical locations at any time.

One of the top benefits of cloud storage services is availability. The motto of cloud storage services is to have data availability anywhere anytime.

Users can access their files/photos from any device whenever and wherever they like. This is a huge advantage, especially for those who work remotely or travel frequently.

Cloud storage also offers 100% reliability and durability of data. It ensures that users will never lose their data, by keeping multiple copies of the data stored on different geographically located servers.

Users will never have to worry about getting out of storage space with cloud storage. With cloud storage, you have unlimited storage as long as you are ready to pay for it.

Database

Credit: youtube.com, What is Database & Database Management System DBMS | Intro to DBMS

Database design is a crucial aspect of data management, and it's essential to understand the requirements of your system before designing it. Each user must have at least one device, and each device will have at least one object, such as a file or folder.

To store data, we need to create specific tables in our database. For example, we need a table to store the information of users and workspace, as well as the different versions of files and chunks.

The metadata database maintains the indexes of various chunks, containing file/chunk names, versions, user information, and workspace details. Relational databases can be difficult to scale, so we may need to use a database sharding technique to overcome this problem.

In a database sharding setup, we would add multiple MySQL databases, but managing these databases for updates or new information can be challenging. To simplify this process, we can build an edge wrapper around the sharded databases, providing an ORM (Object-Relational Mapping) layer that makes it easier for clients to interact with the database.

Here are the key requirements for our database design:

  • Each user must have at least one device.
  • Each device will have at least one object (file or folder).
  • Each object may have chunks (only files can have chunks, folders can’t have chunks).
  • Each object may be shared with one or multiple users.

Metadata Management

Credit: youtube.com, Data Management - Metadata Management

Metadata Management is a crucial aspect of data management, and it's essential to understand how it works.

Metadata is the information about the file that doesn't include its actual content, encompassing the file's name, path, and a specially designated 'namespace'. A namespace is a unique identifier, often used to differentiate files from different users or different directories.

To store metadata, a dedicated storage space is required, often managed by a specialized metadata server. This server acts as the system's directory or index, guiding it on how to piece together files from the blocks when necessary.

A metadata database maintains the indexes of the various chunks, containing files/chunks names, and their different versions along with the information of users and workspace. You can use RDBMS or NoSQL, but make sure that you meet the data consistency property because multiple clients will be working on the same file.

Relational databases are difficult to scale, so if you're using the MySQL database, you need to use a database sharding technique (or master-slave technique) to scale the application. In database sharding, you need to add multiple MySQL databases, but it will be difficult to manage these databases for any update or for any new information that will be added to the databases.

Credit: youtube.com, Metadata Management & Data Catalog (Data Architecture | Data Governance)

To overcome this problem, an edge wrapper can be built around the sharded databases. This edge wrapper provides the ORM and the client can easily use this edge wrapper's ORM to interact with the database (instead of interacting with the databases directly).

To scale out metadata DB, it needs to be partitioned so that it can store information about millions of users and billions of files/chunks. There are several partitioning schemes, including Vertical Partitioning, Range Based Partitioning, and Hash-Based Partitioning.

Here are some characteristics of each partitioning scheme:

The main problem with Range Based Partitioning is that it can lead to unbalanced servers. For example, if we decide to put all files starting with letter 'E' into a DB partition, and later we realize that we have too many files that start with letter 'E', to such an extent that we cannot fit them into one DB partition.

Hash-Based Partitioning can still lead to overloaded partitions, which can be solved by using Consistent Hashing.

File Processing

Credit: youtube.com, Design file-sharing system like Google Drive / Dropbox (System design interview with EM)

File Processing is a critical aspect of Dropbox architecture, allowing seamless collaboration and efficient transfer of files. Client A uploads chunks to cloud storage, which are then updated and committed by Client A.

Large files are broken into smaller chunks for efficient transfer, making it easier for users to upload and download files. This process is initiated by users interacting with the client application or web interface to initiate file uploads.

Notifications are sent to Clients B and C about the changes, and they receive metadata changes and download updated chunks. The Message Queuing Service keeps update notifications in separate response queues for offline clients until they become online later.

File Processing Workflow

File Processing Workflow is a crucial aspect of how files are handled in cloud storage systems. It's a complex process, but let's break it down.

Client A uploads chunks to cloud storage, which is the first step in the workflow. This is how files are divided into smaller pieces to be stored efficiently.

Credit: youtube.com, Oracle Integration - Realtime File Processing from Object Storage

Client A updates metadata and commits changes, which is the next step after uploading chunks. This ensures that the file's properties, such as name and description, are up to date.

Notifications are sent to other clients, like Client B and C, about the changes made by Client A. This is done to keep all clients in sync.

If a client is not online at the time of the update, the Message Queuing Service keeps the update notifications in separate response queues for them. This ensures that they receive the updates as soon as they come online.

Client B and C receive metadata changes and download updated chunks, which is the final step in the workflow. This allows them to access the updated file.

Chunking Files

Chunking files is a clever way to improve performance when uploading or downloading large files. By breaking down files into smaller chunks, you can upload or download each chunk separately, reducing the overall time it takes.

Credit: youtube.com, Http Request Chunking

Multiple chunks can be uploaded in parallel, making the process faster. For example, if you're uploading a 16 MB file in 4 MB chunks, you can upload all four chunks simultaneously.

If there's a small change in the file, only the affected chunk needs to be uploaded and downloaded by other clients, saving bandwidth and time. This is especially useful in collaborative environments where multiple users are working on the same file.

If the upload is interrupted due to network connectivity loss, you can simply resume from the last chunk already uploaded, saving bandwidth and time.

Here are the benefits of chunking files:

  • Improved performance through parallel uploads
  • Reduced bandwidth usage with only affected chunks uploaded
  • Resume capability in case of network interruptions

Scalability and Performance

Dropbox's architecture is built with scalability and performance in mind. By chunking files and data deduplication while uploading files, Dropbox sees a significant boost in performance.

This chunking process allows for faster upload times and reduces the strain on servers. I've experienced this firsthand when uploading large files to Dropbox - it's noticeably faster than other cloud storage services.

Credit: youtube.com, How We've Scaled Dropbox

Our architecture is highly scalable, thanks to several key features. Horizontal scaling is one of them, where we can add more servers behind the load balancer to increase capacity.

This is known as Horizontal Scaling, and each service can be independently scaled horizontally in our design. Each shard is essentially a separate database instance that can be distributed across different servers or even different geographic locations.

Database sharding is a horizontal partitioning technique where a large database is divided into smaller, more manageable parts called shards. Sharding helps distribute the load, improve query performance, and enhance scalability.

Here are the benefits of sharding:

  • Distributed load
  • Improved query performance
  • Enhanced scalability

Cloud/Block Storage

Cloud/Block Storage is a key component of Dropbox's architecture. It stores chunks of files uploaded by users.

Cloud/Block Storage can be implemented using a distributed file system like Glusterfs or Amazon S3. Distributed file systems provide high reliability and durability, ensuring that uploaded files are never lost.

Dropbox started by using S3 as block storage, but as they grew, they developed an in-house multi-exabyte storage system called Magic Pocket. Magic Pocket splits files into blocks, replicates them for durability, and distributes them across data centers in multiple geographic regions.

Credit: youtube.com, Block vs. File Storage

Files are stored in chunks, not as a single entity. This allows for more efficient storage and retrieval of files.

Here's a breakdown of the key features of Cloud/Block Storage in Dropbox's architecture:

  • Stores chunks of files uploaded by users
  • Implemented using a distributed file system like Glusterfs or Amazon S3
  • Provides high reliability and durability
  • Files are split into blocks, replicated, and distributed across data centers

This approach enables Dropbox to handle large amounts of data and ensure that files are always available to users.

Security and Permissions

One of the primary concerns users will have while storing their files in the cloud is the privacy and security of their data. Especially since in our system users can share their files with other users or even make them public to share it with everyone.

We'll be storing permissions of each file in our metadata DB to reflect what files are visible or modifiable by any user. This ensures that users have control over who can access their files.

To handle file sharing, we'll be storing permissions in our metadata database. This way, users can easily track who has access to their files and make changes as needed.

System Design Considerations

Credit: youtube.com, System Design Interview: Design Dropbox or Google Drive w/ a Ex-Meta Staff Engineer

We should expect huge read and write volumes, which means our system needs to be able to handle a massive amount of data.

Read to write ratio is expected to be nearly the same, indicating that our system will need to optimize for both reading and writing data.

Internally, storing files in small parts or chunks (like 4MB) can provide several benefits, including the ability to retry failed operations for smaller parts of a file.

Here are some key benefits of chunking files:

  • All failed operations shall only be retried for smaller parts of a file.
  • Only the failing chunk will be retried if a user fails to upload a file.
  • We can reduce the amount of data exchange by transferring updated chunks only.
  • We can save storage space and bandwidth usage by removing duplicate chunks.

Keeping a local copy of the metadata (file name, size, etc.) with the client can save us a lot of round trips to the server.

Requirements and Goals

Our Cloud Storage system needs to meet certain requirements to be effective. Users should be able to upload and download files from any device.

To achieve this, the system must support automatic synchronization between devices, so that changes made on one device are reflected on all devices. This ensures that users have access to the latest version of their files, regardless of which device they're using.

Credit: youtube.com, Ultimate System DesignTemplate || Design Goals || Scalability

The system should also support storing large files up to 1 GB, which is a reasonable size limit for most users. This means that users won't have to worry about splitting their files into smaller parts or facing storage limitations.

ACID-ity is a crucial requirement for our system. This means that all file operations must be atomic (all or nothing), consistent (follow the rules), isolated (don't interfere with other operations), and durable (persistent even in the face of failures).

To enable offline editing, the system should allow users to add, delete, or modify files while offline. Once they come back online, all changes should be synced to the remote servers and other online devices.

Here are the top-level requirements for our system:

  • Users can upload and download files from any device.
  • Users can share files or folders with other users.
  • The system supports automatic synchronization between devices.
  • The system supports storing large files up to 1 GB.
  • ACID-ity is required for all file operations.
  • The system supports offline editing.
  • The system supports snapshotting of data, so users can go back to any version of their files.

Some Considerations

We should expect huge read and write volumes, so our system needs to be designed to handle this massive amount of data.

Read to write ratio is expected to be nearly the same, which means we can't just focus on one aspect of the system.

Credit: youtube.com, System Design Considerations

Internally, files can be stored in small parts or chunks, which provides a lot of benefits. This approach allows us to retry failed operations for smaller parts of a file, reducing the impact of errors.

By storing files in chunks, we can reduce the amount of data exchange by transferring only updated chunks. This not only saves bandwidth but also reduces the load on the system.

We can also save storage space and bandwidth usage by removing duplicate chunks. This is a simple yet effective way to optimize our system's performance.

Keeping a local copy of the metadata (file name, size, etc.) with the client can save us a lot of round trips to the server. This is a small tweak that can make a big difference in our system's efficiency.

For small changes, clients can intelligently upload the diffs instead of the whole chunk. This approach reduces the amount of data transferred and makes our system more scalable.

Rosemary Boyer

Writer

Rosemary Boyer is a skilled writer with a passion for crafting engaging and informative content. With a focus on technical and educational topics, she has established herself as a reliable voice in the industry. Her writing has been featured in a variety of publications, covering subjects such as CSS Precedence, where she breaks down complex concepts into clear and concise language.

Love What You Read? Stay Updated!

Join our community for insights, tips, and more.