Kiến trúc hệ thốngThiết kế hệ thống mở rộng tới hàng triệu người dùng trên AWS

Thiết kế hệ thống mở rộng tới hàng triệu người dùng trên AWS

Nội dung bài

Thiết kế hệ thống mở rộng tới hàng triệu người dùng trên AWS

Bài tập25 phút đọcThe System Design Primer - bài giải "Design a system that scales to millions of users on AWS"

Mục lục
  1. Nội dung gốc
  2. Ghi chú của người dịch

Thiết kế hệ thống mở rộng tới hàng triệu người dùng trên AWS

Nội dung gốc

Lưu ý: Tài liệu này liên kết thẳng tới các phần liên quan trong danh mục chủ đề system design để tránh lặp lại. Hãy tham khảo nội dung được liên kết để nắm các ý chính cần trình bày, các đánh đổi (tradeoff) và các phương án thay thế.

Bước 1: Phác thảo các trường hợp sử dụng và ràng buộc

Thu thập yêu cầu và khoanh vùng bài toán. Đặt câu hỏi để làm rõ các trường hợp sử dụng (use case) và ràng buộc (constraint). Thảo luận các giả định.

Vì không có người phỏng vấn để trả lời các câu hỏi làm rõ, ta sẽ tự định nghĩa một số trường hợp sử dụng và ràng buộc.

Các trường hợp sử dụng (use cases)

Giải bài toán này theo cách tiếp cận lặp: 1) Đo hiệu năng/Kiểm thử tải (Benchmark/Load Test), 2) Phân tích hiệu năng (Profile) để tìm nút thắt cổ chai (bottleneck), 3) xử lý nút thắt đồng thời đánh giá các phương án thay thế và đánh đổi, và 4) lặp lại. Đây là một khuôn mẫu tốt để phát triển các thiết kế cơ bản thành thiết kế có khả năng mở rộng.

Trừ khi bạn có nền tảng về AWS hoặc đang ứng tuyển vào vị trí đòi hỏi kiến thức AWS, các chi tiết riêng của AWS không phải là yêu cầu bắt buộc. Tuy nhiên, phần lớn các nguyên tắc được bàn trong bài tập này có thể áp dụng rộng rãi bên ngoài hệ sinh thái AWS.

Ta khoanh vùng bài toán, chỉ xử lý các trường hợp sử dụng sau

Ràng buộc và giả định

Nêu các giả định
Tính toán mức sử dụng

Hãy hỏi rõ người phỏng vấn xem bạn có nên làm các phép ước lượng nhanh (back-of-the-envelope) về mức sử dụng hay không.

Bảng quy đổi tiện dụng:

Bước 2: Tạo thiết kế tổng quan (high level design)

Phác thảo thiết kế tổng quan với tất cả các thành phần quan trọng.

Sơ đồ thiết kế tổng quan: Client, DNS, Web Server

Bước 3: Thiết kế các thành phần cốt lõi

Đi sâu vào chi tiết từng thành phần cốt lõi.

Trường hợp sử dụng: Người dùng gửi một yêu cầu đọc hoặc ghi

Mục tiêu
Bắt đầu với một máy duy nhất

Dùng mở rộng theo chiều dọc (Vertical Scaling):

Đánh đổi, phương án thay thế và chi tiết bổ sung:

Bắt đầu với SQL, cân nhắc NoSQL

Các ràng buộc giả định rằng cần dữ liệu quan hệ. Ta có thể bắt đầu bằng một cơ sở dữ liệu MySQL trên chính máy duy nhất đó.

Đánh đổi, phương án thay thế và chi tiết bổ sung:

Gán một IP tĩnh công khai
Dùng DNS

Thêm một DNS như Route 53 để ánh xạ tên miền tới IP công khai của máy (instance).

Đánh đổi, phương án thay thế và chi tiết bổ sung:

Bảo mật web server

Đánh đổi, phương án thay thế và chi tiết bổ sung:

Bước 4: Mở rộng thiết kế (scale the design)

Xác định và xử lý các nút thắt, dựa trên các ràng buộc.

Hành trình mở rộng từ một máy tới Users+++++: mỗi bước xử lý đúng một nút thắt đã đo 1 máy Users+ Users++ Users+++ Users++++ Users+++++ Mỗi bước: đo tải → xử lý đúng nút thắt đó → lặp lại
Từ một máy tới Users+++++, mỗi giai đoạn chỉ thêm đúng thành phần xử lý nút thắt vừa đo được ở giai đoạn trước, không nhảy thẳng lên thiết kế cuối.

Users+

Sơ đồ Users+: tách SQL và Object Store khỏi Web Server
Giả định

Số người dùng bắt đầu tăng và tải trên máy duy nhất ngày càng lớn. Kết quả Benchmark/Load Test và Profiling chỉ ra rằng cơ sở dữ liệu MySQL chiếm ngày càng nhiều bộ nhớ và CPU, trong khi nội dung người dùng đang lấp đầy ổ đĩa.

Cho tới giờ ta đã xử lý được các vấn đề này bằng mở rộng theo chiều dọc. Không may, cách này đã trở nên khá đắt và không cho phép mở rộng cơ sở dữ liệu MySQL và Web Server một cách độc lập.

Mục tiêu
Lưu nội dung tĩnh riêng
Chuyển cơ sở dữ liệu MySQL sang một máy riêng
Bảo mật hệ thống

Đánh đổi, phương án thay thế và chi tiết bổ sung:

Users++

Sơ đồ Users++: Load Balancer, nhiều Web Server, Read/Write API, CDN
Giả định

Kết quả Benchmark/Load Test và Profiling cho thấy Web Server duy nhất bị nghẽn vào giờ cao điểm, dẫn tới phản hồi chậm và đôi khi ngừng hoạt động (downtime). Khi dịch vụ trưởng thành hơn, ta cũng muốn tiến tới tính sẵn sàng và dự phòng cao hơn.

Mục tiêu

Đánh đổi, phương án thay thế và chi tiết bổ sung:

Users+++

Sơ đồ Users+++: thêm Memory Cache và SQL Read Replicas

Lưu ý: Các Load Balancer nội bộ không được vẽ để sơ đồ đỡ rối

Giả định

Kết quả Benchmark/Load Test và Profiling cho thấy hệ thống thiên về đọc (read-heavy, đọc gấp 100 lần ghi) và cơ sở dữ liệu đang có hiệu năng kém do lượng yêu cầu đọc lớn.

Mục tiêu

Đánh đổi, phương án thay thế và chi tiết bổ sung:

Thêm MySQL read replica

Đánh đổi, phương án thay thế và chi tiết bổ sung:

Users++++

Sơ đồ Users++++: các nhóm Autoscale cho Web Server, Write API, Read API
Giả định

Kết quả Benchmark/Load Test và Profiling cho thấy lưu lượng tăng vọt trong giờ hành chính ở Mỹ và giảm mạnh khi người dùng rời văn phòng. Ta nghĩ có thể cắt giảm chi phí bằng cách tự động bật và tắt máy chủ theo tải thực tế. Ta là một đội nhỏ nên muốn tự động hóa DevOps nhiều nhất có thể cho Autoscaling và cho vận hành nói chung.

Mục tiêu
Thêm autoscaling
Autoscaling co giãn số máy theo giờ trong ngày Đêm Sáng Trưa Chiều Tối nhiều server nhất
Minh hoạ: số server bám theo tải trong ngày — nhiều nhất trong giờ hành chính của người dùng, tắt bớt khi họ rời văn phòng, nhưng không xuống dưới số instance tối thiểu đã đặt.

Users+++++

Sơ đồ Users+++++: thêm Queue, Worker Service, NoSQL, sharding và federation

Lưu ý: Các nhóm Autoscaling không được vẽ để sơ đồ đỡ rối

Giả định

Khi dịch vụ tiếp tục tăng trưởng hướng tới các con số nêu trong ràng buộc, ta lặp lại việc chạy Benchmark/Load Test và Profiling để phát hiện và xử lý các nút thắt mới.

Mục tiêu

Ta sẽ tiếp tục xử lý các vấn đề mở rộng do ràng buộc của bài toán:

Các mẫu mở rộng SQL gồm:

Để xử lý thêm lượng yêu cầu đọc và ghi cao, ta cũng nên cân nhắc chuyển những dữ liệu phù hợp sang một cơ sở dữ liệu NoSQL như DynamoDB.

Ta có thể tách tiếp các Application Server để mở rộng độc lập. Các tiến trình theo lô (batch) hoặc các phép tính không cần thực hiện theo thời gian thực có thể làm bất đồng bộ (asynchronously) với hàng đợi (Queue) và Worker:

Đánh đổi, phương án thay thế và chi tiết bổ sung:

Các ý bàn thêm (additional talking points)

Các chủ đề bổ sung để đào sâu, tùy vào phạm vi bài toán và thời gian còn lại.

Các mẫu mở rộng SQL

NoSQL

Bộ nhớ đệm (caching)

Bất đồng bộ (asynchronism) và microservices

Giao tiếp (communications)

Bảo mật (security)

Tham khảo phần bảo mật.

Các con số độ trễ

Xem Các con số độ trễ mọi lập trình viên nên biết (Latency numbers every programmer should know).

Tiếp tục


Nguồn: The System Design Primer - bài giải "Design a system that scales to millions of users on AWS" — Donne Martin và cộng đồng đóng góp

Giấy phép: CC BY 4.0 (nguyên bản: Donne Martin, The System Design Primer)

Xem bản gốc

Bài tiếp theoThiết kế timeline và tìm kiếm của Twitter