feat: integrate system design
No files matched your search
@@ -0,0 +1,265 @@
|
||||
---
|
||||
title: "Scale from Zero to Millions of Users"
|
||||
description: "Grow a single server into a multi-data-center system: load balancers, replication, caching, CDNs, a stateless web tier, queues and sharding."
|
||||
icon: trending-up
|
||||
sidebar:
|
||||
label: "Scaling"
|
||||
---
|
||||
|
||||
## Introduction
|
||||
Scaling a system to support millions of users is a complex, iterative journey requiring refinement and optimization. This chapter outlines how to begin with a single server setup and scale the architecture step by step to handle millions of users.
|
||||
|
||||
---
|
||||
|
||||
## Single Server Setup
|
||||
Initially, all components (web app, database, cache) run on a single server.
|
||||
|
||||
<Frame caption="Single server">
|
||||
|
||||

|
||||
|
||||
</Frame>
|
||||
|
||||
### Request Flow
|
||||
1. Users access the application via domain names (e.g., `api.mysite.com`), resolved to IP addresses using DNS.
|
||||
2. IP address of the web-server is returned to the browser or mobile app.
|
||||
3. HTTP requests are sent to the web server, which returns HTML or JSON responses.
|
||||
|
||||
### Traffic Sources
|
||||
1. **Web Applications:** Use server-side languages (e.g., Python, Java) for business logic and client-side languages (e.g., JavaScript, HTML) for presentation.
|
||||
2. **Mobile Applications:** Communicate with the web server using HTTP and JSON for lightweight data exchange.
|
||||
|
||||
---
|
||||
|
||||
## Database Separation
|
||||
As the user base grows, the database is moved to a dedicated server to allow independent scaling of web and database tiers.
|
||||
|
||||
<Frame caption="Database">
|
||||
|
||||

|
||||
|
||||
</Frame>
|
||||
|
||||
### Database Choices
|
||||
|
||||
1. **Relational Databases (SQL):** Structured data stored in tables. Examples: MySQL, PostgreSQL.
|
||||
2. **Non-Relational Databases (NoSQL):** Suitable for unstructured data or low-latency requirements. Categories include:
|
||||
- Key-Value Stores
|
||||
- Graph Databases
|
||||
- Column Stores
|
||||
- Document Stores
|
||||
|
||||
- Non-relational databases might be the right choice if:
|
||||
- application requires super-low latency.
|
||||
- data is unstructured, or there is no relational data.
|
||||
- only need to serialize and deserialize data (JSON, XML, YAML, etc.).
|
||||
- need to store a massive amount of data.
|
||||
|
||||
---
|
||||
|
||||
## Vertical vs Horizontal Scaling
|
||||
### Vertical Scaling
|
||||
- Adds more resources (CPU, RAM) to existing servers.
|
||||
- Limited by hardware constraints and lacks redundancy.
|
||||
|
||||
### Horizontal Scaling
|
||||
- Adds more servers to the pool, making it more suitable for large-scale systems.
|
||||
- A load balancer is used to handle the request routing between the servers.
|
||||
|
||||
---
|
||||
|
||||
## Load Balancer
|
||||
|
||||
<Frame caption="Load balancer">
|
||||
|
||||

|
||||
|
||||
</Frame>
|
||||
|
||||
A **load balancer** distributes traffic among multiple servers. Benefits include:
|
||||
1. Redundancy: If a server goes offline, traffic is rerouted.
|
||||
- If server 1 goes offline, all the traffic will be routed to server 2.
|
||||
2. Scalability: Easily add servers to handle traffic spikes.
|
||||
- If the website traffic grows rapidly, subsequent servers can be added to handle the additional traffic.
|
||||
|
||||
---
|
||||
|
||||
## Database Replication
|
||||
|
||||
<Frame caption="Database replication">
|
||||
|
||||

|
||||
|
||||
</Frame>
|
||||
|
||||
### Master-Slave Model
|
||||
- **Master Database:** Handles write operations.
|
||||
- All the data-modifying commands like insert, delete, or update must be sent to the master database.
|
||||
- **Slave Databases:** Handle read operations, improving performance and reliability.
|
||||
- Since the ratio of reads to writes is higher in most applications; thus, the number of slave
|
||||
databases in a system is usually larger than the number of master databases.
|
||||
|
||||
### Benefits
|
||||
1. Improved performance through parallel read operations.
|
||||
2. High availability and data reliability through redundancy.
|
||||
|
||||
### Failure Handling
|
||||
- If only one slave database is available and it goes offline, read operations will be directed
|
||||
to the master database temporarily.
|
||||
- In case multiple slave databases are available, read operations are
|
||||
redirected to other healthy slave databases and a new server will replace the old one.
|
||||
- If the master database goes offline, a slave database will be promoted to be the new
|
||||
master.
|
||||
- In production system the chosen slave database might not be up to date, hence data needs to be updated by running data
|
||||
recovery scripts (methods like multi-masters and circular replication could help).
|
||||
|
||||
---
|
||||
|
||||
## Caching
|
||||
A **cache** stores frequently accessed data in memory to reduce database load. The cache tier is a temporary data store layer, much faster than the database.
|
||||
|
||||
<Frame caption="Cache">
|
||||
|
||||

|
||||
|
||||
</Frame>
|
||||
|
||||
### Caching considerations
|
||||
1. **Use case**: Consider using cache when data is read frequently but modified infrequently.
|
||||
2. **Expiration Policies:** Once cached data is expired, it is removed from the cache. When there is no expiration policy, cached
|
||||
data will be stored in the memory permanently.
|
||||
3. **Consistency:** This means keeping the data store and the cache in sync. Inconsistency
|
||||
can happen because data-modifying operations on the data store and cache are not in a single transaction.
|
||||
4. **Mitigating failures**: A single cache server represents a potential single point of failure, multiple
|
||||
cache servers across different data centers are recommended to avoid SPOF.
|
||||
5. **Eviction Policies:**: Once the cache is full, items need to be evicted to free up memory. LRU is the most popular cache eviction policy.
|
||||
|
||||
---
|
||||
|
||||
## Content Delivery Network (CDN)
|
||||
A **CDN** improves load times by caching static content (images, CSS, JavaScript) on geographically distributed servers.
|
||||
|
||||
<Frame caption="Cdn">
|
||||
|
||||

|
||||
|
||||
</Frame>
|
||||
|
||||
### Workflow
|
||||
1. User requests content from the nearest CDN server.
|
||||
2. If unavailable, content is fetched from the origin server and cached.
|
||||
|
||||
### CDN considerations
|
||||
1. **Cost:** CDNs are run by third-party providers which charge for data transfers in and out of the CDN.
|
||||
2. **Cache Expiry:** The cache expiry time should neither be too long nor too short.
|
||||
3. **CDN fallback:** If there is a temporary CDN outage, clients should be able to detect the problem
|
||||
and request resources from the origin.
|
||||
4. **Invalidating files:** If files are updated the cache should be invalidated to point to the updated files.
|
||||
|
||||
---
|
||||
|
||||
## Stateless Web Tier
|
||||
By moving session data to a shared datastore, web servers become stateless. This allows:
|
||||
1. Easier horizontal scaling.
|
||||
2. Auto-scaling based on traffic.
|
||||
|
||||
<Frame caption="Stateless">
|
||||
|
||||

|
||||
|
||||
</Frame>
|
||||
|
||||
---
|
||||
|
||||
## Multi-Data Center Setup
|
||||
Deploying across multiple data centers improves availability and reduces latency. Strategies include:
|
||||
|
||||
<Frame caption="Data center">
|
||||
|
||||

|
||||
|
||||
</Frame>
|
||||
|
||||
1. **GeoDNS Routing:** Direct users to the nearest data center.
|
||||
2. **Data Replication:** Synchronize data across centers to prevent inconsistencies.
|
||||
|
||||
### Key considerations
|
||||
- **Traffic redirection:** Effective tools are needed to direct traffic to the correct data center.
|
||||
- **Data synchronization:** A common strategy is to replicate data across multiple data centers.
|
||||
- **Test and deployment:** Automated deployment tools are vital to keep services consistent through all the data centers.
|
||||
|
||||
---
|
||||
|
||||
## Message Queue
|
||||
A **message queue** is a durable component, stored in memory, that supports asynchronous
|
||||
communication. It serves as a buffer and distributes asynchronous requests.
|
||||
|
||||
<Frame caption="Message queue">
|
||||
|
||||

|
||||
|
||||
</Frame>
|
||||
|
||||
- Input services, called producers/publishers, create messages, and publish them to a message queue.
|
||||
- Other services called consumers/subscribers, connect to the queue, and perform actions defined by the messages.
|
||||
|
||||
---
|
||||
|
||||
## Logging, Metrics, and Automation
|
||||
|
||||
<Frame caption="Logging">
|
||||
|
||||

|
||||
|
||||
</Frame>
|
||||
|
||||
### Importance
|
||||
1. **Logging:** Tracks errors and system health.
|
||||
2. **Metrics:** Provides insights into performance and user activity.
|
||||
3. **Automation:** Streamlines testing, deployment, and scaling.
|
||||
|
||||
---
|
||||
|
||||
## Database Scaling
|
||||
### Vertical Scaling
|
||||
- Adds hardware resources but has physical and cost limitations.
|
||||
- Has multiple drawbacks:
|
||||
- Greater risk of single point of failures.
|
||||
- Overall cost of vertical scaling is high
|
||||
|
||||
### Horizontal Scaling (Sharding)
|
||||
|
||||
<Frame caption="Horizontal scaling">
|
||||
|
||||

|
||||
|
||||
</Frame>
|
||||
|
||||
- Divides data across multiple shards using keys (e.g., `user_id`).
|
||||
- Sharding separates large databases into smaller, more easily managed parts called shards.
|
||||
- Each shard shares the same schema, though the actual data on each shard is unique to the shard.
|
||||
- Sharding key is critical when implementing a sharding strategy. When choosing a sharding key it is important to choose a key that can evenly distribute data.
|
||||
|
||||
#### Challenges
|
||||
1. **Resharding data:** Resharding data is needed when:
|
||||
- Single shard could no longer hold more data due to rapid growth.
|
||||
- Certain shards might experience shard exhaustion faster than others due to uneven data distribution.
|
||||
- Consistent Hashing is used to overcome these problems
|
||||
|
||||
2. **Celebrity problem:** Excessive access to a specific shard could cause server overload.
|
||||
- To solve this problem, we may need to allocate a shard for each celebrity.
|
||||
|
||||
3. **Join and de-normalization:** Once a database has been sharded across multiple servers, it is hard to perform join operations across database shards.
|
||||
- A common workaround is to de-normalize the database so that queries can be performed in a single table.
|
||||
|
||||
---
|
||||
|
||||
## Conclusion
|
||||
### Key Takeaways
|
||||
1. Keep the web tier stateless.
|
||||
2. Build redundancy at every tier.
|
||||
3. Use caching and CDNs to optimize performance.
|
||||
4. Scale the data tier with sharding.
|
||||
5. Decouple components for flexibility.
|
||||
|
||||
This chapter provides a solid foundation for building scalable systems that can handle millions of users.
|
||||
@@ -0,0 +1,109 @@
|
||||
---
|
||||
title: "Back-of-the-Envelope Estimation"
|
||||
description: "Powers of two, latency numbers and availability figures, and how to estimate QPS and storage quickly in an interview."
|
||||
icon: calculator
|
||||
sidebar:
|
||||
label: "Estimation"
|
||||
---
|
||||
|
||||
## Introduction
|
||||
Back-of-the-envelope estimation is a crucial skill in system design interviews. It involves making quick, rough calculations to assess system capacity or performance. According to Jeff Dean, Google Senior Fellow, these estimates help evaluate whether designs meet requirements through thought experiments and common performance benchmarks.
|
||||
|
||||
This chapter covers key concepts, methodologies, and examples to build proficiency in scalability and estimation.
|
||||
|
||||
---
|
||||
|
||||
## Key Concepts
|
||||
|
||||
### Power of Two
|
||||
Understanding data volume in terms of powers of two is fundamental:
|
||||
|
||||
<Frame caption="Powers of two">
|
||||
|
||||

|
||||
|
||||
</Frame>
|
||||
|
||||
This knowledge helps in performing accurate storage and bandwidth calculations.
|
||||
|
||||
---
|
||||
|
||||
### Latency Numbers Every Programmer Should Know
|
||||
Latency numbers represent the time taken for various operations in computing systems. These provide insights into relative performance:
|
||||
|
||||
| Operation | Latency (2020) |
|
||||
|--------------------------|----------------|
|
||||
| L1 Cache Access | 0.5 ns |
|
||||
| L2 Cache Access | 7 ns |
|
||||
| Main Memory Access | 100 ns |
|
||||
| SSD Random Read | 150 µs |
|
||||
| HDD Random Seek | 10 ms |
|
||||
| Round-Trip in Data Center| 500 µs |
|
||||
| Inter-Region Data Center | 150 ms |
|
||||
|
||||
:::tip[Key insights]
|
||||
- Memory is fast, disk is slow.
|
||||
- Avoid disk seeks whenever possible.
|
||||
- Compress data before transmitting over the internet to save bandwidth.
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
### Availability Numbers
|
||||
High availability (HA) ensures minimal downtime. Availability is expressed in **nines**:
|
||||
|
||||
| Availability | Downtime per year |
|
||||
| --- | --- |
|
||||
| 99% (two nines) | ~3.65 days |
|
||||
| 99.9% (three nines) | ~8.8 hours |
|
||||
| 99.99% (four nines) | ~52 minutes |
|
||||
| 99.999% (five nines) | ~5.3 minutes |
|
||||
| 99.9999% (six nines) | ~31.56 seconds |
|
||||
|
||||
Cloud providers like Amazon, Google, and Microsoft aim for SLAs (Service Level Agreements) of **99.9% or higher**.
|
||||
|
||||
---
|
||||
|
||||
## Example Estimation - Twitter QPS and Storage Requirements
|
||||
|
||||
### Assumptions
|
||||
- **300 million monthly active users (MAU).**
|
||||
- **50% daily active users (DAU).**
|
||||
- **Average tweets/user/day:** 2.
|
||||
- **10% of tweets contain media.**
|
||||
- **Data retention:** 5 years.
|
||||
|
||||
### Estimations
|
||||
1. **Query Per Second (QPS):**
|
||||
- DAU: $$300\text{M} \times 50\% = 150\text{M}$$
|
||||
- Tweets QPS: $$150\text{M} \times 2 \text{ tweets} / 24 \text{ h} / 3600 \text{ s} \approx 3500$$
|
||||
- Peak QPS: $$2 \times 3500 \approx 7000$$
|
||||
|
||||
2. **Media Storage:**
|
||||
- **Tweet Size Components:**
|
||||
- `tweet_id`: 64 bytes
|
||||
- `text`: 140 bytes
|
||||
- `media`: 1 MB
|
||||
- **Daily Media Storage:** $$150\text{M} \times 2 \times 10\% \times 1\text{ MB} = 30\text{ TB/day}$$
|
||||
- **5-Year Storage:** $$30\text{ TB} \times 365 \times 5 \approx 55\text{ PB}$$
|
||||
|
||||
---
|
||||
|
||||
## Tips for Effective Estimation
|
||||
|
||||
### 1. Rounding and Approximation
|
||||
Precision is not critical; focus on the process. Simplify complex calculations using round numbers. For example:
|
||||
- $$99987 / 9.1$$ can be approximated as $$100{,}000 / 10 = 10{,}000$$.
|
||||
|
||||
### 2. Write Down Assumptions
|
||||
Document assumptions clearly for future reference.
|
||||
|
||||
### 3. Label Units
|
||||
Avoid ambiguity by labeling units (e.g., `5 MB` instead of `5`).
|
||||
|
||||
### 4. Common Estimation Scenarios
|
||||
- **QPS (Queries Per Second):** Measure traffic intensity.
|
||||
- **Peak QPS:** Account for traffic spikes.
|
||||
- **Storage Requirements:** Estimate total data needs.
|
||||
- **Cache Requirements:** Evaluate memory requirements for caching.
|
||||
- **Number of Servers:** Calculate hardware needs based on workload.
|
||||
@@ -0,0 +1,125 @@
|
||||
---
|
||||
title: "A Framework for System Design Interviews"
|
||||
description: "A four-step process for the interview: scope the problem, propose a high-level design, dive deep, and wrap up."
|
||||
icon: list-checks
|
||||
sidebar:
|
||||
label: "Interview Framework"
|
||||
---
|
||||
|
||||
## Introduction
|
||||
System design interviews are a key part of the hiring process, simulating real-life problem-solving scenarios. These interviews evaluate not just technical skills but also collaboration, communication, and the ability to handle ambiguous requirements.
|
||||
|
||||
This chapter introduces a **4-step framework** for navigating system design interviews effectively.
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Understand the Problem and Establish Design Scope
|
||||
|
||||
### Key Objectives
|
||||
- Clarify requirements and assumptions.
|
||||
- Avoid jumping into solutions prematurely.
|
||||
- Showcase critical thinking by asking good questions.
|
||||
|
||||
### Approach
|
||||
- **Ask Clarifying Questions:**
|
||||
- What are the most important features?
|
||||
- What scale does the system need to handle?
|
||||
- Are we building for web, mobile, or both?
|
||||
- Are there existing technologies or constraints?
|
||||
|
||||
- **Document Assumptions:** Write assumptions on a whiteboard or paper for reference.
|
||||
|
||||
### Example
|
||||
**Problem:** Design a news feed system.
|
||||
**Questions:**
|
||||
- Is it a mobile app, web app, or both?
|
||||
- How many friends can a user have?
|
||||
- Should the feed include images and videos?
|
||||
- Is the feed sorted by reverse chronological order?
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Propose High-Level Design and Get Buy-In
|
||||
|
||||
### Key Objectives
|
||||
- Develop a high-level architecture.
|
||||
- Collaborate with the interviewer to refine the design.
|
||||
|
||||
### Approach
|
||||
- **Draft a Blueprint:**
|
||||
- Use box diagrams for key components (e.g., clients, APIs, databases, caches, CDNs).
|
||||
- Treat the interviewer as a teammate to refine the design.
|
||||
|
||||
- **Perform Back-of-the-Envelope Calculations:**
|
||||
- Ensure the design can handle the scale constraints.
|
||||
|
||||
- **Walk Through Use Cases:** Identify edge cases and validate design assumptions.
|
||||
|
||||
### Example
|
||||
For a news feed system, divide the design into:
|
||||
1. **Feed Publishing Flow:** Writing posts into databases and populating friends' feeds.
|
||||
2. **Feed Retrieval Flow:** Aggregating and displaying friends' posts in reverse chronological order.
|
||||
|
||||
---
|
||||
|
||||
## Step 3: Design Deep Dive
|
||||
|
||||
### Key Objectives
|
||||
- Dive into critical components.
|
||||
- Showcase depth of understanding and adaptability.
|
||||
|
||||
### Approach
|
||||
- **Prioritize Key Components:** Focus on areas most relevant to the problem.
|
||||
- **Discuss Bottlenecks:** Identify potential performance issues and propose solutions.
|
||||
- **Balance Detail:** Avoid over-engineering or unnecessary deep dives.
|
||||
|
||||
### Example Topics
|
||||
- **URL Shortener:** Focus on hash function design.
|
||||
- **Chat System:** Explore latency reduction and online/offline status handling.
|
||||
- **News Feed System:** Examine feed publishing and retrieval processes.
|
||||
|
||||
---
|
||||
|
||||
## Step 4: Wrap-Up
|
||||
|
||||
### Key Objectives
|
||||
- Highlight areas for improvement.
|
||||
- Recap the design and discuss follow-ups.
|
||||
|
||||
### Approach
|
||||
- **Identify Bottlenecks:** Discuss potential limitations and scaling strategies.
|
||||
- **Summarize Design:** Recap major design decisions and trade-offs.
|
||||
- **Propose Enhancements:**
|
||||
- How to scale from 1 million to 10 million users.
|
||||
- Error handling for server failures or network issues.
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
:::tip[Do]
|
||||
- **Ask Questions:** Clarify ambiguities before diving into solutions.
|
||||
- **Communicate:** Share your thought process with the interviewer.
|
||||
- **Iterate with the Interviewer:** Treat them as a collaborator.
|
||||
- **Show Flexibility:** Suggest alternative approaches and refine your design.
|
||||
- **Focus on Critical Components:** Prioritize key parts of the system.
|
||||
:::
|
||||
|
||||
:::warning[Don't]
|
||||
- **Avoid Premature Solutions:** Don’t design before understanding the requirements.
|
||||
- **Don’t Go Silent:** Communicate regularly during the process.
|
||||
- **Avoid Over-Engineering:** Focus on practical, scalable solutions.
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## Time Management
|
||||
|
||||
Suggested split of a 45-minute interview:
|
||||
|
||||
| Step | Time |
|
||||
| --- | --- |
|
||||
| 1. Understand the problem and scope | 3–10 minutes |
|
||||
| 2. High-level design and buy-in | 10–15 minutes |
|
||||
| 3. Deep dive | 10–25 minutes |
|
||||
| 4. Wrap-up | 3–5 minutes |
|
||||
|
After Width: | Height: | Size: 190 KiB |
|
After Width: | Height: | Size: 107 KiB |
|
After Width: | Height: | Size: 213 KiB |
|
After Width: | Height: | Size: 487 KiB |
|
After Width: | Height: | Size: 547 KiB |
|
After Width: | Height: | Size: 201 KiB |
|
After Width: | Height: | Size: 203 KiB |
|
After Width: | Height: | Size: 308 KiB |
|
After Width: | Height: | Size: 375 KiB |
|
After Width: | Height: | Size: 111 KiB |
|
After Width: | Height: | Size: 161 KiB |
|
After Width: | Height: | Size: 173 KiB |
@@ -0,0 +1,3 @@
|
||||
import { defineMeta } from "blume";
|
||||
|
||||
export default defineMeta({ title: "Foundations", order: 1 });
|
||||