parent
7e9b9b265d
commit
0889f04f0d
|
@ -1,6 +1,6 @@
|
||||||
# Design Mint.com
|
# Design Mint.com
|
||||||
|
|
||||||
*Note: This document links directly to relevant areas found in the [system design topics](https://github.com/donnemartin/system-design-primer-interview#index-of-system-design-topics-1) to avoid duplication. Refer to the linked content for general talking points, tradeoffs, and alternatives.*
|
*Note: This document links directly to relevant areas found in the [system design topics](https://github.com/donnemartin/system-design-primer#index-of-system-design-topics) to avoid duplication. Refer to the linked content for general talking points, tradeoffs, and alternatives.*
|
||||||
|
|
||||||
## Step 1: Outline use cases and constraints
|
## Step 1: Outline use cases and constraints
|
||||||
|
|
||||||
|
@ -88,9 +88,9 @@ Handy conversion guide:
|
||||||
|
|
||||||
### Use case: User connects to a financial account
|
### Use case: User connects to a financial account
|
||||||
|
|
||||||
We could store info on the 10 million users in a [relational database](https://github.com/donnemartin/system-design-primer-interview#relational-database-management-system-rdbms). We should discuss the [use cases and tradeoffs between choosing SQL or NoSQL](https://github.com/donnemartin/system-design-primer-interview#sql-or-nosql).
|
We could store info on the 10 million users in a [relational database](https://github.com/donnemartin/system-design-primer#relational-database-management-system-rdbms). We should discuss the [use cases and tradeoffs between choosing SQL or NoSQL](https://github.com/donnemartin/system-design-primer#sql-or-nosql).
|
||||||
|
|
||||||
* The **Client** sends a request to the **Web Server**, running as a [reverse proxy](https://github.com/donnemartin/system-design-primer-interview#reverse-proxy-web-server)
|
* The **Client** sends a request to the **Web Server**, running as a [reverse proxy](https://github.com/donnemartin/system-design-primer#reverse-proxy-web-server)
|
||||||
* The **Web Server** forwards the request to the **Accounts API** server
|
* The **Web Server** forwards the request to the **Accounts API** server
|
||||||
* The **Accounts API** server updates the **SQL Database** `accounts` table with the newly entered account info
|
* The **Accounts API** server updates the **SQL Database** `accounts` table with the newly entered account info
|
||||||
|
|
||||||
|
@ -110,9 +110,9 @@ PRIMARY KEY(id)
|
||||||
FOREIGN KEY(user_id) REFERENCES users(id)
|
FOREIGN KEY(user_id) REFERENCES users(id)
|
||||||
```
|
```
|
||||||
|
|
||||||
We'll create an [index](https://github.com/donnemartin/system-design-primer-interview#use-good-indices) on `id`, `user_id `, and `created_at` to speed up lookups (log-time instead of scanning the entire table) and to keep the data in memory. Reading 1 MB sequentially from memory takes about 250 microseconds, while reading from SSD takes 4x and from disk takes 80x longer.<sup><a href=https://github.com/donnemartin/system-design-primer-interview#latency-numbers-every-programmer-should-know>1</a></sup>
|
We'll create an [index](https://github.com/donnemartin/system-design-primer#use-good-indices) on `id`, `user_id `, and `created_at` to speed up lookups (log-time instead of scanning the entire table) and to keep the data in memory. Reading 1 MB sequentially from memory takes about 250 microseconds, while reading from SSD takes 4x and from disk takes 80x longer.<sup><a href=https://github.com/donnemartin/system-design-primer#latency-numbers-every-programmer-should-know>1</a></sup>
|
||||||
|
|
||||||
We'll use a public [**REST API**](https://github.com/donnemartin/system-design-primer-interview##representational-state-transfer-rest):
|
We'll use a public [**REST API**](https://github.com/donnemartin/system-design-primer#representational-state-transfer-rest):
|
||||||
|
|
||||||
```
|
```
|
||||||
$ curl -X POST --data '{ "user_id": "foo", "account_url": "bar", \
|
$ curl -X POST --data '{ "user_id": "foo", "account_url": "bar", \
|
||||||
|
@ -120,7 +120,7 @@ $ curl -X POST --data '{ "user_id": "foo", "account_url": "bar", \
|
||||||
https://mint.com/api/v1/account
|
https://mint.com/api/v1/account
|
||||||
```
|
```
|
||||||
|
|
||||||
For internal communications, we could use [Remote Procedure Calls](https://github.com/donnemartin/system-design-primer-interview#remote-procedure-call-rpc).
|
For internal communications, we could use [Remote Procedure Calls](https://github.com/donnemartin/system-design-primer#remote-procedure-call-rpc).
|
||||||
|
|
||||||
Next, the service extracts transactions from the account.
|
Next, the service extracts transactions from the account.
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ Data flow:
|
||||||
* The **Client** sends a request to the **Web Server**
|
* The **Client** sends a request to the **Web Server**
|
||||||
* The **Web Server** forwards the request to the **Accounts API** server
|
* The **Web Server** forwards the request to the **Accounts API** server
|
||||||
* The **Accounts API** server places a job on a **Queue** such as Amazon SQS or [RabbitMQ](https://www.rabbitmq.com/)
|
* The **Accounts API** server places a job on a **Queue** such as Amazon SQS or [RabbitMQ](https://www.rabbitmq.com/)
|
||||||
* Extracting transactions could take awhile, we'd probably want to do this [asynchronously with a queue](https://github.com/donnemartin/system-design-primer-interview#asynchronism), although this introduces additional complexity
|
* Extracting transactions could take awhile, we'd probably want to do this [asynchronously with a queue](https://github.com/donnemartin/system-design-primer#asynchronism), although this introduces additional complexity
|
||||||
* The **Transaction Extraction Service** does the following:
|
* The **Transaction Extraction Service** does the following:
|
||||||
* Pulls from the **Queue** and extracts transactions for the given account from the financial institution, storing the results as raw log files in the **Object Store**
|
* Pulls from the **Queue** and extracts transactions for the given account from the financial institution, storing the results as raw log files in the **Object Store**
|
||||||
* Uses the **Category Service** to categorize each transaction
|
* Uses the **Category Service** to categorize each transaction
|
||||||
|
@ -160,7 +160,7 @@ PRIMARY KEY(id)
|
||||||
FOREIGN KEY(user_id) REFERENCES users(id)
|
FOREIGN KEY(user_id) REFERENCES users(id)
|
||||||
```
|
```
|
||||||
|
|
||||||
We'll create an [index](https://github.com/donnemartin/system-design-primer-interview#use-good-indices) on `id`, `user_id `, and `created_at`.
|
We'll create an [index](https://github.com/donnemartin/system-design-primer#use-good-indices) on `id`, `user_id `, and `created_at`.
|
||||||
|
|
||||||
The `monthly_spending` table could have the following structure:
|
The `monthly_spending` table could have the following structure:
|
||||||
|
|
||||||
|
@ -174,7 +174,7 @@ PRIMARY KEY(id)
|
||||||
FOREIGN KEY(user_id) REFERENCES users(id)
|
FOREIGN KEY(user_id) REFERENCES users(id)
|
||||||
```
|
```
|
||||||
|
|
||||||
We'll create an [index](https://github.com/donnemartin/system-design-primer-interview#use-good-indices) on `id` and `user_id `.
|
We'll create an [index](https://github.com/donnemartin/system-design-primer#use-good-indices) on `id` and `user_id `.
|
||||||
|
|
||||||
#### Category service
|
#### Category service
|
||||||
|
|
||||||
|
@ -331,27 +331,27 @@ class SpendingByCategory(MRJob):
|
||||||
|
|
||||||
**Important: Do not simply jump right into the final design from the initial design!**
|
**Important: Do not simply jump right into the final design from the initial design!**
|
||||||
|
|
||||||
State you would 1) **Benchmark/Load Test**, 2) **Profile** for bottlenecks 3) address bottlenecks while evaluating alternatives and trade-offs, and 4) repeat. See [Design a system that scales to millions of users on AWS]() as a sample on how to iteratively scale the initial design.
|
State you would 1) **Benchmark/Load Test**, 2) **Profile** for bottlenecks 3) address bottlenecks while evaluating alternatives and trade-offs, and 4) repeat. See [Design a system that scales to millions of users on AWS](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/scaling_aws/README.md) as a sample on how to iteratively scale the initial design.
|
||||||
|
|
||||||
It's important to discuss what bottlenecks you might encounter with the initial design and how you might address each of them. For example, what issues are addressed by adding a **Load Balancer** with multiple **Web Servers**? **CDN**? **Master-Slave Replicas**? What are the alternatives and **Trade-Offs** for each?
|
It's important to discuss what bottlenecks you might encounter with the initial design and how you might address each of them. For example, what issues are addressed by adding a **Load Balancer** with multiple **Web Servers**? **CDN**? **Master-Slave Replicas**? What are the alternatives and **Trade-Offs** for each?
|
||||||
|
|
||||||
We'll introduce some components to complete the design and to address scalability issues. Internal load balancers are not shown to reduce clutter.
|
We'll introduce some components to complete the design and to address scalability issues. Internal load balancers are not shown to reduce clutter.
|
||||||
|
|
||||||
*To avoid repeating discussions*, refer to the following [system design topics](https://github.com/donnemartin/system-design-primer-interview#) for main talking points, tradeoffs, and alternatives:
|
*To avoid repeating discussions*, refer to the following [system design topics](https://github.com/donnemartin/system-design-primer#index-of-system-design-topics) for main talking points, tradeoffs, and alternatives:
|
||||||
|
|
||||||
* [DNS](https://github.com/donnemartin/system-design-primer-interview#domain-name-system)
|
* [DNS](https://github.com/donnemartin/system-design-primer#domain-name-system)
|
||||||
* [CDN](https://github.com/donnemartin/system-design-primer-interview#content-delivery-network)
|
* [CDN](https://github.com/donnemartin/system-design-primer#content-delivery-network)
|
||||||
* [Load balancer](https://github.com/donnemartin/system-design-primer-interview#load-balancer)
|
* [Load balancer](https://github.com/donnemartin/system-design-primer#load-balancer)
|
||||||
* [Horizontal scaling](https://github.com/donnemartin/system-design-primer-interview#horizontal-scaling)
|
* [Horizontal scaling](https://github.com/donnemartin/system-design-primer#horizontal-scaling)
|
||||||
* [Web server (reverse proxy)](https://github.com/donnemartin/system-design-primer-interview#reverse-proxy-web-server)
|
* [Web server (reverse proxy)](https://github.com/donnemartin/system-design-primer#reverse-proxy-web-server)
|
||||||
* [API server (application layer)](https://github.com/donnemartin/system-design-primer-interview#application-layer)
|
* [API server (application layer)](https://github.com/donnemartin/system-design-primer#application-layer)
|
||||||
* [Cache](https://github.com/donnemartin/system-design-primer-interview#cache)
|
* [Cache](https://github.com/donnemartin/system-design-primer#cache)
|
||||||
* [Relational database management system (RDBMS)](https://github.com/donnemartin/system-design-primer-interview#relational-database-management-system-rdbms)
|
* [Relational database management system (RDBMS)](https://github.com/donnemartin/system-design-primer#relational-database-management-system-rdbms)
|
||||||
* [SQL write master-slave failover](https://github.com/donnemartin/system-design-primer-interview#fail-over)
|
* [SQL write master-slave failover](https://github.com/donnemartin/system-design-primer#fail-over)
|
||||||
* [Master-slave replication](https://github.com/donnemartin/system-design-primer-interview#master-slave-replication)
|
* [Master-slave replication](https://github.com/donnemartin/system-design-primer#master-slave-replication)
|
||||||
* [Asynchronism](https://github.com/donnemartin/system-design-primer-interview#aysnchronism)
|
* [Asynchronism](https://github.com/donnemartin/system-design-primer#aysnchronism)
|
||||||
* [Consistency patterns](https://github.com/donnemartin/system-design-primer-interview#consistency-patterns)
|
* [Consistency patterns](https://github.com/donnemartin/system-design-primer#consistency-patterns)
|
||||||
* [Availability patterns](https://github.com/donnemartin/system-design-primer-interview#availability-patterns)
|
* [Availability patterns](https://github.com/donnemartin/system-design-primer#availability-patterns)
|
||||||
|
|
||||||
We'll add an additional use case: **User** accesses summaries and transactions.
|
We'll add an additional use case: **User** accesses summaries and transactions.
|
||||||
|
|
||||||
|
@ -367,7 +367,7 @@ User sessions, aggregate stats by category, and recent transactions could be pla
|
||||||
* If the url is in the **SQL Database**, fetches the contents
|
* If the url is in the **SQL Database**, fetches the contents
|
||||||
* Updates the **Memory Cache** with the contents
|
* Updates the **Memory Cache** with the contents
|
||||||
|
|
||||||
Refer to [When to update the cache](https://github.com/donnemartin/system-design-primer-interview#when-to-update-the-cache) for tradeoffs and alternatives. The approach above describes [cache-aside](https://github.com/donnemartin/system-design-primer-interview#cache-aside).
|
Refer to [When to update the cache](https://github.com/donnemartin/system-design-primer#when-to-update-the-cache) for tradeoffs and alternatives. The approach above describes [cache-aside](https://github.com/donnemartin/system-design-primer#cache-aside).
|
||||||
|
|
||||||
Instead of keeping the `monthly_spending` aggregate table in the **SQL Database**, we could create a separate **Analytics Database** using a data warehousing solution such as Amazon Redshift or Google BigQuery.
|
Instead of keeping the `monthly_spending` aggregate table in the **SQL Database**, we could create a separate **Analytics Database** using a data warehousing solution such as Amazon Redshift or Google BigQuery.
|
||||||
|
|
||||||
|
@ -377,10 +377,10 @@ To address the 2,000 *average* read requests per second (higher at peak), traffi
|
||||||
|
|
||||||
200 *average* transaction writes per second (higher at peak) might be tough for a single **SQL Write Master-Slave**. We might need to employ additional SQL scaling patterns:
|
200 *average* transaction writes per second (higher at peak) might be tough for a single **SQL Write Master-Slave**. We might need to employ additional SQL scaling patterns:
|
||||||
|
|
||||||
* [Federation](https://github.com/donnemartin/system-design-primer-interview#federation)
|
* [Federation](https://github.com/donnemartin/system-design-primer#federation)
|
||||||
* [Sharding](https://github.com/donnemartin/system-design-primer-interview#sharding)
|
* [Sharding](https://github.com/donnemartin/system-design-primer#sharding)
|
||||||
* [Denormalization](https://github.com/donnemartin/system-design-primer-interview#denormalization)
|
* [Denormalization](https://github.com/donnemartin/system-design-primer#denormalization)
|
||||||
* [SQL Tuning](https://github.com/donnemartin/system-design-primer-interview#sql-tuning)
|
* [SQL Tuning](https://github.com/donnemartin/system-design-primer#sql-tuning)
|
||||||
|
|
||||||
We should also consider moving some data to a **NoSQL Database**.
|
We should also consider moving some data to a **NoSQL Database**.
|
||||||
|
|
||||||
|
@ -390,50 +390,50 @@ We should also consider moving some data to a **NoSQL Database**.
|
||||||
|
|
||||||
#### NoSQL
|
#### NoSQL
|
||||||
|
|
||||||
* [Key-value store](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Key-value store](https://github.com/donnemartin/system-design-primer#key-value-store)
|
||||||
* [Document store](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Document store](https://github.com/donnemartin/system-design-primer#document-store)
|
||||||
* [Wide column store](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Wide column store](https://github.com/donnemartin/system-design-primer#wide-column-store)
|
||||||
* [Graph database](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Graph database](https://github.com/donnemartin/system-design-primer#graph-database)
|
||||||
* [SQL vs NoSQL](https://github.com/donnemartin/system-design-primer-interview#)
|
* [SQL vs NoSQL](https://github.com/donnemartin/system-design-primer#sql-or-nosql)
|
||||||
|
|
||||||
### Caching
|
### Caching
|
||||||
|
|
||||||
* Where to cache
|
* Where to cache
|
||||||
* [Client caching](https://github.com/donnemartin/system-design-primer-interview#client-caching)
|
* [Client caching](https://github.com/donnemartin/system-design-primer#client-caching)
|
||||||
* [CDN caching](https://github.com/donnemartin/system-design-primer-interview#cdn-caching)
|
* [CDN caching](https://github.com/donnemartin/system-design-primer#cdn-caching)
|
||||||
* [Web server caching](https://github.com/donnemartin/system-design-primer-interview#web-server-caching)
|
* [Web server caching](https://github.com/donnemartin/system-design-primer#web-server-caching)
|
||||||
* [Database caching](https://github.com/donnemartin/system-design-primer-interview#database-caching)
|
* [Database caching](https://github.com/donnemartin/system-design-primer#database-caching)
|
||||||
* [Application caching](https://github.com/donnemartin/system-design-primer-interview#application-caching)
|
* [Application caching](https://github.com/donnemartin/system-design-primer#application-caching)
|
||||||
* What to cache
|
* What to cache
|
||||||
* [Caching at the database query level](https://github.com/donnemartin/system-design-primer-interview#caching-at-the-database-query-level)
|
* [Caching at the database query level](https://github.com/donnemartin/system-design-primer#caching-at-the-database-query-level)
|
||||||
* [Caching at the object level](https://github.com/donnemartin/system-design-primer-interview#caching-at-the-object-level)
|
* [Caching at the object level](https://github.com/donnemartin/system-design-primer#caching-at-the-object-level)
|
||||||
* When to update the cache
|
* When to update the cache
|
||||||
* [Cache-aside](https://github.com/donnemartin/system-design-primer-interview#cache-aside)
|
* [Cache-aside](https://github.com/donnemartin/system-design-primer#cache-aside)
|
||||||
* [Write-through](https://github.com/donnemartin/system-design-primer-interview#write-through)
|
* [Write-through](https://github.com/donnemartin/system-design-primer#write-through)
|
||||||
* [Write-behind (write-back)](https://github.com/donnemartin/system-design-primer-interview#write-behind-write-back)
|
* [Write-behind (write-back)](https://github.com/donnemartin/system-design-primer#write-behind-write-back)
|
||||||
* [Refresh ahead](https://github.com/donnemartin/system-design-primer-interview#refresh-ahead)
|
* [Refresh ahead](https://github.com/donnemartin/system-design-primer#refresh-ahead)
|
||||||
|
|
||||||
### Asynchronism and microservices
|
### Asynchronism and microservices
|
||||||
|
|
||||||
* [Message queues](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Message queues](https://github.com/donnemartin/system-design-primer#message-queues)
|
||||||
* [Task queues](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Task queues](https://github.com/donnemartin/system-design-primer#task-queues)
|
||||||
* [Back pressure](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Back pressure](https://github.com/donnemartin/system-design-primer#back-pressure)
|
||||||
* [Microservices](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Microservices](https://github.com/donnemartin/system-design-primer#microservices)
|
||||||
|
|
||||||
### Communications
|
### Communications
|
||||||
|
|
||||||
* Discuss tradeoffs:
|
* Discuss tradeoffs:
|
||||||
* External communication with clients - [HTTP APIs following REST](https://github.com/donnemartin/system-design-primer-interview#representational-state-transfer-rest)
|
* External communication with clients - [HTTP APIs following REST](https://github.com/donnemartin/system-design-primer#representational-state-transfer-rest)
|
||||||
* Internal communications - [RPC](https://github.com/donnemartin/system-design-primer-interview#remote-procedure-call-rpc)
|
* Internal communications - [RPC](https://github.com/donnemartin/system-design-primer#remote-procedure-call-rpc)
|
||||||
* [Service discovery](https://github.com/donnemartin/system-design-primer-interview#service-discovery)
|
* [Service discovery](https://github.com/donnemartin/system-design-primer#service-discovery)
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
||||||
Refer to the [security section](https://github.com/donnemartin/system-design-primer-interview#security).
|
Refer to the [security section](https://github.com/donnemartin/system-design-primer#security).
|
||||||
|
|
||||||
### Latency numbers
|
### Latency numbers
|
||||||
|
|
||||||
See [Latency numbers every programmer should know](https://github.com/donnemartin/system-design-primer-interview#latency-numbers-every-programmer-should-know).
|
See [Latency numbers every programmer should know](https://github.com/donnemartin/system-design-primer#latency-numbers-every-programmer-should-know).
|
||||||
|
|
||||||
### Ongoing
|
### Ongoing
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Design Pastebin.com (or Bit.ly)
|
# Design Pastebin.com (or Bit.ly)
|
||||||
|
|
||||||
*Note: This document links directly to relevant areas found in the [system design topics](https://github.com/donnemartin/system-design-primer-interview#index-of-system-design-topics-1) to avoid duplication. Refer to the linked content for general talking points, tradeoffs, and alternatives.*
|
*Note: This document links directly to relevant areas found in the [system design topics](https://github.com/donnemartin/system-design-primer#index-of-system-design-topics) to avoid duplication. Refer to the linked content for general talking points, tradeoffs, and alternatives.*
|
||||||
|
|
||||||
**Design Bit.ly** - is a similar question, except pastebin requires storing the paste contents instead of the original unshortened url.
|
**Design Bit.ly** - is a similar question, except pastebin requires storing the paste contents instead of the original unshortened url.
|
||||||
|
|
||||||
|
@ -87,13 +87,13 @@ Handy conversion guide:
|
||||||
|
|
||||||
### Use case: User enters a block of text and gets a randomly generated link
|
### Use case: User enters a block of text and gets a randomly generated link
|
||||||
|
|
||||||
We could use a [relational database](https://github.com/donnemartin/system-design-primer-interview#relational-database-management-system-rdbms) as a large hash table, mapping the generated url to a file server and path containing the paste file.
|
We could use a [relational database](https://github.com/donnemartin/system-design-primer#relational-database-management-system-rdbms) as a large hash table, mapping the generated url to a file server and path containing the paste file.
|
||||||
|
|
||||||
Instead of managing a file server, we could use a managed **Object Store** such as Amazon S3 or a [NoSQL document store](https://github.com/donnemartin/system-design-primer-interview#document-store).
|
Instead of managing a file server, we could use a managed **Object Store** such as Amazon S3 or a [NoSQL document store](https://github.com/donnemartin/system-design-primer#document-store).
|
||||||
|
|
||||||
An alternative to a relational database acting as a large hash table, we could use a [NoSQL key-value store](https://github.com/donnemartin/system-design-primer-interview#key-value-store). We should discuss the [tradeoffs between choosing SQL or NoSQL](https://github.com/donnemartin/system-design-primer-interview#sql-or-nosql). The following discussion uses the relational database approach.
|
An alternative to a relational database acting as a large hash table, we could use a [NoSQL key-value store](https://github.com/donnemartin/system-design-primer#key-value-store). We should discuss the [tradeoffs between choosing SQL or NoSQL](https://github.com/donnemartin/system-design-primer#sql-or-nosql). The following discussion uses the relational database approach.
|
||||||
|
|
||||||
* The **Client** sends a create paste request to the **Web Server**, running as a [reverse proxy](https://github.com/donnemartin/system-design-primer-interview#reverse-proxy-web-server)
|
* The **Client** sends a create paste request to the **Web Server**, running as a [reverse proxy](https://github.com/donnemartin/system-design-primer#reverse-proxy-web-server)
|
||||||
* The **Web Server** forwards the request to the **Write API** server
|
* The **Web Server** forwards the request to the **Write API** server
|
||||||
* The **Write API** server does does the following:
|
* The **Write API** server does does the following:
|
||||||
* Generates a unique url
|
* Generates a unique url
|
||||||
|
@ -116,7 +116,7 @@ paste_path varchar(255) NOT NULL
|
||||||
PRIMARY KEY(shortlink)
|
PRIMARY KEY(shortlink)
|
||||||
```
|
```
|
||||||
|
|
||||||
We'll create an [index](https://github.com/donnemartin/system-design-primer-interview#use-good-indices) on `shortlink ` and `created_at` to speed up lookups (log-time instead of scanning the entire table) and to keep the data in memory. Reading 1 MB sequentially from memory takes about 250 microseconds, while reading from SSD takes 4x and from disk takes 80x longer.<sup><a href=https://github.com/donnemartin/system-design-primer-interview#latency-numbers-every-programmer-should-know>1</a></sup>
|
We'll create an [index](https://github.com/donnemartin/system-design-primer#use-good-indices) on `shortlink ` and `created_at` to speed up lookups (log-time instead of scanning the entire table) and to keep the data in memory. Reading 1 MB sequentially from memory takes about 250 microseconds, while reading from SSD takes 4x and from disk takes 80x longer.<sup><a href=https://github.com/donnemartin/system-design-primer#latency-numbers-every-programmer-should-know>1</a></sup>
|
||||||
|
|
||||||
To generate the unique url, we could:
|
To generate the unique url, we could:
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ def base_encode(num, base=62):
|
||||||
url = base_encode(md5(ip_address+timestamp))[:URL_LENGTH]
|
url = base_encode(md5(ip_address+timestamp))[:URL_LENGTH]
|
||||||
```
|
```
|
||||||
|
|
||||||
We'll use a public [**REST API**](https://github.com/donnemartin/system-design-primer-interview##representational-state-transfer-rest):
|
We'll use a public [**REST API**](https://github.com/donnemartin/system-design-primer#representational-state-transfer-rest):
|
||||||
|
|
||||||
```
|
```
|
||||||
$ curl -X POST --data '{ "expiration_length_in_minutes": "60", \
|
$ curl -X POST --data '{ "expiration_length_in_minutes": "60", \
|
||||||
|
@ -161,7 +161,7 @@ Response:
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
For internal communications, we could use [Remote Procedure Calls](https://github.com/donnemartin/system-design-primer-interview#remote-procedure-call-rpc).
|
For internal communications, we could use [Remote Procedure Calls](https://github.com/donnemartin/system-design-primer#remote-procedure-call-rpc).
|
||||||
|
|
||||||
### Use case: User enters a paste's url and views the contents
|
### Use case: User enters a paste's url and views the contents
|
||||||
|
|
||||||
|
@ -239,26 +239,26 @@ To delete expired pastes, we could just scan the **SQL Database** for all entrie
|
||||||
|
|
||||||
**Important: Do not simply jump right into the final design from the initial design!**
|
**Important: Do not simply jump right into the final design from the initial design!**
|
||||||
|
|
||||||
State you would do this iteratively: 1) **Benchmark/Load Test**, 2) **Profile** for bottlenecks 3) address bottlenecks while evaluating alternatives and trade-offs, and 4) repeat. See [Design a system that scales to millions of users on AWS]() as a sample on how to iteratively scale the initial design.
|
State you would do this iteratively: 1) **Benchmark/Load Test**, 2) **Profile** for bottlenecks 3) address bottlenecks while evaluating alternatives and trade-offs, and 4) repeat. See [Design a system that scales to millions of users on AWS](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/scaling_aws/README.md) as a sample on how to iteratively scale the initial design.
|
||||||
|
|
||||||
It's important to discuss what bottlenecks you might encounter with the initial design and how you might address each of them. For example, what issues are addressed by adding a **Load Balancer** with multiple **Web Servers**? **CDN**? **Master-Slave Replicas**? What are the alternatives and **Trade-Offs** for each?
|
It's important to discuss what bottlenecks you might encounter with the initial design and how you might address each of them. For example, what issues are addressed by adding a **Load Balancer** with multiple **Web Servers**? **CDN**? **Master-Slave Replicas**? What are the alternatives and **Trade-Offs** for each?
|
||||||
|
|
||||||
We'll introduce some components to complete the design and to address scalability issues. Internal load balancers are not shown to reduce clutter.
|
We'll introduce some components to complete the design and to address scalability issues. Internal load balancers are not shown to reduce clutter.
|
||||||
|
|
||||||
*To avoid repeating discussions*, refer to the following [system design topics](https://github.com/donnemartin/system-design-primer-interview#) for main talking points, tradeoffs, and alternatives:
|
*To avoid repeating discussions*, refer to the following [system design topics](https://github.com/donnemartin/system-design-primer#index-of-system-design-topics) for main talking points, tradeoffs, and alternatives:
|
||||||
|
|
||||||
* [DNS](https://github.com/donnemartin/system-design-primer-interview#domain-name-system)
|
* [DNS](https://github.com/donnemartin/system-design-primer#domain-name-system)
|
||||||
* [CDN](https://github.com/donnemartin/system-design-primer-interview#content-delivery-network)
|
* [CDN](https://github.com/donnemartin/system-design-primer#content-delivery-network)
|
||||||
* [Load balancer](https://github.com/donnemartin/system-design-primer-interview#load-balancer)
|
* [Load balancer](https://github.com/donnemartin/system-design-primer#load-balancer)
|
||||||
* [Horizontal scaling](https://github.com/donnemartin/system-design-primer-interview#horizontal-scaling)
|
* [Horizontal scaling](https://github.com/donnemartin/system-design-primer#horizontal-scaling)
|
||||||
* [Web server (reverse proxy)](https://github.com/donnemartin/system-design-primer-interview#reverse-proxy-web-server)
|
* [Web server (reverse proxy)](https://github.com/donnemartin/system-design-primer#reverse-proxy-web-server)
|
||||||
* [API server (application layer)](https://github.com/donnemartin/system-design-primer-interview#application-layer)
|
* [API server (application layer)](https://github.com/donnemartin/system-design-primer#application-layer)
|
||||||
* [Cache](https://github.com/donnemartin/system-design-primer-interview#cache)
|
* [Cache](https://github.com/donnemartin/system-design-primer#cache)
|
||||||
* [Relational database management system (RDBMS)](https://github.com/donnemartin/system-design-primer-interview#relational-database-management-system-rdbms)
|
* [Relational database management system (RDBMS)](https://github.com/donnemartin/system-design-primer#relational-database-management-system-rdbms)
|
||||||
* [SQL write master-slave failover](https://github.com/donnemartin/system-design-primer-interview#fail-over)
|
* [SQL write master-slave failover](https://github.com/donnemartin/system-design-primer#fail-over)
|
||||||
* [Master-slave replication](https://github.com/donnemartin/system-design-primer-interview#master-slave-replication)
|
* [Master-slave replication](https://github.com/donnemartin/system-design-primer#master-slave-replication)
|
||||||
* [Consistency patterns](https://github.com/donnemartin/system-design-primer-interview#consistency-patterns)
|
* [Consistency patterns](https://github.com/donnemartin/system-design-primer#consistency-patterns)
|
||||||
* [Availability patterns](https://github.com/donnemartin/system-design-primer-interview#availability-patterns)
|
* [Availability patterns](https://github.com/donnemartin/system-design-primer#availability-patterns)
|
||||||
|
|
||||||
The **Analytics Database** could use a data warehousing solution such as Amazon Redshift or Google BigQuery.
|
The **Analytics Database** could use a data warehousing solution such as Amazon Redshift or Google BigQuery.
|
||||||
|
|
||||||
|
@ -268,10 +268,10 @@ To address the 40 *average* read requests per second (higher at peak), traffic f
|
||||||
|
|
||||||
4 *average* paste writes per second (with higher at peak) should be do-able for a single **SQL Write Master-Slave**. Otherwise, we'll need to employ additional SQL scaling patterns:
|
4 *average* paste writes per second (with higher at peak) should be do-able for a single **SQL Write Master-Slave**. Otherwise, we'll need to employ additional SQL scaling patterns:
|
||||||
|
|
||||||
* [Federation](https://github.com/donnemartin/system-design-primer-interview#federation)
|
* [Federation](https://github.com/donnemartin/system-design-primer#federation)
|
||||||
* [Sharding](https://github.com/donnemartin/system-design-primer-interview#sharding)
|
* [Sharding](https://github.com/donnemartin/system-design-primer#sharding)
|
||||||
* [Denormalization](https://github.com/donnemartin/system-design-primer-interview#denormalization)
|
* [Denormalization](https://github.com/donnemartin/system-design-primer#denormalization)
|
||||||
* [SQL Tuning](https://github.com/donnemartin/system-design-primer-interview#sql-tuning)
|
* [SQL Tuning](https://github.com/donnemartin/system-design-primer#sql-tuning)
|
||||||
|
|
||||||
We should also consider moving some data to a **NoSQL Database**.
|
We should also consider moving some data to a **NoSQL Database**.
|
||||||
|
|
||||||
|
@ -281,50 +281,50 @@ We should also consider moving some data to a **NoSQL Database**.
|
||||||
|
|
||||||
#### NoSQL
|
#### NoSQL
|
||||||
|
|
||||||
* [Key-value store](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Key-value store](https://github.com/donnemartin/system-design-primer#key-value-store)
|
||||||
* [Document store](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Document store](https://github.com/donnemartin/system-design-primer#document-store)
|
||||||
* [Wide column store](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Wide column store](https://github.com/donnemartin/system-design-primer#wide-column-store)
|
||||||
* [Graph database](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Graph database](https://github.com/donnemartin/system-design-primer#graph-database)
|
||||||
* [SQL vs NoSQL](https://github.com/donnemartin/system-design-primer-interview#)
|
* [SQL vs NoSQL](https://github.com/donnemartin/system-design-primer#sql-or-nosql)
|
||||||
|
|
||||||
### Caching
|
### Caching
|
||||||
|
|
||||||
* Where to cache
|
* Where to cache
|
||||||
* [Client caching](https://github.com/donnemartin/system-design-primer-interview#client-caching)
|
* [Client caching](https://github.com/donnemartin/system-design-primer#client-caching)
|
||||||
* [CDN caching](https://github.com/donnemartin/system-design-primer-interview#cdn-caching)
|
* [CDN caching](https://github.com/donnemartin/system-design-primer#cdn-caching)
|
||||||
* [Web server caching](https://github.com/donnemartin/system-design-primer-interview#web-server-caching)
|
* [Web server caching](https://github.com/donnemartin/system-design-primer#web-server-caching)
|
||||||
* [Database caching](https://github.com/donnemartin/system-design-primer-interview#database-caching)
|
* [Database caching](https://github.com/donnemartin/system-design-primer#database-caching)
|
||||||
* [Application caching](https://github.com/donnemartin/system-design-primer-interview#application-caching)
|
* [Application caching](https://github.com/donnemartin/system-design-primer#application-caching)
|
||||||
* What to cache
|
* What to cache
|
||||||
* [Caching at the database query level](https://github.com/donnemartin/system-design-primer-interview#caching-at-the-database-query-level)
|
* [Caching at the database query level](https://github.com/donnemartin/system-design-primer#caching-at-the-database-query-level)
|
||||||
* [Caching at the object level](https://github.com/donnemartin/system-design-primer-interview#caching-at-the-object-level)
|
* [Caching at the object level](https://github.com/donnemartin/system-design-primer#caching-at-the-object-level)
|
||||||
* When to update the cache
|
* When to update the cache
|
||||||
* [Cache-aside](https://github.com/donnemartin/system-design-primer-interview#cache-aside)
|
* [Cache-aside](https://github.com/donnemartin/system-design-primer#cache-aside)
|
||||||
* [Write-through](https://github.com/donnemartin/system-design-primer-interview#write-through)
|
* [Write-through](https://github.com/donnemartin/system-design-primer#write-through)
|
||||||
* [Write-behind (write-back)](https://github.com/donnemartin/system-design-primer-interview#write-behind-write-back)
|
* [Write-behind (write-back)](https://github.com/donnemartin/system-design-primer#write-behind-write-back)
|
||||||
* [Refresh ahead](https://github.com/donnemartin/system-design-primer-interview#refresh-ahead)
|
* [Refresh ahead](https://github.com/donnemartin/system-design-primer#refresh-ahead)
|
||||||
|
|
||||||
### Asynchronism and microservices
|
### Asynchronism and microservices
|
||||||
|
|
||||||
* [Message queues](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Message queues](https://github.com/donnemartin/system-design-primer#message-queues)
|
||||||
* [Task queues](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Task queues](https://github.com/donnemartin/system-design-primer#task-queues)
|
||||||
* [Back pressure](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Back pressure](https://github.com/donnemartin/system-design-primer#back-pressure)
|
||||||
* [Microservices](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Microservices](https://github.com/donnemartin/system-design-primer#microservices)
|
||||||
|
|
||||||
### Communications
|
### Communications
|
||||||
|
|
||||||
* Discuss tradeoffs:
|
* Discuss tradeoffs:
|
||||||
* External communication with clients - [HTTP APIs following REST](https://github.com/donnemartin/system-design-primer-interview#representational-state-transfer-rest)
|
* External communication with clients - [HTTP APIs following REST](https://github.com/donnemartin/system-design-primer#representational-state-transfer-rest)
|
||||||
* Internal communications - [RPC](https://github.com/donnemartin/system-design-primer-interview#remote-procedure-call-rpc)
|
* Internal communications - [RPC](https://github.com/donnemartin/system-design-primer#remote-procedure-call-rpc)
|
||||||
* [Service discovery](https://github.com/donnemartin/system-design-primer-interview#service-discovery)
|
* [Service discovery](https://github.com/donnemartin/system-design-primer#service-discovery)
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
||||||
Refer to the [security section](https://github.com/donnemartin/system-design-primer-interview#security).
|
Refer to the [security section](https://github.com/donnemartin/system-design-primer#security).
|
||||||
|
|
||||||
### Latency numbers
|
### Latency numbers
|
||||||
|
|
||||||
See [Latency numbers every programmer should know](https://github.com/donnemartin/system-design-primer-interview#latency-numbers-every-programmer-should-know).
|
See [Latency numbers every programmer should know](https://github.com/donnemartin/system-design-primer#latency-numbers-every-programmer-should-know).
|
||||||
|
|
||||||
### Ongoing
|
### Ongoing
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Design a key-value cache to save the results of the most recent web server queries
|
# Design a key-value cache to save the results of the most recent web server queries
|
||||||
|
|
||||||
*Note: This document links directly to relevant areas found in the [system design topics](https://github.com/donnemartin/system-design-primer-interview#index-of-system-design-topics-1) to avoid duplication. Refer to the linked content for general talking points, tradeoffs, and alternatives.*
|
*Note: This document links directly to relevant areas found in the [system design topics](https://github.com/donnemartin/system-design-primer#index-of-system-design-topics) to avoid duplication. Refer to the linked content for general talking points, tradeoffs, and alternatives.*
|
||||||
|
|
||||||
## Step 1: Outline use cases and constraints
|
## Step 1: Outline use cases and constraints
|
||||||
|
|
||||||
|
@ -66,11 +66,11 @@ Handy conversion guide:
|
||||||
|
|
||||||
### Use case: User sends a request resulting in a cache hit
|
### Use case: User sends a request resulting in a cache hit
|
||||||
|
|
||||||
Popular queries can be served from a **Memory Cache** such as Redis or Memcached to reduce read latency and to avoid overloading the **Reverse Index Service** and **Document Service**. Reading 1 MB sequentially from memory takes about 250 microseconds, while reading from SSD takes 4x and from disk takes 80x longer.<sup><a href=https://github.com/donnemartin/system-design-primer-interview#latency-numbers-every-programmer-should-know>1</a></sup>
|
Popular queries can be served from a **Memory Cache** such as Redis or Memcached to reduce read latency and to avoid overloading the **Reverse Index Service** and **Document Service**. Reading 1 MB sequentially from memory takes about 250 microseconds, while reading from SSD takes 4x and from disk takes 80x longer.<sup><a href=https://github.com/donnemartin/system-design-primer#latency-numbers-every-programmer-should-know>1</a></sup>
|
||||||
|
|
||||||
Since the cache has limited capacity, we'll use a least recently used (LRU) approach to expire older entries.
|
Since the cache has limited capacity, we'll use a least recently used (LRU) approach to expire older entries.
|
||||||
|
|
||||||
* The **Client** sends a request to the **Web Server**, running as a [reverse proxy](https://github.com/donnemartin/system-design-primer-interview#reverse-proxy-web-server)
|
* The **Client** sends a request to the **Web Server**, running as a [reverse proxy](https://github.com/donnemartin/system-design-primer#reverse-proxy-web-server)
|
||||||
* The **Web Server** forwards the request to the **Query API** server
|
* The **Web Server** forwards the request to the **Query API** server
|
||||||
* The **Query API** server does the following:
|
* The **Query API** server does the following:
|
||||||
* Parses the query
|
* Parses the query
|
||||||
|
@ -206,7 +206,7 @@ The cache should be updated when:
|
||||||
|
|
||||||
The most straightforward way to handle these cases is to simply set a max time that a cached entry can stay in the cache before it is updated, usually referred to as time to live (TTL).
|
The most straightforward way to handle these cases is to simply set a max time that a cached entry can stay in the cache before it is updated, usually referred to as time to live (TTL).
|
||||||
|
|
||||||
Refer to [When to update the cache](https://github.com/donnemartin/system-design-primer-interview#when-to-update-the-cache) for tradeoffs and alternatives. The approach above describes [cache-aside](https://github.com/donnemartin/system-design-primer-interview#cache-aside).
|
Refer to [When to update the cache](https://github.com/donnemartin/system-design-primer#when-to-update-the-cache) for tradeoffs and alternatives. The approach above describes [cache-aside](https://github.com/donnemartin/system-design-primer#cache-aside).
|
||||||
|
|
||||||
## Step 4: Scale the design
|
## Step 4: Scale the design
|
||||||
|
|
||||||
|
@ -216,22 +216,22 @@ Refer to [When to update the cache](https://github.com/donnemartin/system-design
|
||||||
|
|
||||||
**Important: Do not simply jump right into the final design from the initial design!**
|
**Important: Do not simply jump right into the final design from the initial design!**
|
||||||
|
|
||||||
State you would 1) **Benchmark/Load Test**, 2) **Profile** for bottlenecks 3) address bottlenecks while evaluating alternatives and trade-offs, and 4) repeat. See [Design a system that scales to millions of users on AWS]() as a sample on how to iteratively scale the initial design.
|
State you would 1) **Benchmark/Load Test**, 2) **Profile** for bottlenecks 3) address bottlenecks while evaluating alternatives and trade-offs, and 4) repeat. See [Design a system that scales to millions of users on AWS](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/scaling_aws/README.md) as a sample on how to iteratively scale the initial design.
|
||||||
|
|
||||||
It's important to discuss what bottlenecks you might encounter with the initial design and how you might address each of them. For example, what issues are addressed by adding a **Load Balancer** with multiple **Web Servers**? **CDN**? **Master-Slave Replicas**? What are the alternatives and **Trade-Offs** for each?
|
It's important to discuss what bottlenecks you might encounter with the initial design and how you might address each of them. For example, what issues are addressed by adding a **Load Balancer** with multiple **Web Servers**? **CDN**? **Master-Slave Replicas**? What are the alternatives and **Trade-Offs** for each?
|
||||||
|
|
||||||
We'll introduce some components to complete the design and to address scalability issues. Internal load balancers are not shown to reduce clutter.
|
We'll introduce some components to complete the design and to address scalability issues. Internal load balancers are not shown to reduce clutter.
|
||||||
|
|
||||||
*To avoid repeating discussions*, refer to the following [system design topics](https://github.com/donnemartin/system-design-primer-interview#) for main talking points, tradeoffs, and alternatives:
|
*To avoid repeating discussions*, refer to the following [system design topics](https://github.com/donnemartin/system-design-primer#index-of-system-design-topics) for main talking points, tradeoffs, and alternatives:
|
||||||
|
|
||||||
* [DNS](https://github.com/donnemartin/system-design-primer-interview#domain-name-system)
|
* [DNS](https://github.com/donnemartin/system-design-primer#domain-name-system)
|
||||||
* [Load balancer](https://github.com/donnemartin/system-design-primer-interview#load-balancer)
|
* [Load balancer](https://github.com/donnemartin/system-design-primer#load-balancer)
|
||||||
* [Horizontal scaling](https://github.com/donnemartin/system-design-primer-interview#horizontal-scaling)
|
* [Horizontal scaling](https://github.com/donnemartin/system-design-primer#horizontal-scaling)
|
||||||
* [Web server (reverse proxy)](https://github.com/donnemartin/system-design-primer-interview#reverse-proxy-web-server)
|
* [Web server (reverse proxy)](https://github.com/donnemartin/system-design-primer#reverse-proxy-web-server)
|
||||||
* [API server (application layer)](https://github.com/donnemartin/system-design-primer-interview#application-layer)
|
* [API server (application layer)](https://github.com/donnemartin/system-design-primer#application-layer)
|
||||||
* [Cache](https://github.com/donnemartin/system-design-primer-interview#cache)
|
* [Cache](https://github.com/donnemartin/system-design-primer#cache)
|
||||||
* [Consistency patterns](https://github.com/donnemartin/system-design-primer-interview#consistency-patterns)
|
* [Consistency patterns](https://github.com/donnemartin/system-design-primer#consistency-patterns)
|
||||||
* [Availability patterns](https://github.com/donnemartin/system-design-primer-interview#availability-patterns)
|
* [Availability patterns](https://github.com/donnemartin/system-design-primer#availability-patterns)
|
||||||
|
|
||||||
### Expanding the Memory Cache to many machines
|
### Expanding the Memory Cache to many machines
|
||||||
|
|
||||||
|
@ -239,7 +239,7 @@ To handle the heavy request load and the large amount of memory needed, we'll sc
|
||||||
|
|
||||||
* **Each machine in the cache cluster has its own cache** - Simple, although it will likely result in a low cache hit rate.
|
* **Each machine in the cache cluster has its own cache** - Simple, although it will likely result in a low cache hit rate.
|
||||||
* **Each machine in the cache cluster has a copy of the cache** - Simple, although it is an inefficient use of memory.
|
* **Each machine in the cache cluster has a copy of the cache** - Simple, although it is an inefficient use of memory.
|
||||||
* **The cache is [sharded](https://github.com/donnemartin/system-design-primer-interview#sharding) across all machines in the cache cluster** - More complex, although it is likely the best option. We could use hashing to determine which machine could have the cached results of a query using `machine = hash(query)`. We'll likely want to use [consistent hashing](https://github.com/donnemartin/system-design-primer-interview#consistent-hashing).
|
* **The cache is [sharded](https://github.com/donnemartin/system-design-primer#sharding) across all machines in the cache cluster** - More complex, although it is likely the best option. We could use hashing to determine which machine could have the cached results of a query using `machine = hash(query)`. We'll likely want to use [consistent hashing](https://github.com/donnemartin/system-design-primer#under-development).
|
||||||
|
|
||||||
## Additional talking points
|
## Additional talking points
|
||||||
|
|
||||||
|
@ -247,58 +247,58 @@ To handle the heavy request load and the large amount of memory needed, we'll sc
|
||||||
|
|
||||||
### SQL scaling patterns
|
### SQL scaling patterns
|
||||||
|
|
||||||
* [Read replicas](https://github.com/donnemartin/system-design-primer-interview#master-slave)
|
* [Read replicas](https://github.com/donnemartin/system-design-primer#master-slave)
|
||||||
* [Federation](https://github.com/donnemartin/system-design-primer-interview#federation)
|
* [Federation](https://github.com/donnemartin/system-design-primer#federation)
|
||||||
* [Sharding](https://github.com/donnemartin/system-design-primer-interview#sharding)
|
* [Sharding](https://github.com/donnemartin/system-design-primer#sharding)
|
||||||
* [Denormalization](https://github.com/donnemartin/system-design-primer-interview#denormalization)
|
* [Denormalization](https://github.com/donnemartin/system-design-primer#denormalization)
|
||||||
* [SQL Tuning](https://github.com/donnemartin/system-design-primer-interview#sql-tuning)
|
* [SQL Tuning](https://github.com/donnemartin/system-design-primer#sql-tuning)
|
||||||
|
|
||||||
#### NoSQL
|
#### NoSQL
|
||||||
|
|
||||||
* [Key-value store](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Key-value store](https://github.com/donnemartin/system-design-primer#key-value-store)
|
||||||
* [Document store](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Document store](https://github.com/donnemartin/system-design-primer#document-store)
|
||||||
* [Wide column store](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Wide column store](https://github.com/donnemartin/system-design-primer#wide-column-store)
|
||||||
* [Graph database](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Graph database](https://github.com/donnemartin/system-design-primer#graph-database)
|
||||||
* [SQL vs NoSQL](https://github.com/donnemartin/system-design-primer-interview#)
|
* [SQL vs NoSQL](https://github.com/donnemartin/system-design-primer#sql-or-nosql)
|
||||||
|
|
||||||
### Caching
|
### Caching
|
||||||
|
|
||||||
* Where to cache
|
* Where to cache
|
||||||
* [Client caching](https://github.com/donnemartin/system-design-primer-interview#client-caching)
|
* [Client caching](https://github.com/donnemartin/system-design-primer#client-caching)
|
||||||
* [CDN caching](https://github.com/donnemartin/system-design-primer-interview#cdn-caching)
|
* [CDN caching](https://github.com/donnemartin/system-design-primer#cdn-caching)
|
||||||
* [Web server caching](https://github.com/donnemartin/system-design-primer-interview#web-server-caching)
|
* [Web server caching](https://github.com/donnemartin/system-design-primer#web-server-caching)
|
||||||
* [Database caching](https://github.com/donnemartin/system-design-primer-interview#database-caching)
|
* [Database caching](https://github.com/donnemartin/system-design-primer#database-caching)
|
||||||
* [Application caching](https://github.com/donnemartin/system-design-primer-interview#application-caching)
|
* [Application caching](https://github.com/donnemartin/system-design-primer#application-caching)
|
||||||
* What to cache
|
* What to cache
|
||||||
* [Caching at the database query level](https://github.com/donnemartin/system-design-primer-interview#caching-at-the-database-query-level)
|
* [Caching at the database query level](https://github.com/donnemartin/system-design-primer#caching-at-the-database-query-level)
|
||||||
* [Caching at the object level](https://github.com/donnemartin/system-design-primer-interview#caching-at-the-object-level)
|
* [Caching at the object level](https://github.com/donnemartin/system-design-primer#caching-at-the-object-level)
|
||||||
* When to update the cache
|
* When to update the cache
|
||||||
* [Cache-aside](https://github.com/donnemartin/system-design-primer-interview#cache-aside)
|
* [Cache-aside](https://github.com/donnemartin/system-design-primer#cache-aside)
|
||||||
* [Write-through](https://github.com/donnemartin/system-design-primer-interview#write-through)
|
* [Write-through](https://github.com/donnemartin/system-design-primer#write-through)
|
||||||
* [Write-behind (write-back)](https://github.com/donnemartin/system-design-primer-interview#write-behind-write-back)
|
* [Write-behind (write-back)](https://github.com/donnemartin/system-design-primer#write-behind-write-back)
|
||||||
* [Refresh ahead](https://github.com/donnemartin/system-design-primer-interview#refresh-ahead)
|
* [Refresh ahead](https://github.com/donnemartin/system-design-primer#refresh-ahead)
|
||||||
|
|
||||||
### Asynchronism and microservices
|
### Asynchronism and microservices
|
||||||
|
|
||||||
* [Message queues](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Message queues](https://github.com/donnemartin/system-design-primer#message-queues)
|
||||||
* [Task queues](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Task queues](https://github.com/donnemartin/system-design-primer#task-queues)
|
||||||
* [Back pressure](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Back pressure](https://github.com/donnemartin/system-design-primer#back-pressure)
|
||||||
* [Microservices](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Microservices](https://github.com/donnemartin/system-design-primer#microservices)
|
||||||
|
|
||||||
### Communications
|
### Communications
|
||||||
|
|
||||||
* Discuss tradeoffs:
|
* Discuss tradeoffs:
|
||||||
* External communication with clients - [HTTP APIs following REST](https://github.com/donnemartin/system-design-primer-interview#representational-state-transfer-rest)
|
* External communication with clients - [HTTP APIs following REST](https://github.com/donnemartin/system-design-primer#representational-state-transfer-rest)
|
||||||
* Internal communications - [RPC](https://github.com/donnemartin/system-design-primer-interview#remote-procedure-call-rpc)
|
* Internal communications - [RPC](https://github.com/donnemartin/system-design-primer#remote-procedure-call-rpc)
|
||||||
* [Service discovery](https://github.com/donnemartin/system-design-primer-interview#service-discovery)
|
* [Service discovery](https://github.com/donnemartin/system-design-primer#service-discovery)
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
||||||
Refer to the [security section](https://github.com/donnemartin/system-design-primer-interview#security).
|
Refer to the [security section](https://github.com/donnemartin/system-design-primer#security).
|
||||||
|
|
||||||
### Latency numbers
|
### Latency numbers
|
||||||
|
|
||||||
See [Latency numbers every programmer should know](https://github.com/donnemartin/system-design-primer-interview#latency-numbers-every-programmer-should-know).
|
See [Latency numbers every programmer should know](https://github.com/donnemartin/system-design-primer#latency-numbers-every-programmer-should-know).
|
||||||
|
|
||||||
### Ongoing
|
### Ongoing
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Design Amazon's sales rank by category feature
|
# Design Amazon's sales rank by category feature
|
||||||
|
|
||||||
*Note: This document links directly to relevant areas found in the [system design topics](https://github.com/donnemartin/system-design-primer-interview#index-of-system-design-topics-1) to avoid duplication. Refer to the linked content for general talking points, tradeoffs, and alternatives.*
|
*Note: This document links directly to relevant areas found in the [system design topics](https://github.com/donnemartin/system-design-primer#index-of-system-design-topics) to avoid duplication. Refer to the linked content for general talking points, tradeoffs, and alternatives.*
|
||||||
|
|
||||||
## Step 1: Outline use cases and constraints
|
## Step 1: Outline use cases and constraints
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ t5 product4 category1 1 5.00 5 6
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
The **Sales Rank Service** could use **MapReduce**, using the **Sales API** server log files as input and writing the results to an aggregate table `sales_rank` in a **SQL Database**. We should discuss the [use cases and tradeoffs between choosing SQL or NoSQL](https://github.com/donnemartin/system-design-primer-interview#sql-or-nosql).
|
The **Sales Rank Service** could use **MapReduce**, using the **Sales API** server log files as input and writing the results to an aggregate table `sales_rank` in a **SQL Database**. We should discuss the [use cases and tradeoffs between choosing SQL or NoSQL](https://github.com/donnemartin/system-design-primer#sql-or-nosql).
|
||||||
|
|
||||||
We'll use a multi-step **MapReduce**:
|
We'll use a multi-step **MapReduce**:
|
||||||
|
|
||||||
|
@ -196,15 +196,15 @@ FOREIGN KEY(category_id) REFERENCES Categories(id)
|
||||||
FOREIGN KEY(product_id) REFERENCES Products(id)
|
FOREIGN KEY(product_id) REFERENCES Products(id)
|
||||||
```
|
```
|
||||||
|
|
||||||
We'll create an [index](https://github.com/donnemartin/system-design-primer-interview#use-good-indices) on `id `, `category_id`, and `product_id` to speed up lookups (log-time instead of scanning the entire table) and to keep the data in memory. Reading 1 MB sequentially from memory takes about 250 microseconds, while reading from SSD takes 4x and from disk takes 80x longer.<sup><a href=https://github.com/donnemartin/system-design-primer-interview#latency-numbers-every-programmer-should-know>1</a></sup>
|
We'll create an [index](https://github.com/donnemartin/system-design-primer#use-good-indices) on `id `, `category_id`, and `product_id` to speed up lookups (log-time instead of scanning the entire table) and to keep the data in memory. Reading 1 MB sequentially from memory takes about 250 microseconds, while reading from SSD takes 4x and from disk takes 80x longer.<sup><a href=https://github.com/donnemartin/system-design-primer#latency-numbers-every-programmer-should-know>1</a></sup>
|
||||||
|
|
||||||
### Use case: User views the past week's most popular products by category
|
### Use case: User views the past week's most popular products by category
|
||||||
|
|
||||||
* The **Client** sends a request to the **Web Server**, running as a [reverse proxy](https://github.com/donnemartin/system-design-primer-interview#reverse-proxy-web-server)
|
* The **Client** sends a request to the **Web Server**, running as a [reverse proxy](https://github.com/donnemartin/system-design-primer#reverse-proxy-web-server)
|
||||||
* The **Web Server** forwards the request to the **Read API** server
|
* The **Web Server** forwards the request to the **Read API** server
|
||||||
* The **Read API** server reads from the **SQL Database** `sales_rank` table
|
* The **Read API** server reads from the **SQL Database** `sales_rank` table
|
||||||
|
|
||||||
We'll use a public [**REST API**](https://github.com/donnemartin/system-design-primer-interview##representational-state-transfer-rest):
|
We'll use a public [**REST API**](https://github.com/donnemartin/system-design-primer#representational-state-transfer-rest):
|
||||||
|
|
||||||
```
|
```
|
||||||
$ curl https://amazon.com/api/v1/popular?category_id=1234
|
$ curl https://amazon.com/api/v1/popular?category_id=1234
|
||||||
|
@ -233,7 +233,7 @@ Response:
|
||||||
},
|
},
|
||||||
```
|
```
|
||||||
|
|
||||||
For internal communications, we could use [Remote Procedure Calls](https://github.com/donnemartin/system-design-primer-interview#remote-procedure-call-rpc).
|
For internal communications, we could use [Remote Procedure Calls](https://github.com/donnemartin/system-design-primer#remote-procedure-call-rpc).
|
||||||
|
|
||||||
## Step 4: Scale the design
|
## Step 4: Scale the design
|
||||||
|
|
||||||
|
@ -243,26 +243,26 @@ For internal communications, we could use [Remote Procedure Calls](https://githu
|
||||||
|
|
||||||
**Important: Do not simply jump right into the final design from the initial design!**
|
**Important: Do not simply jump right into the final design from the initial design!**
|
||||||
|
|
||||||
State you would 1) **Benchmark/Load Test**, 2) **Profile** for bottlenecks 3) address bottlenecks while evaluating alternatives and trade-offs, and 4) repeat. See [Design a system that scales to millions of users on AWS]() as a sample on how to iteratively scale the initial design.
|
State you would 1) **Benchmark/Load Test**, 2) **Profile** for bottlenecks 3) address bottlenecks while evaluating alternatives and trade-offs, and 4) repeat. See [Design a system that scales to millions of users on AWS](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/scaling_aws/README.md) as a sample on how to iteratively scale the initial design.
|
||||||
|
|
||||||
It's important to discuss what bottlenecks you might encounter with the initial design and how you might address each of them. For example, what issues are addressed by adding a **Load Balancer** with multiple **Web Servers**? **CDN**? **Master-Slave Replicas**? What are the alternatives and **Trade-Offs** for each?
|
It's important to discuss what bottlenecks you might encounter with the initial design and how you might address each of them. For example, what issues are addressed by adding a **Load Balancer** with multiple **Web Servers**? **CDN**? **Master-Slave Replicas**? What are the alternatives and **Trade-Offs** for each?
|
||||||
|
|
||||||
We'll introduce some components to complete the design and to address scalability issues. Internal load balancers are not shown to reduce clutter.
|
We'll introduce some components to complete the design and to address scalability issues. Internal load balancers are not shown to reduce clutter.
|
||||||
|
|
||||||
*To avoid repeating discussions*, refer to the following [system design topics](https://github.com/donnemartin/system-design-primer-interview#) for main talking points, tradeoffs, and alternatives:
|
*To avoid repeating discussions*, refer to the following [system design topics](https://github.com/donnemartin/system-design-primer#index-of-system-design-topics) for main talking points, tradeoffs, and alternatives:
|
||||||
|
|
||||||
* [DNS](https://github.com/donnemartin/system-design-primer-interview#domain-name-system)
|
* [DNS](https://github.com/donnemartin/system-design-primer#domain-name-system)
|
||||||
* [CDN](https://github.com/donnemartin/system-design-primer-interview#content-delivery-network)
|
* [CDN](https://github.com/donnemartin/system-design-primer#content-delivery-network)
|
||||||
* [Load balancer](https://github.com/donnemartin/system-design-primer-interview#load-balancer)
|
* [Load balancer](https://github.com/donnemartin/system-design-primer#load-balancer)
|
||||||
* [Horizontal scaling](https://github.com/donnemartin/system-design-primer-interview#horizontal-scaling)
|
* [Horizontal scaling](https://github.com/donnemartin/system-design-primer#horizontal-scaling)
|
||||||
* [Web server (reverse proxy)](https://github.com/donnemartin/system-design-primer-interview#reverse-proxy-web-server)
|
* [Web server (reverse proxy)](https://github.com/donnemartin/system-design-primer#reverse-proxy-web-server)
|
||||||
* [API server (application layer)](https://github.com/donnemartin/system-design-primer-interview#application-layer)
|
* [API server (application layer)](https://github.com/donnemartin/system-design-primer#application-layer)
|
||||||
* [Cache](https://github.com/donnemartin/system-design-primer-interview#cache)
|
* [Cache](https://github.com/donnemartin/system-design-primer#cache)
|
||||||
* [Relational database management system (RDBMS)](https://github.com/donnemartin/system-design-primer-interview#relational-database-management-system-rdbms)
|
* [Relational database management system (RDBMS)](https://github.com/donnemartin/system-design-primer#relational-database-management-system-rdbms)
|
||||||
* [SQL write master-slave failover](https://github.com/donnemartin/system-design-primer-interview#fail-over)
|
* [SQL write master-slave failover](https://github.com/donnemartin/system-design-primer#fail-over)
|
||||||
* [Master-slave replication](https://github.com/donnemartin/system-design-primer-interview#master-slave-replication)
|
* [Master-slave replication](https://github.com/donnemartin/system-design-primer#master-slave-replication)
|
||||||
* [Consistency patterns](https://github.com/donnemartin/system-design-primer-interview#consistency-patterns)
|
* [Consistency patterns](https://github.com/donnemartin/system-design-primer#consistency-patterns)
|
||||||
* [Availability patterns](https://github.com/donnemartin/system-design-primer-interview#availability-patterns)
|
* [Availability patterns](https://github.com/donnemartin/system-design-primer#availability-patterns)
|
||||||
|
|
||||||
The **Analytics Database** could use a data warehousing solution such as Amazon Redshift or Google BigQuery.
|
The **Analytics Database** could use a data warehousing solution such as Amazon Redshift or Google BigQuery.
|
||||||
|
|
||||||
|
@ -274,10 +274,10 @@ To address the 40,000 *average* read requests per second (higher at peak), traff
|
||||||
|
|
||||||
SQL scaling patterns include:
|
SQL scaling patterns include:
|
||||||
|
|
||||||
* [Federation](https://github.com/donnemartin/system-design-primer-interview#federation)
|
* [Federation](https://github.com/donnemartin/system-design-primer#federation)
|
||||||
* [Sharding](https://github.com/donnemartin/system-design-primer-interview#sharding)
|
* [Sharding](https://github.com/donnemartin/system-design-primer#sharding)
|
||||||
* [Denormalization](https://github.com/donnemartin/system-design-primer-interview#denormalization)
|
* [Denormalization](https://github.com/donnemartin/system-design-primer#denormalization)
|
||||||
* [SQL Tuning](https://github.com/donnemartin/system-design-primer-interview#sql-tuning)
|
* [SQL Tuning](https://github.com/donnemartin/system-design-primer#sql-tuning)
|
||||||
|
|
||||||
We should also consider moving some data to a **NoSQL Database**.
|
We should also consider moving some data to a **NoSQL Database**.
|
||||||
|
|
||||||
|
@ -287,50 +287,50 @@ We should also consider moving some data to a **NoSQL Database**.
|
||||||
|
|
||||||
#### NoSQL
|
#### NoSQL
|
||||||
|
|
||||||
* [Key-value store](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Key-value store](https://github.com/donnemartin/system-design-primer#key-value-store)
|
||||||
* [Document store](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Document store](https://github.com/donnemartin/system-design-primer#document-store)
|
||||||
* [Wide column store](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Wide column store](https://github.com/donnemartin/system-design-primer#wide-column-store)
|
||||||
* [Graph database](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Graph database](https://github.com/donnemartin/system-design-primer#graph-database)
|
||||||
* [SQL vs NoSQL](https://github.com/donnemartin/system-design-primer-interview#)
|
* [SQL vs NoSQL](https://github.com/donnemartin/system-design-primer#sql-or-nosql)
|
||||||
|
|
||||||
### Caching
|
### Caching
|
||||||
|
|
||||||
* Where to cache
|
* Where to cache
|
||||||
* [Client caching](https://github.com/donnemartin/system-design-primer-interview#client-caching)
|
* [Client caching](https://github.com/donnemartin/system-design-primer#client-caching)
|
||||||
* [CDN caching](https://github.com/donnemartin/system-design-primer-interview#cdn-caching)
|
* [CDN caching](https://github.com/donnemartin/system-design-primer#cdn-caching)
|
||||||
* [Web server caching](https://github.com/donnemartin/system-design-primer-interview#web-server-caching)
|
* [Web server caching](https://github.com/donnemartin/system-design-primer#web-server-caching)
|
||||||
* [Database caching](https://github.com/donnemartin/system-design-primer-interview#database-caching)
|
* [Database caching](https://github.com/donnemartin/system-design-primer#database-caching)
|
||||||
* [Application caching](https://github.com/donnemartin/system-design-primer-interview#application-caching)
|
* [Application caching](https://github.com/donnemartin/system-design-primer#application-caching)
|
||||||
* What to cache
|
* What to cache
|
||||||
* [Caching at the database query level](https://github.com/donnemartin/system-design-primer-interview#caching-at-the-database-query-level)
|
* [Caching at the database query level](https://github.com/donnemartin/system-design-primer#caching-at-the-database-query-level)
|
||||||
* [Caching at the object level](https://github.com/donnemartin/system-design-primer-interview#caching-at-the-object-level)
|
* [Caching at the object level](https://github.com/donnemartin/system-design-primer#caching-at-the-object-level)
|
||||||
* When to update the cache
|
* When to update the cache
|
||||||
* [Cache-aside](https://github.com/donnemartin/system-design-primer-interview#cache-aside)
|
* [Cache-aside](https://github.com/donnemartin/system-design-primer#cache-aside)
|
||||||
* [Write-through](https://github.com/donnemartin/system-design-primer-interview#write-through)
|
* [Write-through](https://github.com/donnemartin/system-design-primer#write-through)
|
||||||
* [Write-behind (write-back)](https://github.com/donnemartin/system-design-primer-interview#write-behind-write-back)
|
* [Write-behind (write-back)](https://github.com/donnemartin/system-design-primer#write-behind-write-back)
|
||||||
* [Refresh ahead](https://github.com/donnemartin/system-design-primer-interview#refresh-ahead)
|
* [Refresh ahead](https://github.com/donnemartin/system-design-primer#refresh-ahead)
|
||||||
|
|
||||||
### Asynchronism and microservices
|
### Asynchronism and microservices
|
||||||
|
|
||||||
* [Message queues](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Message queues](https://github.com/donnemartin/system-design-primer#message-queues)
|
||||||
* [Task queues](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Task queues](https://github.com/donnemartin/system-design-primer#task-queues)
|
||||||
* [Back pressure](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Back pressure](https://github.com/donnemartin/system-design-primer#back-pressure)
|
||||||
* [Microservices](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Microservices](https://github.com/donnemartin/system-design-primer#microservices)
|
||||||
|
|
||||||
### Communications
|
### Communications
|
||||||
|
|
||||||
* Discuss tradeoffs:
|
* Discuss tradeoffs:
|
||||||
* External communication with clients - [HTTP APIs following REST](https://github.com/donnemartin/system-design-primer-interview#representational-state-transfer-rest)
|
* External communication with clients - [HTTP APIs following REST](https://github.com/donnemartin/system-design-primer#representational-state-transfer-rest)
|
||||||
* Internal communications - [RPC](https://github.com/donnemartin/system-design-primer-interview#remote-procedure-call-rpc)
|
* Internal communications - [RPC](https://github.com/donnemartin/system-design-primer#remote-procedure-call-rpc)
|
||||||
* [Service discovery](https://github.com/donnemartin/system-design-primer-interview#service-discovery)
|
* [Service discovery](https://github.com/donnemartin/system-design-primer#service-discovery)
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
||||||
Refer to the [security section](https://github.com/donnemartin/system-design-primer-interview#security).
|
Refer to the [security section](https://github.com/donnemartin/system-design-primer#security).
|
||||||
|
|
||||||
### Latency numbers
|
### Latency numbers
|
||||||
|
|
||||||
See [Latency numbers every programmer should know](https://github.com/donnemartin/system-design-primer-interview#latency-numbers-every-programmer-should-know).
|
See [Latency numbers every programmer should know](https://github.com/donnemartin/system-design-primer#latency-numbers-every-programmer-should-know).
|
||||||
|
|
||||||
### Ongoing
|
### Ongoing
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Design a system that scales to millions of users on AWS
|
# Design a system that scales to millions of users on AWS
|
||||||
|
|
||||||
*Note: This document links directly to relevant areas found in the [system design topics](https://github.com/donnemartin/system-design-primer-interview#index-of-system-design-topics-1) to avoid duplication. Refer to the linked content for general talking points, tradeoffs, and alternatives.*
|
*Note: This document links directly to relevant areas found in the [system design topics](https://github.com/donnemartin/system-design-primer#index-of-system-design-topics) to avoid duplication. Refer to the linked content for general talking points, tradeoffs, and alternatives.*
|
||||||
|
|
||||||
## Step 1: Outline use cases and constraints
|
## Step 1: Outline use cases and constraints
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ Handy conversion guide:
|
||||||
|
|
||||||
* **Web server** on EC2
|
* **Web server** on EC2
|
||||||
* Storage for user data
|
* Storage for user data
|
||||||
* [**MySQL Database**](https://github.com/donnemartin/system-design-primer-interview#sql)
|
* [**MySQL Database**](https://github.com/donnemartin/system-design-primer#sql)
|
||||||
|
|
||||||
Use **Vertical Scaling**:
|
Use **Vertical Scaling**:
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ Use **Vertical Scaling**:
|
||||||
|
|
||||||
*Trade-offs, alternatives, and additional details:*
|
*Trade-offs, alternatives, and additional details:*
|
||||||
|
|
||||||
* The alternative to **Vertical Scaling** is [**Horizontal scaling**](https://github.com/donnemartin/system-design-primer-interview#horizontal-scaling)
|
* The alternative to **Vertical Scaling** is [**Horizontal scaling**](https://github.com/donnemartin/system-design-primer#horizontal-scaling)
|
||||||
|
|
||||||
#### Start with SQL, consider NoSQL
|
#### Start with SQL, consider NoSQL
|
||||||
|
|
||||||
|
@ -104,8 +104,8 @@ The constraints assume there is a need for relational data. We can start off us
|
||||||
|
|
||||||
*Trade-offs, alternatives, and additional details:*
|
*Trade-offs, alternatives, and additional details:*
|
||||||
|
|
||||||
* See the [Relational database management system (RDBMS)](https://github.com/donnemartin/system-design-primer-interview#relational-database-management-system-rdbms) section
|
* See the [Relational database management system (RDBMS)](https://github.com/donnemartin/system-design-primer#relational-database-management-system-rdbms) section
|
||||||
* Discuss reasons to use [SQL or NoSQL](https://github.com/donnemartin/system-design-primer-interview#sql-or-nosql)
|
* Discuss reasons to use [SQL or NoSQL](https://github.com/donnemartin/system-design-primer#sql-or-nosql)
|
||||||
|
|
||||||
#### Assign a public static IP
|
#### Assign a public static IP
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ Add a **DNS** such as Route 53 to map the domain to the instance's public IP.
|
||||||
|
|
||||||
*Trade-offs, alternatives, and additional details:*
|
*Trade-offs, alternatives, and additional details:*
|
||||||
|
|
||||||
* See the [Domain name system](https://github.com/donnemartin/system-design-primer-interview#domain-name-system) section
|
* See the [Domain name system](https://github.com/donnemartin/system-design-primer#domain-name-system) section
|
||||||
|
|
||||||
#### Secure the web server
|
#### Secure the web server
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ Add a **DNS** such as Route 53 to map the domain to the instance's public IP.
|
||||||
|
|
||||||
*Trade-offs, alternatives, and additional details:*
|
*Trade-offs, alternatives, and additional details:*
|
||||||
|
|
||||||
* See the [Security](https://github.com/donnemartin/system-design-primer-interview#security) section
|
* See the [Security](https://github.com/donnemartin/system-design-primer#security) section
|
||||||
|
|
||||||
## Step 4: Scale the design
|
## Step 4: Scale the design
|
||||||
|
|
||||||
|
@ -187,7 +187,7 @@ We've been able to address these issues with **Vertical Scaling** so far. Unfor
|
||||||
|
|
||||||
*Trade-offs, alternatives, and additional details:*
|
*Trade-offs, alternatives, and additional details:*
|
||||||
|
|
||||||
* See the [Security](https://github.com/donnemartin/system-design-primer-interview#security) section
|
* See the [Security](https://github.com/donnemartin/system-design-primer#security) section
|
||||||
|
|
||||||
### Users++
|
### Users++
|
||||||
|
|
||||||
|
@ -201,18 +201,18 @@ Our **Benchmarks/Load Tests** and **Profiling** show that our single **Web Serve
|
||||||
|
|
||||||
* The following goals attempt to address the scaling issues with the **Web Server**
|
* The following goals attempt to address the scaling issues with the **Web Server**
|
||||||
* Based on the **Benchmarks/Load Tests** and **Profiling**, you might only need to implement one or two of these techniques
|
* Based on the **Benchmarks/Load Tests** and **Profiling**, you might only need to implement one or two of these techniques
|
||||||
* Use [**Horizontal Scaling**](https://github.com/donnemartin/system-design-primer-interview#horizontal-scaling) to handle increasing loads and to address single points of failure
|
* Use [**Horizontal Scaling**](https://github.com/donnemartin/system-design-primer#horizontal-scaling) to handle increasing loads and to address single points of failure
|
||||||
* Add a [**Load Balancer**](https://github.com/donnemartin/system-design-primer-interview#load-balancer) such as Amazon's ELB or HAProxy
|
* Add a [**Load Balancer**](https://github.com/donnemartin/system-design-primer#load-balancer) such as Amazon's ELB or HAProxy
|
||||||
* ELB is highly available
|
* ELB is highly available
|
||||||
* If you are configuring your own **Load Balancer**, setting up multiple servers in [active-active](https://github.com/donnemartin/system-design-primer-interview#active-active) or [active-passive](https://github.com/donnemartin/system-design-primer-interview#active-passive) in multiple availability zones will improve availability
|
* If you are configuring your own **Load Balancer**, setting up multiple servers in [active-active](https://github.com/donnemartin/system-design-primer#active-active) or [active-passive](https://github.com/donnemartin/system-design-primer#active-passive) in multiple availability zones will improve availability
|
||||||
* Terminate SSL on the **Load Balancer** to reduce computational load on backend servers and to simplify certificate administration
|
* Terminate SSL on the **Load Balancer** to reduce computational load on backend servers and to simplify certificate administration
|
||||||
* Use multiple **Web Servers** spread out over multiple availability zones
|
* Use multiple **Web Servers** spread out over multiple availability zones
|
||||||
* Use multiple **MySQL** instances in [**Master-Slave Failover**](https://github.com/donnemartin/system-design-primer-interview#master-slave-replication) mode across multiple availability zones to improve redundancy
|
* Use multiple **MySQL** instances in [**Master-Slave Failover**](https://github.com/donnemartin/system-design-primer#master-slave-replication) mode across multiple availability zones to improve redundancy
|
||||||
* Separate out the **Web Servers** from the [**Application Servers**](https://github.com/donnemartin/system-design-primer-interview#application-layer)
|
* Separate out the **Web Servers** from the [**Application Servers**](https://github.com/donnemartin/system-design-primer#application-layer)
|
||||||
* Scale and configure both layers independently
|
* Scale and configure both layers independently
|
||||||
* **Web Servers** can run as a [**Reverse Proxy**](https://github.com/donnemartin/system-design-primer-interview#reverse-proxy)
|
* **Web Servers** can run as a [**Reverse Proxy**](https://github.com/donnemartin/system-design-primer#reverse-proxy-web-server)
|
||||||
* For example, you can add **Application Servers** handling **Read APIs** while others handle **Write APIs**
|
* For example, you can add **Application Servers** handling **Read APIs** while others handle **Write APIs**
|
||||||
* Move static (and some dynamic) content to a [**Content Delivery Network (CDN)**](https://github.com/donnemartin/system-design-primer-interview#content-delivery-network) such as CloudFront to reduce load and latency
|
* Move static (and some dynamic) content to a [**Content Delivery Network (CDN)**](https://github.com/donnemartin/system-design-primer#content-delivery-network) such as CloudFront to reduce load and latency
|
||||||
|
|
||||||
*Trade-offs, alternatives, and additional details:*
|
*Trade-offs, alternatives, and additional details:*
|
||||||
|
|
||||||
|
@ -232,13 +232,13 @@ Our **Benchmarks/Load Tests** and **Profiling** show that we are read-heavy (100
|
||||||
|
|
||||||
* The following goals attempt to address the scaling issues with the **MySQL Database**
|
* The following goals attempt to address the scaling issues with the **MySQL Database**
|
||||||
* Based on the **Benchmarks/Load Tests** and **Profiling**, you might only need to implement one or two of these techniques
|
* Based on the **Benchmarks/Load Tests** and **Profiling**, you might only need to implement one or two of these techniques
|
||||||
* Move the following data to a [**Memory Cache**](https://github.com/donnemartin/system-design-primer-interview#cache) such as Elasticache to reduce load and latency:
|
* Move the following data to a [**Memory Cache**](https://github.com/donnemartin/system-design-primer#cache) such as Elasticache to reduce load and latency:
|
||||||
* Frequently accessed content from **MySQL**
|
* Frequently accessed content from **MySQL**
|
||||||
* First, try to configure the **MySQL Database** cache to see if that is sufficient to relieve the bottleneck before implementing a **Memory Cache**
|
* First, try to configure the **MySQL Database** cache to see if that is sufficient to relieve the bottleneck before implementing a **Memory Cache**
|
||||||
* Session data from the **Web Servers**
|
* Session data from the **Web Servers**
|
||||||
* The **Web Servers** become stateless, allowing for **Autoscaling**
|
* The **Web Servers** become stateless, allowing for **Autoscaling**
|
||||||
* Reading 1 MB sequentially from memory takes about 250 microseconds, while reading from SSD takes 4x and from disk takes 80x longer.<sup><a href=https://github.com/donnemartin/system-design-primer-interview#latency-numbers-every-programmer-should-know>1</a></sup>
|
* Reading 1 MB sequentially from memory takes about 250 microseconds, while reading from SSD takes 4x and from disk takes 80x longer.<sup><a href=https://github.com/donnemartin/system-design-primer#latency-numbers-every-programmer-should-know>1</a></sup>
|
||||||
* Add [**MySQL Read Replicas**](https://github.com/donnemartin/system-design-primer-interview#master-slave-replication) to reduce load on the write master
|
* Add [**MySQL Read Replicas**](https://github.com/donnemartin/system-design-primer#master-slave-replication) to reduce load on the write master
|
||||||
* Add more **Web Servers** and **Application Servers** to improve responsiveness
|
* Add more **Web Servers** and **Application Servers** to improve responsiveness
|
||||||
|
|
||||||
*Trade-offs, alternatives, and additional details:*
|
*Trade-offs, alternatives, and additional details:*
|
||||||
|
@ -254,7 +254,7 @@ Our **Benchmarks/Load Tests** and **Profiling** show that we are read-heavy (100
|
||||||
|
|
||||||
*Trade-offs, alternatives, and additional details:*
|
*Trade-offs, alternatives, and additional details:*
|
||||||
|
|
||||||
* See the [Relational database management system (RDBMS)](https://github.com/donnemartin/system-design-primer-interview#relational-database-management-system-rdbms) section
|
* See the [Relational database management system (RDBMS)](https://github.com/donnemartin/system-design-primer#relational-database-management-system-rdbms) section
|
||||||
|
|
||||||
### Users++++
|
### Users++++
|
||||||
|
|
||||||
|
@ -317,14 +317,14 @@ We'll continue to address scaling issues due to the problem's constraints:
|
||||||
|
|
||||||
SQL scaling patterns include:
|
SQL scaling patterns include:
|
||||||
|
|
||||||
* [Federation](https://github.com/donnemartin/system-design-primer-interview#federation)
|
* [Federation](https://github.com/donnemartin/system-design-primer#federation)
|
||||||
* [Sharding](https://github.com/donnemartin/system-design-primer-interview#sharding)
|
* [Sharding](https://github.com/donnemartin/system-design-primer#sharding)
|
||||||
* [Denormalization](https://github.com/donnemartin/system-design-primer-interview#denormalization)
|
* [Denormalization](https://github.com/donnemartin/system-design-primer#denormalization)
|
||||||
* [SQL Tuning](https://github.com/donnemartin/system-design-primer-interview#sql-tuning)
|
* [SQL Tuning](https://github.com/donnemartin/system-design-primer#sql-tuning)
|
||||||
|
|
||||||
To further address the high read and write requests, we should also consider moving appropriate data to a [**NoSQL Database**](https://github.com/donnemartin/system-design-primer-interview#nosql) such as DynamoDB.
|
To further address the high read and write requests, we should also consider moving appropriate data to a [**NoSQL Database**](https://github.com/donnemartin/system-design-primer#nosql) such as DynamoDB.
|
||||||
|
|
||||||
We can further separate out our [**Application Servers**](https://github.com/donnemartin/system-design-primer-interview#application-layer) to allow for independent scaling. Batch processes or computations that do not need to be done in real-time can be done [**Asynchronously**](https://github.com/donnemartin/system-design-primer-interview#asynchronism) with **Queues** and **Workers**:
|
We can further separate out our [**Application Servers**](https://github.com/donnemartin/system-design-primer#application-layer) to allow for independent scaling. Batch processes or computations that do not need to be done in real-time can be done [**Asynchronously**](https://github.com/donnemartin/system-design-primer#asynchronism) with **Queues** and **Workers**:
|
||||||
|
|
||||||
* For example, in a photo service, the photo upload and the thumbnail creation can be separated:
|
* For example, in a photo service, the photo upload and the thumbnail creation can be separated:
|
||||||
* **Client** uploads photo
|
* **Client** uploads photo
|
||||||
|
@ -344,58 +344,58 @@ We can further separate out our [**Application Servers**](https://github.com/don
|
||||||
|
|
||||||
### SQL scaling patterns
|
### SQL scaling patterns
|
||||||
|
|
||||||
* [Read replicas](https://github.com/donnemartin/system-design-primer-interview#master-slave)
|
* [Read replicas](https://github.com/donnemartin/system-design-primer#master-slave)
|
||||||
* [Federation](https://github.com/donnemartin/system-design-primer-interview#federation)
|
* [Federation](https://github.com/donnemartin/system-design-primer#federation)
|
||||||
* [Sharding](https://github.com/donnemartin/system-design-primer-interview#sharding)
|
* [Sharding](https://github.com/donnemartin/system-design-primer#sharding)
|
||||||
* [Denormalization](https://github.com/donnemartin/system-design-primer-interview#denormalization)
|
* [Denormalization](https://github.com/donnemartin/system-design-primer#denormalization)
|
||||||
* [SQL Tuning](https://github.com/donnemartin/system-design-primer-interview#sql-tuning)
|
* [SQL Tuning](https://github.com/donnemartin/system-design-primer#sql-tuning)
|
||||||
|
|
||||||
#### NoSQL
|
#### NoSQL
|
||||||
|
|
||||||
* [Key-value store](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Key-value store](https://github.com/donnemartin/system-design-primer#key-value-store)
|
||||||
* [Document store](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Document store](https://github.com/donnemartin/system-design-primer#document-store)
|
||||||
* [Wide column store](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Wide column store](https://github.com/donnemartin/system-design-primer#wide-column-store)
|
||||||
* [Graph database](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Graph database](https://github.com/donnemartin/system-design-primer#graph-database)
|
||||||
* [SQL vs NoSQL](https://github.com/donnemartin/system-design-primer-interview#)
|
* [SQL vs NoSQL](https://github.com/donnemartin/system-design-primer#sql-or-nosql)
|
||||||
|
|
||||||
### Caching
|
### Caching
|
||||||
|
|
||||||
* Where to cache
|
* Where to cache
|
||||||
* [Client caching](https://github.com/donnemartin/system-design-primer-interview#client-caching)
|
* [Client caching](https://github.com/donnemartin/system-design-primer#client-caching)
|
||||||
* [CDN caching](https://github.com/donnemartin/system-design-primer-interview#cdn-caching)
|
* [CDN caching](https://github.com/donnemartin/system-design-primer#cdn-caching)
|
||||||
* [Web server caching](https://github.com/donnemartin/system-design-primer-interview#web-server-caching)
|
* [Web server caching](https://github.com/donnemartin/system-design-primer#web-server-caching)
|
||||||
* [Database caching](https://github.com/donnemartin/system-design-primer-interview#database-caching)
|
* [Database caching](https://github.com/donnemartin/system-design-primer#database-caching)
|
||||||
* [Application caching](https://github.com/donnemartin/system-design-primer-interview#application-caching)
|
* [Application caching](https://github.com/donnemartin/system-design-primer#application-caching)
|
||||||
* What to cache
|
* What to cache
|
||||||
* [Caching at the database query level](https://github.com/donnemartin/system-design-primer-interview#caching-at-the-database-query-level)
|
* [Caching at the database query level](https://github.com/donnemartin/system-design-primer#caching-at-the-database-query-level)
|
||||||
* [Caching at the object level](https://github.com/donnemartin/system-design-primer-interview#caching-at-the-object-level)
|
* [Caching at the object level](https://github.com/donnemartin/system-design-primer#caching-at-the-object-level)
|
||||||
* When to update the cache
|
* When to update the cache
|
||||||
* [Cache-aside](https://github.com/donnemartin/system-design-primer-interview#cache-aside)
|
* [Cache-aside](https://github.com/donnemartin/system-design-primer#cache-aside)
|
||||||
* [Write-through](https://github.com/donnemartin/system-design-primer-interview#write-through)
|
* [Write-through](https://github.com/donnemartin/system-design-primer#write-through)
|
||||||
* [Write-behind (write-back)](https://github.com/donnemartin/system-design-primer-interview#write-behind-write-back)
|
* [Write-behind (write-back)](https://github.com/donnemartin/system-design-primer#write-behind-write-back)
|
||||||
* [Refresh ahead](https://github.com/donnemartin/system-design-primer-interview#refresh-ahead)
|
* [Refresh ahead](https://github.com/donnemartin/system-design-primer#refresh-ahead)
|
||||||
|
|
||||||
### Asynchronism and microservices
|
### Asynchronism and microservices
|
||||||
|
|
||||||
* [Message queues](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Message queues](https://github.com/donnemartin/system-design-primer#message-queues)
|
||||||
* [Task queues](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Task queues](https://github.com/donnemartin/system-design-primer#task-queues)
|
||||||
* [Back pressure](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Back pressure](https://github.com/donnemartin/system-design-primer#back-pressure)
|
||||||
* [Microservices](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Microservices](https://github.com/donnemartin/system-design-primer#microservices)
|
||||||
|
|
||||||
### Communications
|
### Communications
|
||||||
|
|
||||||
* Discuss tradeoffs:
|
* Discuss tradeoffs:
|
||||||
* External communication with clients - [HTTP APIs following REST](https://github.com/donnemartin/system-design-primer-interview#representational-state-transfer-rest)
|
* External communication with clients - [HTTP APIs following REST](https://github.com/donnemartin/system-design-primer#representational-state-transfer-rest)
|
||||||
* Internal communications - [RPC](https://github.com/donnemartin/system-design-primer-interview#remote-procedure-call-rpc)
|
* Internal communications - [RPC](https://github.com/donnemartin/system-design-primer#remote-procedure-call-rpc)
|
||||||
* [Service discovery](https://github.com/donnemartin/system-design-primer-interview#service-discovery)
|
* [Service discovery](https://github.com/donnemartin/system-design-primer#service-discovery)
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
||||||
Refer to the [security section](https://github.com/donnemartin/system-design-primer-interview#security).
|
Refer to the [security section](https://github.com/donnemartin/system-design-primer#security).
|
||||||
|
|
||||||
### Latency numbers
|
### Latency numbers
|
||||||
|
|
||||||
See [Latency numbers every programmer should know](https://github.com/donnemartin/system-design-primer-interview#latency-numbers-every-programmer-should-know).
|
See [Latency numbers every programmer should know](https://github.com/donnemartin/system-design-primer#latency-numbers-every-programmer-should-know).
|
||||||
|
|
||||||
### Ongoing
|
### Ongoing
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Design the data structures for a social network
|
# Design the data structures for a social network
|
||||||
|
|
||||||
*Note: This document links directly to relevant areas found in the [system design topics](https://github.com/donnemartin/system-design-primer-interview#index-of-system-design-topics-1) to avoid duplication. Refer to the linked content for general talking points, tradeoffs, and alternatives.*
|
*Note: This document links directly to relevant areas found in the [system design topics](https://github.com/donnemartin/system-design-primer#index-of-system-design-topics) to avoid duplication. Refer to the linked content for general talking points, tradeoffs, and alternatives.*
|
||||||
|
|
||||||
## Step 1: Outline use cases and constraints
|
## Step 1: Outline use cases and constraints
|
||||||
|
|
||||||
|
@ -99,9 +99,9 @@ class Graph(Graph):
|
||||||
return None
|
return None
|
||||||
```
|
```
|
||||||
|
|
||||||
We won't be able to fit all users on the same machine, we'll need to [shard](https://github.com/donnemartin/system-design-primer-interview#sharding) users across **Person Servers** and access them with a **Lookup Service**.
|
We won't be able to fit all users on the same machine, we'll need to [shard](https://github.com/donnemartin/system-design-primer#sharding) users across **Person Servers** and access them with a **Lookup Service**.
|
||||||
|
|
||||||
* The **Client** sends a request to the **Web Server**, running as a [reverse proxy](https://github.com/donnemartin/system-design-primer-interview#reverse-proxy-web-server)
|
* The **Client** sends a request to the **Web Server**, running as a [reverse proxy](https://github.com/donnemartin/system-design-primer#reverse-proxy-web-server)
|
||||||
* The **Web Server** forwards the request to the **Search API** server
|
* The **Web Server** forwards the request to the **Search API** server
|
||||||
* The **Search API** server forwards the request to the **User Graph Service**
|
* The **Search API** server forwards the request to the **User Graph Service**
|
||||||
* The **User Graph Service** does does the following:
|
* The **User Graph Service** does does the following:
|
||||||
|
@ -218,7 +218,7 @@ class UserGraphService(object):
|
||||||
return None
|
return None
|
||||||
```
|
```
|
||||||
|
|
||||||
We'll use a public [**REST API**](https://github.com/donnemartin/system-design-primer-interview##representational-state-transfer-rest):
|
We'll use a public [**REST API**](https://github.com/donnemartin/system-design-primer#representational-state-transfer-rest):
|
||||||
|
|
||||||
```
|
```
|
||||||
$ curl https://social.com/api/v1/friend_search?person_id=1234
|
$ curl https://social.com/api/v1/friend_search?person_id=1234
|
||||||
|
@ -244,7 +244,7 @@ Response:
|
||||||
},
|
},
|
||||||
```
|
```
|
||||||
|
|
||||||
For internal communications, we could use [Remote Procedure Calls](https://github.com/donnemartin/system-design-primer-interview#remote-procedure-call-rpc).
|
For internal communications, we could use [Remote Procedure Calls](https://github.com/donnemartin/system-design-primer#remote-procedure-call-rpc).
|
||||||
|
|
||||||
## Step 4: Scale the design
|
## Step 4: Scale the design
|
||||||
|
|
||||||
|
@ -254,31 +254,31 @@ For internal communications, we could use [Remote Procedure Calls](https://githu
|
||||||
|
|
||||||
**Important: Do not simply jump right into the final design from the initial design!**
|
**Important: Do not simply jump right into the final design from the initial design!**
|
||||||
|
|
||||||
State you would 1) **Benchmark/Load Test**, 2) **Profile** for bottlenecks 3) address bottlenecks while evaluating alternatives and trade-offs, and 4) repeat. See [Design a system that scales to millions of users on AWS]() as a sample on how to iteratively scale the initial design.
|
State you would 1) **Benchmark/Load Test**, 2) **Profile** for bottlenecks 3) address bottlenecks while evaluating alternatives and trade-offs, and 4) repeat. See [Design a system that scales to millions of users on AWS](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/scaling_aws/README.md) as a sample on how to iteratively scale the initial design.
|
||||||
|
|
||||||
It's important to discuss what bottlenecks you might encounter with the initial design and how you might address each of them. For example, what issues are addressed by adding a **Load Balancer** with multiple **Web Servers**? **CDN**? **Master-Slave Replicas**? What are the alternatives and **Trade-Offs** for each?
|
It's important to discuss what bottlenecks you might encounter with the initial design and how you might address each of them. For example, what issues are addressed by adding a **Load Balancer** with multiple **Web Servers**? **CDN**? **Master-Slave Replicas**? What are the alternatives and **Trade-Offs** for each?
|
||||||
|
|
||||||
We'll introduce some components to complete the design and to address scalability issues. Internal load balancers are not shown to reduce clutter.
|
We'll introduce some components to complete the design and to address scalability issues. Internal load balancers are not shown to reduce clutter.
|
||||||
|
|
||||||
*To avoid repeating discussions*, refer to the following [system design topics](https://github.com/donnemartin/system-design-primer-interview#) for main talking points, tradeoffs, and alternatives:
|
*To avoid repeating discussions*, refer to the following [system design topics](https://github.com/donnemartin/system-design-primer#index-of-system-design-topics) for main talking points, tradeoffs, and alternatives:
|
||||||
|
|
||||||
* [DNS](https://github.com/donnemartin/system-design-primer-interview#domain-name-system)
|
* [DNS](https://github.com/donnemartin/system-design-primer#domain-name-system)
|
||||||
* [Load balancer](https://github.com/donnemartin/system-design-primer-interview#load-balancer)
|
* [Load balancer](https://github.com/donnemartin/system-design-primer#load-balancer)
|
||||||
* [Horizontal scaling](https://github.com/donnemartin/system-design-primer-interview#horizontal-scaling)
|
* [Horizontal scaling](https://github.com/donnemartin/system-design-primer#horizontal-scaling)
|
||||||
* [Web server (reverse proxy)](https://github.com/donnemartin/system-design-primer-interview#reverse-proxy-web-server)
|
* [Web server (reverse proxy)](https://github.com/donnemartin/system-design-primer#reverse-proxy-web-server)
|
||||||
* [API server (application layer)](https://github.com/donnemartin/system-design-primer-interview#application-layer)
|
* [API server (application layer)](https://github.com/donnemartin/system-design-primer#application-layer)
|
||||||
* [Cache](https://github.com/donnemartin/system-design-primer-interview#cache)
|
* [Cache](https://github.com/donnemartin/system-design-primer#cache)
|
||||||
* [Consistency patterns](https://github.com/donnemartin/system-design-primer-interview#consistency-patterns)
|
* [Consistency patterns](https://github.com/donnemartin/system-design-primer#consistency-patterns)
|
||||||
* [Availability patterns](https://github.com/donnemartin/system-design-primer-interview#availability-patterns)
|
* [Availability patterns](https://github.com/donnemartin/system-design-primer#availability-patterns)
|
||||||
|
|
||||||
To address the constraint of 400 *average* read requests per second (higher at peak), person data can be served from a **Memory Cache** such as Redis or Memcached to reduce response times and to reduce traffic to downstream services. This could be especially useful for people who do multiple searches in succession and for people who are well-connected. Reading 1 MB sequentially from memory takes about 250 microseconds, while reading from SSD takes 4x and from disk takes 80x longer.<sup><a href=https://github.com/donnemartin/system-design-primer-interview#latency-numbers-every-programmer-should-know>1</a></sup>
|
To address the constraint of 400 *average* read requests per second (higher at peak), person data can be served from a **Memory Cache** such as Redis or Memcached to reduce response times and to reduce traffic to downstream services. This could be especially useful for people who do multiple searches in succession and for people who are well-connected. Reading 1 MB sequentially from memory takes about 250 microseconds, while reading from SSD takes 4x and from disk takes 80x longer.<sup><a href=https://github.com/donnemartin/system-design-primer#latency-numbers-every-programmer-should-know>1</a></sup>
|
||||||
|
|
||||||
Below are further optimizations:
|
Below are further optimizations:
|
||||||
|
|
||||||
* Store complete or partial BFS traversals to speed up subsequent lookups in the **Memory Cache**
|
* Store complete or partial BFS traversals to speed up subsequent lookups in the **Memory Cache**
|
||||||
* Batch compute offline then store complete or partial BFS traversals to speed up subsequent lookups in a **NoSQL Database**
|
* Batch compute offline then store complete or partial BFS traversals to speed up subsequent lookups in a **NoSQL Database**
|
||||||
* Reduce machine jumps by batching together friend lookups hosted on the same **Person Server**
|
* Reduce machine jumps by batching together friend lookups hosted on the same **Person Server**
|
||||||
* [Shard](https://github.com/donnemartin/system-design-primer-interview#Sharding) **Person Servers** by location to further improve this, as friends generally live closer to each other
|
* [Shard](https://github.com/donnemartin/system-design-primer#sharding) **Person Servers** by location to further improve this, as friends generally live closer to each other
|
||||||
* Do two BFS searches at the same time, one starting from the source, and one from the destination, then merge the two paths
|
* Do two BFS searches at the same time, one starting from the source, and one from the destination, then merge the two paths
|
||||||
* Start the BFS search from people with large numbers of friends, as they are more likely to reduce the number of [degrees of separation](https://en.wikipedia.org/wiki/Six_degrees_of_separation) between the current user and the search target
|
* Start the BFS search from people with large numbers of friends, as they are more likely to reduce the number of [degrees of separation](https://en.wikipedia.org/wiki/Six_degrees_of_separation) between the current user and the search target
|
||||||
* Set a limit based on time or number of hops before asking the user if they want to continue searching, as searching could take a considerable amount of time in some cases
|
* Set a limit based on time or number of hops before asking the user if they want to continue searching, as searching could take a considerable amount of time in some cases
|
||||||
|
@ -290,58 +290,58 @@ Below are further optimizations:
|
||||||
|
|
||||||
### SQL scaling patterns
|
### SQL scaling patterns
|
||||||
|
|
||||||
* [Read replicas](https://github.com/donnemartin/system-design-primer-interview#master-slave)
|
* [Read replicas](https://github.com/donnemartin/system-design-primer#master-slave)
|
||||||
* [Federation](https://github.com/donnemartin/system-design-primer-interview#federation)
|
* [Federation](https://github.com/donnemartin/system-design-primer#federation)
|
||||||
* [Sharding](https://github.com/donnemartin/system-design-primer-interview#sharding)
|
* [Sharding](https://github.com/donnemartin/system-design-primer#sharding)
|
||||||
* [Denormalization](https://github.com/donnemartin/system-design-primer-interview#denormalization)
|
* [Denormalization](https://github.com/donnemartin/system-design-primer#denormalization)
|
||||||
* [SQL Tuning](https://github.com/donnemartin/system-design-primer-interview#sql-tuning)
|
* [SQL Tuning](https://github.com/donnemartin/system-design-primer#sql-tuning)
|
||||||
|
|
||||||
#### NoSQL
|
#### NoSQL
|
||||||
|
|
||||||
* [Key-value store](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Key-value store](https://github.com/donnemartin/system-design-primer#key-value-store)
|
||||||
* [Document store](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Document store](https://github.com/donnemartin/system-design-primer#document-store)
|
||||||
* [Wide column store](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Wide column store](https://github.com/donnemartin/system-design-primer#wide-column-store)
|
||||||
* [Graph database](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Graph database](https://github.com/donnemartin/system-design-primer#graph-database)
|
||||||
* [SQL vs NoSQL](https://github.com/donnemartin/system-design-primer-interview#)
|
* [SQL vs NoSQL](https://github.com/donnemartin/system-design-primer#sql-or-nosql)
|
||||||
|
|
||||||
### Caching
|
### Caching
|
||||||
|
|
||||||
* Where to cache
|
* Where to cache
|
||||||
* [Client caching](https://github.com/donnemartin/system-design-primer-interview#client-caching)
|
* [Client caching](https://github.com/donnemartin/system-design-primer#client-caching)
|
||||||
* [CDN caching](https://github.com/donnemartin/system-design-primer-interview#cdn-caching)
|
* [CDN caching](https://github.com/donnemartin/system-design-primer#cdn-caching)
|
||||||
* [Web server caching](https://github.com/donnemartin/system-design-primer-interview#web-server-caching)
|
* [Web server caching](https://github.com/donnemartin/system-design-primer#web-server-caching)
|
||||||
* [Database caching](https://github.com/donnemartin/system-design-primer-interview#database-caching)
|
* [Database caching](https://github.com/donnemartin/system-design-primer#database-caching)
|
||||||
* [Application caching](https://github.com/donnemartin/system-design-primer-interview#application-caching)
|
* [Application caching](https://github.com/donnemartin/system-design-primer#application-caching)
|
||||||
* What to cache
|
* What to cache
|
||||||
* [Caching at the database query level](https://github.com/donnemartin/system-design-primer-interview#caching-at-the-database-query-level)
|
* [Caching at the database query level](https://github.com/donnemartin/system-design-primer#caching-at-the-database-query-level)
|
||||||
* [Caching at the object level](https://github.com/donnemartin/system-design-primer-interview#caching-at-the-object-level)
|
* [Caching at the object level](https://github.com/donnemartin/system-design-primer#caching-at-the-object-level)
|
||||||
* When to update the cache
|
* When to update the cache
|
||||||
* [Cache-aside](https://github.com/donnemartin/system-design-primer-interview#cache-aside)
|
* [Cache-aside](https://github.com/donnemartin/system-design-primer#cache-aside)
|
||||||
* [Write-through](https://github.com/donnemartin/system-design-primer-interview#write-through)
|
* [Write-through](https://github.com/donnemartin/system-design-primer#write-through)
|
||||||
* [Write-behind (write-back)](https://github.com/donnemartin/system-design-primer-interview#write-behind-write-back)
|
* [Write-behind (write-back)](https://github.com/donnemartin/system-design-primer#write-behind-write-back)
|
||||||
* [Refresh ahead](https://github.com/donnemartin/system-design-primer-interview#refresh-ahead)
|
* [Refresh ahead](https://github.com/donnemartin/system-design-primer#refresh-ahead)
|
||||||
|
|
||||||
### Asynchronism and microservices
|
### Asynchronism and microservices
|
||||||
|
|
||||||
* [Message queues](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Message queues](https://github.com/donnemartin/system-design-primer#message-queues)
|
||||||
* [Task queues](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Task queues](https://github.com/donnemartin/system-design-primer#task-queues)
|
||||||
* [Back pressure](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Back pressure](https://github.com/donnemartin/system-design-primer#back-pressure)
|
||||||
* [Microservices](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Microservices](https://github.com/donnemartin/system-design-primer#microservices)
|
||||||
|
|
||||||
### Communications
|
### Communications
|
||||||
|
|
||||||
* Discuss tradeoffs:
|
* Discuss tradeoffs:
|
||||||
* External communication with clients - [HTTP APIs following REST](https://github.com/donnemartin/system-design-primer-interview#representational-state-transfer-rest)
|
* External communication with clients - [HTTP APIs following REST](https://github.com/donnemartin/system-design-primer#representational-state-transfer-rest)
|
||||||
* Internal communications - [RPC](https://github.com/donnemartin/system-design-primer-interview#remote-procedure-call-rpc)
|
* Internal communications - [RPC](https://github.com/donnemartin/system-design-primer#remote-procedure-call-rpc)
|
||||||
* [Service discovery](https://github.com/donnemartin/system-design-primer-interview#service-discovery)
|
* [Service discovery](https://github.com/donnemartin/system-design-primer#service-discovery)
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
||||||
Refer to the [security section](https://github.com/donnemartin/system-design-primer-interview#security).
|
Refer to the [security section](https://github.com/donnemartin/system-design-primer#security).
|
||||||
|
|
||||||
### Latency numbers
|
### Latency numbers
|
||||||
|
|
||||||
See [Latency numbers every programmer should know](https://github.com/donnemartin/system-design-primer-interview#latency-numbers-every-programmer-should-know).
|
See [Latency numbers every programmer should know](https://github.com/donnemartin/system-design-primer#latency-numbers-every-programmer-should-know).
|
||||||
|
|
||||||
### Ongoing
|
### Ongoing
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Design the Twitter timeline and search
|
# Design the Twitter timeline and search
|
||||||
|
|
||||||
*Note: This document links directly to relevant areas found in the [system design topics](https://github.com/donnemartin/system-design-primer-interview#index-of-system-design-topics-1) to avoid duplication. Refer to the linked content for general talking points, tradeoffs, and alternatives.*
|
*Note: This document links directly to relevant areas found in the [system design topics](https://github.com/donnemartin/system-design-primer#index-of-system-design-topics) to avoid duplication. Refer to the linked content for general talking points, tradeoffs, and alternatives.*
|
||||||
|
|
||||||
**Design the Facebook feed** and **Design Facebook search** are similar questions.
|
**Design the Facebook feed** and **Design Facebook search** are similar questions.
|
||||||
|
|
||||||
|
@ -100,13 +100,13 @@ Handy conversion guide:
|
||||||
|
|
||||||
### Use case: User posts a tweet
|
### Use case: User posts a tweet
|
||||||
|
|
||||||
We could store the user's own tweets to populate the user timeline (activity from the user) in a [relational database](https://github.com/donnemartin/system-design-primer-interview#relational-database-management-system-rdbms). We should discuss the [use cases and tradeoffs between choosing SQL or NoSQL](https://github.com/donnemartin/system-design-primer-interview#sql-or-nosql).
|
We could store the user's own tweets to populate the user timeline (activity from the user) in a [relational database](https://github.com/donnemartin/system-design-primer#relational-database-management-system-rdbms). We should discuss the [use cases and tradeoffs between choosing SQL or NoSQL](https://github.com/donnemartin/system-design-primer#sql-or-nosql).
|
||||||
|
|
||||||
Delivering tweets and building the home timeline (activity from people the user is following) is trickier. Fanning out tweets to all followers (60 thousand tweets delivered on fanout per second) will overload a traditional [relational database](https://github.com/donnemartin/system-design-primer-interview#relational-database-management-system-rdbms). We'll probably want to choose a data store with fast writes such as a **NoSQL database** or **Memory Cache**. Reading 1 MB sequentially from memory takes about 250 microseconds, while reading from SSD takes 4x and from disk takes 80x longer.<sup><a href=https://github.com/donnemartin/system-design-primer-interview#latency-numbers-every-programmer-should-know>1</a></sup>
|
Delivering tweets and building the home timeline (activity from people the user is following) is trickier. Fanning out tweets to all followers (60 thousand tweets delivered on fanout per second) will overload a traditional [relational database](https://github.com/donnemartin/system-design-primer#relational-database-management-system-rdbms). We'll probably want to choose a data store with fast writes such as a **NoSQL database** or **Memory Cache**. Reading 1 MB sequentially from memory takes about 250 microseconds, while reading from SSD takes 4x and from disk takes 80x longer.<sup><a href=https://github.com/donnemartin/system-design-primer#latency-numbers-every-programmer-should-know>1</a></sup>
|
||||||
|
|
||||||
We could store media such as photos or videos on an **Object Store**.
|
We could store media such as photos or videos on an **Object Store**.
|
||||||
|
|
||||||
* The **Client** posts a tweet to the **Web Server**, running as a [reverse proxy](https://github.com/donnemartin/system-design-primer-interview#reverse-proxy-web-server)
|
* The **Client** posts a tweet to the **Web Server**, running as a [reverse proxy](https://github.com/donnemartin/system-design-primer#reverse-proxy-web-server)
|
||||||
* The **Web Server** forwards the request to the **Write API** server
|
* The **Web Server** forwards the request to the **Write API** server
|
||||||
* The **Write API** stores the tweet in the user's timeline on a **SQL database**
|
* The **Write API** stores the tweet in the user's timeline on a **SQL database**
|
||||||
* The **Write API** contacts the **Fan Out Service**, which does the following:
|
* The **Write API** contacts the **Fan Out Service**, which does the following:
|
||||||
|
@ -130,7 +130,7 @@ If our **Memory Cache** is Redis, we could use a native Redis list with the foll
|
||||||
|
|
||||||
The new tweet would be placed in the **Memory Cache**, which populates user's home timeline (activity from people the user is following).
|
The new tweet would be placed in the **Memory Cache**, which populates user's home timeline (activity from people the user is following).
|
||||||
|
|
||||||
We'll use a public [**REST API**](https://github.com/donnemartin/system-design-primer-interview##representational-state-transfer-rest):
|
We'll use a public [**REST API**](https://github.com/donnemartin/system-design-primer#representational-state-transfer-rest):
|
||||||
|
|
||||||
```
|
```
|
||||||
$ curl -X POST --data '{ "user_id": "123", "auth_token": "ABC123", \
|
$ curl -X POST --data '{ "user_id": "123", "auth_token": "ABC123", \
|
||||||
|
@ -150,7 +150,7 @@ Response:
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
For internal communications, we could use [Remote Procedure Calls](https://github.com/donnemartin/system-design-primer-interview#remote-procedure-call-rpc).
|
For internal communications, we could use [Remote Procedure Calls](https://github.com/donnemartin/system-design-primer#remote-procedure-call-rpc).
|
||||||
|
|
||||||
### Use case: User views the home timeline
|
### Use case: User views the home timeline
|
||||||
|
|
||||||
|
@ -207,7 +207,7 @@ The REST API would be similar to the home timeline, except all tweets would come
|
||||||
* Normalizes capitalization
|
* Normalizes capitalization
|
||||||
* Converts the query to use boolean operations
|
* Converts the query to use boolean operations
|
||||||
* Queries the **Search Cluster** (ie [Lucene](https://lucene.apache.org/)) for the results:
|
* Queries the **Search Cluster** (ie [Lucene](https://lucene.apache.org/)) for the results:
|
||||||
* [Scatter gathers](https://github.com/donnemartin/system-design-primer-interview#scatter-gather) each server in the cluster to determine if there are any results for the query
|
* [Scatter gathers](https://github.com/donnemartin/system-design-primer#under-development) each server in the cluster to determine if there are any results for the query
|
||||||
* Merges, ranks, sorts, and returns the results
|
* Merges, ranks, sorts, and returns the results
|
||||||
|
|
||||||
REST API:
|
REST API:
|
||||||
|
@ -226,26 +226,26 @@ The response would be similar to that of the home timeline, except for tweets ma
|
||||||
|
|
||||||
**Important: Do not simply jump right into the final design from the initial design!**
|
**Important: Do not simply jump right into the final design from the initial design!**
|
||||||
|
|
||||||
State you would 1) **Benchmark/Load Test**, 2) **Profile** for bottlenecks 3) address bottlenecks while evaluating alternatives and trade-offs, and 4) repeat. See [Design a system that scales to millions of users on AWS]() as a sample on how to iteratively scale the initial design.
|
State you would 1) **Benchmark/Load Test**, 2) **Profile** for bottlenecks 3) address bottlenecks while evaluating alternatives and trade-offs, and 4) repeat. See [Design a system that scales to millions of users on AWS](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/scaling_aws/README.md) as a sample on how to iteratively scale the initial design.
|
||||||
|
|
||||||
It's important to discuss what bottlenecks you might encounter with the initial design and how you might address each of them. For example, what issues are addressed by adding a **Load Balancer** with multiple **Web Servers**? **CDN**? **Master-Slave Replicas**? What are the alternatives and **Trade-Offs** for each?
|
It's important to discuss what bottlenecks you might encounter with the initial design and how you might address each of them. For example, what issues are addressed by adding a **Load Balancer** with multiple **Web Servers**? **CDN**? **Master-Slave Replicas**? What are the alternatives and **Trade-Offs** for each?
|
||||||
|
|
||||||
We'll introduce some components to complete the design and to address scalability issues. Internal load balancers are not shown to reduce clutter.
|
We'll introduce some components to complete the design and to address scalability issues. Internal load balancers are not shown to reduce clutter.
|
||||||
|
|
||||||
*To avoid repeating discussions*, refer to the following [system design topics](https://github.com/donnemartin/system-design-primer-interview#) for main talking points, tradeoffs, and alternatives:
|
*To avoid repeating discussions*, refer to the following [system design topics](https://github.com/donnemartin/system-design-primer#index-of-system-design-topics) for main talking points, tradeoffs, and alternatives:
|
||||||
|
|
||||||
* [DNS](https://github.com/donnemartin/system-design-primer-interview#domain-name-system)
|
* [DNS](https://github.com/donnemartin/system-design-primer#domain-name-system)
|
||||||
* [CDN](https://github.com/donnemartin/system-design-primer-interview#content-delivery-network)
|
* [CDN](https://github.com/donnemartin/system-design-primer#content-delivery-network)
|
||||||
* [Load balancer](https://github.com/donnemartin/system-design-primer-interview#load-balancer)
|
* [Load balancer](https://github.com/donnemartin/system-design-primer#load-balancer)
|
||||||
* [Horizontal scaling](https://github.com/donnemartin/system-design-primer-interview#horizontal-scaling)
|
* [Horizontal scaling](https://github.com/donnemartin/system-design-primer#horizontal-scaling)
|
||||||
* [Web server (reverse proxy)](https://github.com/donnemartin/system-design-primer-interview#reverse-proxy-web-server)
|
* [Web server (reverse proxy)](https://github.com/donnemartin/system-design-primer#reverse-proxy-web-server)
|
||||||
* [API server (application layer)](https://github.com/donnemartin/system-design-primer-interview#application-layer)
|
* [API server (application layer)](https://github.com/donnemartin/system-design-primer#application-layer)
|
||||||
* [Cache](https://github.com/donnemartin/system-design-primer-interview#cache)
|
* [Cache](https://github.com/donnemartin/system-design-primer#cache)
|
||||||
* [Relational database management system (RDBMS)](https://github.com/donnemartin/system-design-primer-interview#relational-database-management-system-rdbms)
|
* [Relational database management system (RDBMS)](https://github.com/donnemartin/system-design-primer#relational-database-management-system-rdbms)
|
||||||
* [SQL write master-slave failover](https://github.com/donnemartin/system-design-primer-interview#fail-over)
|
* [SQL write master-slave failover](https://github.com/donnemartin/system-design-primer#fail-over)
|
||||||
* [Master-slave replication](https://github.com/donnemartin/system-design-primer-interview#master-slave-replication)
|
* [Master-slave replication](https://github.com/donnemartin/system-design-primer#master-slave-replication)
|
||||||
* [Consistency patterns](https://github.com/donnemartin/system-design-primer-interview#consistency-patterns)
|
* [Consistency patterns](https://github.com/donnemartin/system-design-primer#consistency-patterns)
|
||||||
* [Availability patterns](https://github.com/donnemartin/system-design-primer-interview#availability-patterns)
|
* [Availability patterns](https://github.com/donnemartin/system-design-primer#availability-patterns)
|
||||||
|
|
||||||
The **Fanout Service** is a potential bottleneck. Twitter users with millions of followers could take several minutes to have their tweets go through the fanout process. This could lead to race conditions with @replies to the tweet, which we could mitigate by re-ordering the tweets at serve time.
|
The **Fanout Service** is a potential bottleneck. Twitter users with millions of followers could take several minutes to have their tweets go through the fanout process. This could lead to race conditions with @replies to the tweet, which we could mitigate by re-ordering the tweets at serve time.
|
||||||
|
|
||||||
|
@ -268,10 +268,10 @@ Although the **Memory Cache** should reduce the load on the database, it is unli
|
||||||
|
|
||||||
The high volume of writes would overwhelm a single **SQL Write Master-Slave**, also pointing to a need for additional scaling techniques.
|
The high volume of writes would overwhelm a single **SQL Write Master-Slave**, also pointing to a need for additional scaling techniques.
|
||||||
|
|
||||||
* [Federation](https://github.com/donnemartin/system-design-primer-interview#federation)
|
* [Federation](https://github.com/donnemartin/system-design-primer#federation)
|
||||||
* [Sharding](https://github.com/donnemartin/system-design-primer-interview#sharding)
|
* [Sharding](https://github.com/donnemartin/system-design-primer#sharding)
|
||||||
* [Denormalization](https://github.com/donnemartin/system-design-primer-interview#denormalization)
|
* [Denormalization](https://github.com/donnemartin/system-design-primer#denormalization)
|
||||||
* [SQL Tuning](https://github.com/donnemartin/system-design-primer-interview#sql-tuning)
|
* [SQL Tuning](https://github.com/donnemartin/system-design-primer#sql-tuning)
|
||||||
|
|
||||||
We should also consider moving some data to a **NoSQL Database**.
|
We should also consider moving some data to a **NoSQL Database**.
|
||||||
|
|
||||||
|
@ -281,50 +281,50 @@ We should also consider moving some data to a **NoSQL Database**.
|
||||||
|
|
||||||
#### NoSQL
|
#### NoSQL
|
||||||
|
|
||||||
* [Key-value store](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Key-value store](https://github.com/donnemartin/system-design-primer#key-value-store)
|
||||||
* [Document store](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Document store](https://github.com/donnemartin/system-design-primer#document-store)
|
||||||
* [Wide column store](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Wide column store](https://github.com/donnemartin/system-design-primer#wide-column-store)
|
||||||
* [Graph database](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Graph database](https://github.com/donnemartin/system-design-primer#graph-database)
|
||||||
* [SQL vs NoSQL](https://github.com/donnemartin/system-design-primer-interview#)
|
* [SQL vs NoSQL](https://github.com/donnemartin/system-design-primer#sql-or-nosql)
|
||||||
|
|
||||||
### Caching
|
### Caching
|
||||||
|
|
||||||
* Where to cache
|
* Where to cache
|
||||||
* [Client caching](https://github.com/donnemartin/system-design-primer-interview#client-caching)
|
* [Client caching](https://github.com/donnemartin/system-design-primer#client-caching)
|
||||||
* [CDN caching](https://github.com/donnemartin/system-design-primer-interview#cdn-caching)
|
* [CDN caching](https://github.com/donnemartin/system-design-primer#cdn-caching)
|
||||||
* [Web server caching](https://github.com/donnemartin/system-design-primer-interview#web-server-caching)
|
* [Web server caching](https://github.com/donnemartin/system-design-primer#web-server-caching)
|
||||||
* [Database caching](https://github.com/donnemartin/system-design-primer-interview#database-caching)
|
* [Database caching](https://github.com/donnemartin/system-design-primer#database-caching)
|
||||||
* [Application caching](https://github.com/donnemartin/system-design-primer-interview#application-caching)
|
* [Application caching](https://github.com/donnemartin/system-design-primer#application-caching)
|
||||||
* What to cache
|
* What to cache
|
||||||
* [Caching at the database query level](https://github.com/donnemartin/system-design-primer-interview#caching-at-the-database-query-level)
|
* [Caching at the database query level](https://github.com/donnemartin/system-design-primer#caching-at-the-database-query-level)
|
||||||
* [Caching at the object level](https://github.com/donnemartin/system-design-primer-interview#caching-at-the-object-level)
|
* [Caching at the object level](https://github.com/donnemartin/system-design-primer#caching-at-the-object-level)
|
||||||
* When to update the cache
|
* When to update the cache
|
||||||
* [Cache-aside](https://github.com/donnemartin/system-design-primer-interview#cache-aside)
|
* [Cache-aside](https://github.com/donnemartin/system-design-primer#cache-aside)
|
||||||
* [Write-through](https://github.com/donnemartin/system-design-primer-interview#write-through)
|
* [Write-through](https://github.com/donnemartin/system-design-primer#write-through)
|
||||||
* [Write-behind (write-back)](https://github.com/donnemartin/system-design-primer-interview#write-behind-write-back)
|
* [Write-behind (write-back)](https://github.com/donnemartin/system-design-primer#write-behind-write-back)
|
||||||
* [Refresh ahead](https://github.com/donnemartin/system-design-primer-interview#refresh-ahead)
|
* [Refresh ahead](https://github.com/donnemartin/system-design-primer#refresh-ahead)
|
||||||
|
|
||||||
### Asynchronism and microservices
|
### Asynchronism and microservices
|
||||||
|
|
||||||
* [Message queues](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Message queues](https://github.com/donnemartin/system-design-primer#message-queues)
|
||||||
* [Task queues](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Task queues](https://github.com/donnemartin/system-design-primer#task-queues)
|
||||||
* [Back pressure](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Back pressure](https://github.com/donnemartin/system-design-primer#back-pressure)
|
||||||
* [Microservices](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Microservices](https://github.com/donnemartin/system-design-primer#microservices)
|
||||||
|
|
||||||
### Communications
|
### Communications
|
||||||
|
|
||||||
* Discuss tradeoffs:
|
* Discuss tradeoffs:
|
||||||
* External communication with clients - [HTTP APIs following REST](https://github.com/donnemartin/system-design-primer-interview#representational-state-transfer-rest)
|
* External communication with clients - [HTTP APIs following REST](https://github.com/donnemartin/system-design-primer#representational-state-transfer-rest)
|
||||||
* Internal communications - [RPC](https://github.com/donnemartin/system-design-primer-interview#remote-procedure-call-rpc)
|
* Internal communications - [RPC](https://github.com/donnemartin/system-design-primer#remote-procedure-call-rpc)
|
||||||
* [Service discovery](https://github.com/donnemartin/system-design-primer-interview#service-discovery)
|
* [Service discovery](https://github.com/donnemartin/system-design-primer#service-discovery)
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
||||||
Refer to the [security section](https://github.com/donnemartin/system-design-primer-interview#security).
|
Refer to the [security section](https://github.com/donnemartin/system-design-primer#security).
|
||||||
|
|
||||||
### Latency numbers
|
### Latency numbers
|
||||||
|
|
||||||
See [Latency numbers every programmer should know](https://github.com/donnemartin/system-design-primer-interview#latency-numbers-every-programmer-should-know).
|
See [Latency numbers every programmer should know](https://github.com/donnemartin/system-design-primer#latency-numbers-every-programmer-should-know).
|
||||||
|
|
||||||
### Ongoing
|
### Ongoing
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Design a web crawler
|
# Design a web crawler
|
||||||
|
|
||||||
*Note: This document links directly to relevant areas found in the [system design topics](https://github.com/donnemartin/system-design-primer-interview#index-of-system-design-topics-1) to avoid duplication. Refer to the linked content for general talking points, tradeoffs, and alternatives.*
|
*Note: This document links directly to relevant areas found in the [system design topics](https://github.com/donnemartin/system-design-primer#index-of-system-design-topics) to avoid duplication. Refer to the linked content for general talking points, tradeoffs, and alternatives.*
|
||||||
|
|
||||||
## Step 1: Outline use cases and constraints
|
## Step 1: Outline use cases and constraints
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ We'll assume we have an initial list of `links_to_crawl` ranked initially based
|
||||||
|
|
||||||
We'll use a table `crawled_links` to store processed links and their page signatures.
|
We'll use a table `crawled_links` to store processed links and their page signatures.
|
||||||
|
|
||||||
We could store `links_to_crawl` and `crawled_links` in a key-value **NoSQL Database**. For the ranked links in `links_to_crawl`, we could use [Redis](https://redis.io/) with sorted sets to maintain a ranking of page links. We should discuss the [use cases and tradeoffs between choosing SQL or NoSQL](https://github.com/donnemartin/system-design-primer-interview#sql-or-nosql).
|
We could store `links_to_crawl` and `crawled_links` in a key-value **NoSQL Database**. For the ranked links in `links_to_crawl`, we could use [Redis](https://redis.io/) with sorted sets to maintain a ranking of page links. We should discuss the [use cases and tradeoffs between choosing SQL or NoSQL](https://github.com/donnemartin/system-design-primer#sql-or-nosql).
|
||||||
|
|
||||||
* The **Crawler Service** processes each page link by doing the following in a loop:
|
* The **Crawler Service** processes each page link by doing the following in a loop:
|
||||||
* Takes the top ranked page link to crawl
|
* Takes the top ranked page link to crawl
|
||||||
|
@ -211,7 +211,7 @@ We might also choose to support a `Robots.txt` file that gives webmasters contro
|
||||||
|
|
||||||
### Use case: User inputs a search term and sees a list of relevant pages with titles and snippets
|
### Use case: User inputs a search term and sees a list of relevant pages with titles and snippets
|
||||||
|
|
||||||
* The **Client** sends a request to the **Web Server**, running as a [reverse proxy](https://github.com/donnemartin/system-design-primer-interview#reverse-proxy-web-server)
|
* The **Client** sends a request to the **Web Server**, running as a [reverse proxy](https://github.com/donnemartin/system-design-primer#reverse-proxy-web-server)
|
||||||
* The **Web Server** forwards the request to the **Query API** server
|
* The **Web Server** forwards the request to the **Query API** server
|
||||||
* The **Query API** server does does the following:
|
* The **Query API** server does does the following:
|
||||||
* Parses the query
|
* Parses the query
|
||||||
|
@ -224,7 +224,7 @@ We might also choose to support a `Robots.txt` file that gives webmasters contro
|
||||||
* The **Reverse Index Service** ranks the matching results and returns the top ones
|
* The **Reverse Index Service** ranks the matching results and returns the top ones
|
||||||
* Uses the **Document Service** to return titles and snippets
|
* Uses the **Document Service** to return titles and snippets
|
||||||
|
|
||||||
We'll use a public [**REST API**](https://github.com/donnemartin/system-design-primer-interview##representational-state-transfer-rest):
|
We'll use a public [**REST API**](https://github.com/donnemartin/system-design-primer#representational-state-transfer-rest):
|
||||||
|
|
||||||
```
|
```
|
||||||
$ curl https://search.com/api/v1/search?query=hello+world
|
$ curl https://search.com/api/v1/search?query=hello+world
|
||||||
|
@ -250,7 +250,7 @@ Response:
|
||||||
},
|
},
|
||||||
```
|
```
|
||||||
|
|
||||||
For internal communications, we could use [Remote Procedure Calls](https://github.com/donnemartin/system-design-primer-interview#remote-procedure-call-rpc).
|
For internal communications, we could use [Remote Procedure Calls](https://github.com/donnemartin/system-design-primer#remote-procedure-call-rpc).
|
||||||
|
|
||||||
## Step 4: Scale the design
|
## Step 4: Scale the design
|
||||||
|
|
||||||
|
@ -260,32 +260,32 @@ For internal communications, we could use [Remote Procedure Calls](https://githu
|
||||||
|
|
||||||
**Important: Do not simply jump right into the final design from the initial design!**
|
**Important: Do not simply jump right into the final design from the initial design!**
|
||||||
|
|
||||||
State you would 1) **Benchmark/Load Test**, 2) **Profile** for bottlenecks 3) address bottlenecks while evaluating alternatives and trade-offs, and 4) repeat. See [Design a system that scales to millions of users on AWS]() as a sample on how to iteratively scale the initial design.
|
State you would 1) **Benchmark/Load Test**, 2) **Profile** for bottlenecks 3) address bottlenecks while evaluating alternatives and trade-offs, and 4) repeat. See [Design a system that scales to millions of users on AWS](https://github.com/donnemartin/system-design-primer/blob/master/solutions/system_design/scaling_aws/README.md) as a sample on how to iteratively scale the initial design.
|
||||||
|
|
||||||
It's important to discuss what bottlenecks you might encounter with the initial design and how you might address each of them. For example, what issues are addressed by adding a **Load Balancer** with multiple **Web Servers**? **CDN**? **Master-Slave Replicas**? What are the alternatives and **Trade-Offs** for each?
|
It's important to discuss what bottlenecks you might encounter with the initial design and how you might address each of them. For example, what issues are addressed by adding a **Load Balancer** with multiple **Web Servers**? **CDN**? **Master-Slave Replicas**? What are the alternatives and **Trade-Offs** for each?
|
||||||
|
|
||||||
We'll introduce some components to complete the design and to address scalability issues. Internal load balancers are not shown to reduce clutter.
|
We'll introduce some components to complete the design and to address scalability issues. Internal load balancers are not shown to reduce clutter.
|
||||||
|
|
||||||
*To avoid repeating discussions*, refer to the following [system design topics](https://github.com/donnemartin/system-design-primer-interview#) for main talking points, tradeoffs, and alternatives:
|
*To avoid repeating discussions*, refer to the following [system design topics](https://github.com/donnemartin/system-design-primer#index-of-system-design-topics) for main talking points, tradeoffs, and alternatives:
|
||||||
|
|
||||||
* [DNS](https://github.com/donnemartin/system-design-primer-interview#domain-name-system)
|
* [DNS](https://github.com/donnemartin/system-design-primer#domain-name-system)
|
||||||
* [Load balancer](https://github.com/donnemartin/system-design-primer-interview#load-balancer)
|
* [Load balancer](https://github.com/donnemartin/system-design-primer#load-balancer)
|
||||||
* [Horizontal scaling](https://github.com/donnemartin/system-design-primer-interview#horizontal-scaling)
|
* [Horizontal scaling](https://github.com/donnemartin/system-design-primer#horizontal-scaling)
|
||||||
* [Web server (reverse proxy)](https://github.com/donnemartin/system-design-primer-interview#reverse-proxy-web-server)
|
* [Web server (reverse proxy)](https://github.com/donnemartin/system-design-primer#reverse-proxy-web-server)
|
||||||
* [API server (application layer)](https://github.com/donnemartin/system-design-primer-interview#application-layer)
|
* [API server (application layer)](https://github.com/donnemartin/system-design-primer#application-layer)
|
||||||
* [Cache](https://github.com/donnemartin/system-design-primer-interview#cache)
|
* [Cache](https://github.com/donnemartin/system-design-primer#cache)
|
||||||
* [NoSQL](https://github.com/donnemartin/system-design-primer-interview#nosql)
|
* [NoSQL](https://github.com/donnemartin/system-design-primer#nosql)
|
||||||
* [Consistency patterns](https://github.com/donnemartin/system-design-primer-interview#consistency-patterns)
|
* [Consistency patterns](https://github.com/donnemartin/system-design-primer#consistency-patterns)
|
||||||
* [Availability patterns](https://github.com/donnemartin/system-design-primer-interview#availability-patterns)
|
* [Availability patterns](https://github.com/donnemartin/system-design-primer#availability-patterns)
|
||||||
|
|
||||||
Some searches are very popular, while others are only executed once. Popular queries can be served from a **Memory Cache** such as Redis or Memcached to reduce response times and to avoid overloading the **Reverse Index Service** and **Document Service**. The **Memory Cache** is also useful for handling the unevenly distributed traffic and traffic spikes. Reading 1 MB sequentially from memory takes about 250 microseconds, while reading from SSD takes 4x and from disk takes 80x longer.<sup><a href=https://github.com/donnemartin/system-design-primer-interview#latency-numbers-every-programmer-should-know>1</a></sup>
|
Some searches are very popular, while others are only executed once. Popular queries can be served from a **Memory Cache** such as Redis or Memcached to reduce response times and to avoid overloading the **Reverse Index Service** and **Document Service**. The **Memory Cache** is also useful for handling the unevenly distributed traffic and traffic spikes. Reading 1 MB sequentially from memory takes about 250 microseconds, while reading from SSD takes 4x and from disk takes 80x longer.<sup><a href=https://github.com/donnemartin/system-design-primer#latency-numbers-every-programmer-should-know>1</a></sup>
|
||||||
|
|
||||||
Below are a few other optimizations to the **Crawling Service**:
|
Below are a few other optimizations to the **Crawling Service**:
|
||||||
|
|
||||||
* To handle the data size and request load, the **Reverse Index Service** and **Document Service** will likely need to make heavy use sharding and replication.
|
* To handle the data size and request load, the **Reverse Index Service** and **Document Service** will likely need to make heavy use sharding and replication.
|
||||||
* DNS lookup can be a bottleneck, the **Crawler Service** can keep its own DNS lookup that is refreshed periodically
|
* DNS lookup can be a bottleneck, the **Crawler Service** can keep its own DNS lookup that is refreshed periodically
|
||||||
* The **Crawler Service** can improve performance and reduce memory usage by keeping many open connections at a time, referred to as [connection pooling](https://en.wikipedia.org/wiki/Connection_pool)
|
* The **Crawler Service** can improve performance and reduce memory usage by keeping many open connections at a time, referred to as [connection pooling](https://en.wikipedia.org/wiki/Connection_pool)
|
||||||
* Switching to [UDP](https://github.com/donnemartin/system-design-primer-interview#user-datagram-protocol-udp) could also boost performance
|
* Switching to [UDP](https://github.com/donnemartin/system-design-primer#user-datagram-protocol-udp) could also boost performance
|
||||||
* Web crawling is bandwidth intensive, ensure there is enough bandwidth to sustain high throughput
|
* Web crawling is bandwidth intensive, ensure there is enough bandwidth to sustain high throughput
|
||||||
|
|
||||||
## Additional talking points
|
## Additional talking points
|
||||||
|
@ -294,58 +294,58 @@ Below are a few other optimizations to the **Crawling Service**:
|
||||||
|
|
||||||
### SQL scaling patterns
|
### SQL scaling patterns
|
||||||
|
|
||||||
* [Read replicas](https://github.com/donnemartin/system-design-primer-interview#master-slave)
|
* [Read replicas](https://github.com/donnemartin/system-design-primer#master-slave)
|
||||||
* [Federation](https://github.com/donnemartin/system-design-primer-interview#federation)
|
* [Federation](https://github.com/donnemartin/system-design-primer#federation)
|
||||||
* [Sharding](https://github.com/donnemartin/system-design-primer-interview#sharding)
|
* [Sharding](https://github.com/donnemartin/system-design-primer#sharding)
|
||||||
* [Denormalization](https://github.com/donnemartin/system-design-primer-interview#denormalization)
|
* [Denormalization](https://github.com/donnemartin/system-design-primer#denormalization)
|
||||||
* [SQL Tuning](https://github.com/donnemartin/system-design-primer-interview#sql-tuning)
|
* [SQL Tuning](https://github.com/donnemartin/system-design-primer#sql-tuning)
|
||||||
|
|
||||||
#### NoSQL
|
#### NoSQL
|
||||||
|
|
||||||
* [Key-value store](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Key-value store](https://github.com/donnemartin/system-design-primer#key-value-store)
|
||||||
* [Document store](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Document store](https://github.com/donnemartin/system-design-primer#document-store)
|
||||||
* [Wide column store](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Wide column store](https://github.com/donnemartin/system-design-primer#wide-column-store)
|
||||||
* [Graph database](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Graph database](https://github.com/donnemartin/system-design-primer#graph-database)
|
||||||
* [SQL vs NoSQL](https://github.com/donnemartin/system-design-primer-interview#)
|
* [SQL vs NoSQL](https://github.com/donnemartin/system-design-primer#sql-or-nosql)
|
||||||
|
|
||||||
### Caching
|
### Caching
|
||||||
|
|
||||||
* Where to cache
|
* Where to cache
|
||||||
* [Client caching](https://github.com/donnemartin/system-design-primer-interview#client-caching)
|
* [Client caching](https://github.com/donnemartin/system-design-primer#client-caching)
|
||||||
* [CDN caching](https://github.com/donnemartin/system-design-primer-interview#cdn-caching)
|
* [CDN caching](https://github.com/donnemartin/system-design-primer#cdn-caching)
|
||||||
* [Web server caching](https://github.com/donnemartin/system-design-primer-interview#web-server-caching)
|
* [Web server caching](https://github.com/donnemartin/system-design-primer#web-server-caching)
|
||||||
* [Database caching](https://github.com/donnemartin/system-design-primer-interview#database-caching)
|
* [Database caching](https://github.com/donnemartin/system-design-primer#database-caching)
|
||||||
* [Application caching](https://github.com/donnemartin/system-design-primer-interview#application-caching)
|
* [Application caching](https://github.com/donnemartin/system-design-primer#application-caching)
|
||||||
* What to cache
|
* What to cache
|
||||||
* [Caching at the database query level](https://github.com/donnemartin/system-design-primer-interview#caching-at-the-database-query-level)
|
* [Caching at the database query level](https://github.com/donnemartin/system-design-primer#caching-at-the-database-query-level)
|
||||||
* [Caching at the object level](https://github.com/donnemartin/system-design-primer-interview#caching-at-the-object-level)
|
* [Caching at the object level](https://github.com/donnemartin/system-design-primer#caching-at-the-object-level)
|
||||||
* When to update the cache
|
* When to update the cache
|
||||||
* [Cache-aside](https://github.com/donnemartin/system-design-primer-interview#cache-aside)
|
* [Cache-aside](https://github.com/donnemartin/system-design-primer#cache-aside)
|
||||||
* [Write-through](https://github.com/donnemartin/system-design-primer-interview#write-through)
|
* [Write-through](https://github.com/donnemartin/system-design-primer#write-through)
|
||||||
* [Write-behind (write-back)](https://github.com/donnemartin/system-design-primer-interview#write-behind-write-back)
|
* [Write-behind (write-back)](https://github.com/donnemartin/system-design-primer#write-behind-write-back)
|
||||||
* [Refresh ahead](https://github.com/donnemartin/system-design-primer-interview#refresh-ahead)
|
* [Refresh ahead](https://github.com/donnemartin/system-design-primer#refresh-ahead)
|
||||||
|
|
||||||
### Asynchronism and microservices
|
### Asynchronism and microservices
|
||||||
|
|
||||||
* [Message queues](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Message queues](https://github.com/donnemartin/system-design-primer#message-queues)
|
||||||
* [Task queues](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Task queues](https://github.com/donnemartin/system-design-primer#task-queues)
|
||||||
* [Back pressure](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Back pressure](https://github.com/donnemartin/system-design-primer#back-pressure)
|
||||||
* [Microservices](https://github.com/donnemartin/system-design-primer-interview#)
|
* [Microservices](https://github.com/donnemartin/system-design-primer#microservices)
|
||||||
|
|
||||||
### Communications
|
### Communications
|
||||||
|
|
||||||
* Discuss tradeoffs:
|
* Discuss tradeoffs:
|
||||||
* External communication with clients - [HTTP APIs following REST](https://github.com/donnemartin/system-design-primer-interview#representational-state-transfer-rest)
|
* External communication with clients - [HTTP APIs following REST](https://github.com/donnemartin/system-design-primer#representational-state-transfer-rest)
|
||||||
* Internal communications - [RPC](https://github.com/donnemartin/system-design-primer-interview#remote-procedure-call-rpc)
|
* Internal communications - [RPC](https://github.com/donnemartin/system-design-primer#remote-procedure-call-rpc)
|
||||||
* [Service discovery](https://github.com/donnemartin/system-design-primer-interview#service-discovery)
|
* [Service discovery](https://github.com/donnemartin/system-design-primer#service-discovery)
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
||||||
Refer to the [security section](https://github.com/donnemartin/system-design-primer-interview#security).
|
Refer to the [security section](https://github.com/donnemartin/system-design-primer#security).
|
||||||
|
|
||||||
### Latency numbers
|
### Latency numbers
|
||||||
|
|
||||||
See [Latency numbers every programmer should know](https://github.com/donnemartin/system-design-primer-interview#latency-numbers-every-programmer-should-know).
|
See [Latency numbers every programmer should know](https://github.com/donnemartin/system-design-primer#latency-numbers-every-programmer-should-know).
|
||||||
|
|
||||||
### Ongoing
|
### Ongoing
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue