Khóa họcArchitecture
Thiết kế hệ thống - ước lượng tải, load balancer, cache, queue, replication và partitioning
System design foundations: requirements and constraints, SLOs and error budgets, workload and back-of-the-envelope estimates, load balancers, caches, queues, read replicas, partitioning, object storage and CDN, bottlenecks, failure propagation and recorded design decisions
Khoá học nền về thiết kế hệ thống, đi từ requirement, tải cao điểm và constraint tới kiến trúc. Bạn ước lượng dung lượng, băng thông và số instance, rồi chọn cache, queue, replica hay partition cho đúng workload, tìm bottleneck và so sánh phương án. Mỗi thành phần thêm vào đều gắn với một triệu chứng đo được.
- 24 bài
- 7h35p
- 11 quiz
- 3 bài học thử miễn phí
- 47 học viên
Bạn sẽ làm được gì
Hệ thống của bạn cần những thành phần nào, và cần thêm từ lúc nào? Developer backend nào cũng gặp câu hỏi này khi sản phẩm bắt đầu có người dùng thật. Câu trả lời nằm ở requirement, tải cao điểm và constraint của chính hệ thống đó, nên khoá học đi từ những đầu vào này tới kiến trúc, rồi tới cách tìm bottleneck và so sánh phương án.
- Viết requirement bằng số liệu — Bạn phân biệt functional requirement, non-functional requirement và constraint, rồi biến những yêu cầu chung chung về tốc độ và độ ổn định thành số liệu đo được: SLO, error budget, RPO và RTO.
- Ước lượng trước khi dựng hệ thống — Từ tải cao điểm theo từng phút, tỉ lệ đọc/ghi và payload, bạn ước lượng nhanh dung lượng lưu trữ, băng thông và số instance cần chạy, chừa headroom và ghi rõ từng giả định để sau này đối chiếu với metric thật.
- Chỉ định nơi giữ dữ liệu gốc — Bạn chọn source of truth cho từng loại dữ liệu và bảo đảm cache, search index hay bảng báo cáo đều dựng lại được từ đó.
- Chọn thành phần theo triệu chứng đo được — Với load balancer, cache, queue, read replica, partition, object storage và CDN, bạn biết lúc nào cần đến từng thành phần, nó cải thiện được số liệu nào và đi kèm tradeoff gì.
- Tìm bottleneck trước khi thêm máy — Bạn xem utilization, saturation và errors ở từng chặng trên request path để tìm tài nguyên bão hòa sớm nhất, rồi chỉ ra lỗi ở một thành phần sẽ lan ra những đâu.
- So sánh phương án và ghi lại quyết định — Bạn thiết lập hai phương án từ cùng một đầu vào thiết kế, so sánh theo latency, chi phí mỗi tháng, số thành phần phải vận hành và failure mode, rồi ghi quyết định cùng phương án bị loại vào ADR (Architecture Decision Record, bản ghi quyết định kiến trúc).
Trọng tâm là nhận ra lúc nào hệ thống cần thêm một thành phần và ước lượng thành phần đó cải thiện được bao nhiêu; cách cấu hình từng công cụ nằm ngoài phạm vi. Ví dụ trong bài dùng Postgres, Redis và một cửa hàng online nhỏ, còn phép tính và cách chọn thì không phụ thuộc vào ngôn ngữ, framework hay nhà cung cấp cloud bạn đang dùng.
Bạn có đang gặp những dấu hiệu này?
- Tăng số instance của app từ 3 lên 6, throughput vẫn giữ ở 1.200 request/giây còn p99 tăng từ 180 ms lên 650 msCPU của Postgres primary đã gần chạm giới hạn, nên thêm instance app chỉ dồn thêm truy vấn vào đúng chặng đang bão hòa.
- Dashboard báo trung bình 40 request/giây nhưng nginx trả 502 lúc 20:00 mỗi tốiSố trung bình theo ngày che mất 3 phút tải tăng lên 900 request/giây sau mỗi lần gửi push notification khuyến mãi, gấp ba mức app chịu được.
- Benchmark đạt 2.000 request/giây nên một instance được coi là dư sức cho 500 request/giâyBenchmark đo trên
/healthvới 5 ms mỗi request, còn API chat mất 80 ms nên mỗi instance chỉ chịu khoảng 125 request/giây.
Khóa học này có hợp với bạn?
Khoá học dành cho ai
- Developer backend— Bạn đã đưa lên production một ứng dụng web có database phía sau, và giờ phải trả lời những câu hỏi như có cần cache không, cần mấy instance, hệ thống có chịu nổi đợt khuyến mãi tới không.
- Người viết đề xuất kiến trúc cho team— Bạn là tech lead hoặc developer được giao chọn giữa các phương án thiết kế, và cần so sánh chúng bằng số liệu rồi ghi lại quyết định cho người vào team sau.
- Developer vận hành một hệ thống đang lớn dần— Bạn phụ trách một app có tải, dữ liệu và hóa đơn hạ tầng tăng theo từng tháng, và cần biết triệu chứng nào báo hiệu đã tới lúc thêm thành phần, thành phần nào vẫn chưa cần.
Những điều cần lưu ý
- Không đi vào cách từng thành phần hoạt động bên trong — Cache invalidation, consistency model của replica hay delivery semantics của queue nằm ngoài khoá học; mỗi bài dừng ở mức đủ để bạn quyết định có thêm thành phần đó hay chưa.
- Không có bước cài đặt hay cấu hình — Khoá học không đi vào Kubernetes, cách phân loại load balancer theo tầng mạng (L4/L7) hay cách cấu hình một nhà cung cấp cloud cụ thể; bạn có phép tính và tiêu chí để quyết định trước khi mở bất kỳ trang cấu hình nào.
- Số liệu trong bài là số minh họa — Các ví dụ dùng số tự đặt để các phép tính khớp với nhau, không phải sức chịu tải chung của Postgres hay Redis; bạn học cách lập phép tính kèm giả định, rồi thay bằng số đo từ hệ thống của mình.
- Demo kit không bắt buộc — Mọi bài đều đọc hiểu được mà không cần chạy Docker; kit dành cho lúc bạn muốn tận mắt thấy p99 tăng vọt trên máy mình rồi giảm xuống sau khi áp dụng cách xử lý.
Bạn sẽ học theo cách nào
- Bắt đầu từ triệu chứng thật— Bài nào cũng mở bằng một dashboard, một đoạn log hay một hóa đơn cloud có số liệu cụ thể; thành phần hay khái niệm chỉ xuất hiện khi bạn đã thấy nó giải quyết triệu chứng nào.
- Phép tính kèm hình vẽ— Các phép tính đều ghi rõ đơn vị và giả định, còn ảnh minh họa vẽ request path, chỗ giữ state, chặng bão hòa và thành phần được thêm vào sau khi sửa.
- Quiz ở các bài cần tính toán— Các bài về cách đọc dashboard, workload, ước lượng, sáu thành phần, bottleneck và cách lỗi lan ra có quiz ngắn, trong đó nhiều câu yêu cầu bạn làm phép tính trước khi chọn đáp án.
- Áp dụng cho hệ thống của bạn— Phần lớn các bài khép lại bằng một bài tập trên hệ thống bạn đang có: vẽ request path, lập bảng constraint, viết hai dòng SLO hay một ADR.
- Ba demo kit chạy bằng Docker— Mỗi bài tình huống kèm một kit để coding agent của bạn dựng lại hệ thống trên laptop, chạy k6 ở mức tải cố định và cho bạn thấy triệu chứng của bài; khi bạn yêu cầu, agent áp dụng cách xử lý mà bài trình bày rồi chạy lại cùng kịch bản để so sánh.
Mentor
Khóa học cung cấp những gì
Nguyên tắc xuyên suốt là ghi lại đầu vào thiết kế trước khi vẽ sơ đồ: requirement, constraint và workload, trong đó phần nào đo được thì ghi bằng số liệu. Sau đó, mỗi thành phần chỉ được thêm vào khi nó giải quyết một triệu chứng đo được. Phần mô tả tải và đo hiệu năng bám theo chương đầu của sách Designing Data-Intensive Applications của Martin Kleppmann, phần SLO và error budget bám theo chương Service Level Objectives trong sách SRE của Google, còn cách tìm bottleneck dùng phương pháp USE của Brendan Gregg.
Nội dung chia thành bảy nhóm, nhóm sau dùng lại những gì nhóm trước đã trình bày. Các nhóm 5, 6 và 7 kết thúc bằng một bài tình huống, nơi bạn áp dụng những gì vừa học vào một nghiệp vụ cụ thể và đo kết quả trước và sau khi sửa.
Request đi qua những đâu, state nằm ở đâu và đọc dashboard thế nào
Bài nền đưa ra cách vẽ hệ thống mà cả khoá học dùng chung: request path đi từ client tới database, mọi chỗ đang giữ state được đánh dấu riêng. Bạn phân biệt tầng stateless với tầng stateful, chuyển session ra một nơi lưu chung để có thể thêm instance app an toàn, và thấy app stateless không có nghĩa là state đã biến mất khỏi hệ thống. Chặng nào trên request path cũng có thể chậm hoặc hỏng, nên các bài sau đều quay lại hình vẽ này.
Bài thứ hai mở bằng một dashboard có ba panel đều xanh, trong khi chỉ trong một phút đã có 90 lần bấm đặt hàng nhận lỗi 503. Bạn đọc latency theo p50, p95 và p99 thay cho số trung bình, vì trong gần 18.000 request thành công của phút đó, 180 request chờ khoảng 2,5 giây chỉ kéo số trung bình từ 100 ms lên 124 ms. Throughput cần được đọc cùng latency, vì API xử lý xong nhiều request hơn chưa chắc khách đã chờ ít hơn.
Error rate thì phải được tính trên request của đúng thao tác cần theo dõi: cùng 90 lỗi, chia cho mọi request của API thì được 0,5%, chia riêng cho request đặt hàng thì được 7,5%. Cuối bài, bạn phân biệt utilization với saturation: CPU mới 45%, nhưng connection pool đã dùng hết và khoảng 25 request đang xếp hàng chờ connection.
Các loại requirement và cách biến chúng thành số liệu
API xuất hóa đơn PDF qua hết mười hai test chức năng, nhưng tối ngày cuối tháng p99 của nó tăng lên 40 giây, vì chưa ai hỏi có bao nhiêu cửa hàng sẽ xuất hóa đơn cùng lúc. Từ tình huống đó, bạn phân biệt functional requirement, non-functional requirement và constraint (ngân sách, team, công nghệ sẵn có). Nhóm bài cũng đưa ra tám câu hỏi về non-functional requirement nên hỏi trước khi thiết kế.
Ở trang thanh toán, yêu cầu mơ hồ về tốc độ và độ ổn định được viết lại thành hai dòng SLO: với SLO 99,9% trong 30 ngày, chỉ 15 phút sập vào giờ cao điểm đã dùng hết error budget của cả tháng. Phần cuối nhóm trình bày RPO, RTO và cách xếp ưu tiên khi hai requirement mâu thuẫn nhau.
Mô tả workload, ước lượng nhanh và xác định dữ liệu gốc
Bạn mô tả workload bằng tải cao điểm theo từng phút, burst, tỉ lệ đọc/ghi, payload và tốc độ tăng của tải và dữ liệu, lấy từ access log thay vì dựa vào số trung bình theo ngày. Phần ước lượng nhanh (back-of-the-envelope) tính dung lượng lưu trữ và băng thông cho một tính năng chat chưa ra mắt, rồi dùng Little’s Law để chọn số instance: với cùng 500 request/giây, khi mỗi request mất 400 ms thay vì 80 ms, số request đang xử lý cùng lúc tăng gấp năm lần. Bài cuối nhóm trình bày cách xác định source of truth cho từng loại dữ liệu, để cache, search index hay bảng báo cáo luôn dựng lại được từ đó.
Các thành phần cơ bản: khi nào cần và tradeoff
Sáu bài, mỗi bài một thành phần, cùng xét ba điểm: khi nào cần, cải thiện được số liệu nào và tradeoff là gì. Load balancer chia tải và loại instance đã chết khỏi danh sách nhận request, nhưng tự nó có thể trở thành single point of failure. Với cache-aside và hit ratio 88%, CPU của Postgres giảm từ 85% xuống khoảng 16%, đổi lại người dùng có thể thấy dữ liệu cũ trong khoảng thời gian TTL.
Queue đưa việc gửi email ra khỏi request đăng ký; read replica nhận những truy vấn đọc mà dữ liệu cũ vài giây vẫn chấp nhận được; partition theo ngày thay job xóa dữ liệu cũ chạy suốt đêm bằng một câu lệnh drop partition. Bài về object storage và CDN đưa ra một kết quả nhiều người không ngờ: khi CDN phục vụ 95% số byte ảnh, chi phí băng thông chỉ giảm khoảng 28%, còn thời gian backup database được rút ngắn từ 5 giờ xuống khoảng 30 phút.
Hệ thống lớn lên theo từng nấc
Một cửa hàng online nhỏ chạy tám tháng đầu chỉ với một app và một Postgres, tới năm thứ ba đã có bảy thành phần, và hóa đơn hạ tầng tăng từ khoảng 3 triệu đồng lên 24 triệu đồng mỗi tháng. Ở mỗi nấc, bạn thấy triệu chứng đo được nào báo hiệu đã tới lúc lên nấc, thành phần nào được thêm vào và vì sao, cùng những thành phần chưa cần dù hay xuất hiện trong sơ đồ của các hệ thống lớn.
Nhóm kết thúc bằng bài tình huống về dịch vụ rút gọn link: một link chiến dịch bị share mạnh làm p99 của redirect tăng từ 12 ms lên 1,8 giây. Từ requirement và bản ước lượng tải, bạn đặt cache trước database để đưa p99 về dưới 50 ms, rồi so sánh hai cách sinh mã ngắn không trùng nhau.
Tìm bottleneck và xem lỗi lan ra như thế nào
Bottleneck đầu tiên là tài nguyên bão hòa sớm nhất trên request path, và thêm tài nguyên ở chỗ khác không làm throughput tăng. Bạn tìm nó bằng cách xem utilization, saturation và errors ở từng chặng, rồi ước lượng throughput tối đa mà tài nguyên đó chịu được để biết bottleneck sẽ chuyển sang đâu sau khi sửa.
Bài tiếp theo giải thích vì sao lỗi ở một service phụ lan sang cả những endpoint không gọi tới nó, và cách tính availability khi request phải đi qua nhiều thành phần nối tiếp hoặc khi một tầng có instance dự phòng. Trong ví dụ, số phút tầng app không dùng được mỗi tháng giảm từ khoảng 216 phút xuống khoảng 1 phút chỉ nhờ thêm một instance. Ở bài tình huống cuối nhóm, bạn lần ngược từ một triệu chứng lặp lại đúng giờ mỗi sáng để tìm ra tài nguyên mà API đặt hàng và job báo cáo đang dùng chung, rồi chuyển báo cáo sang một replica riêng và partition bảng
orderstheo tháng.Thiết lập, so sánh phương án và ghi lại quyết định thiết kế
Khách gõ sai chính tả thì trang tìm kiếm không trả về sản phẩm nào. Từ cùng requirement, constraint và workload, bạn thiết lập hai phương án thật sự khác nhau: tìm gần đúng ngay trong Postgres bằng extension trigram, hoặc thêm Elasticsearch đồng bộ dữ liệu từ Postgres.
Bảng so sánh thay những dòng ưu nhược điểm chung chung bằng giá trị đo ở cùng một workload: latency, chi phí mỗi tháng, số thành phần phải vận hành, failure mode và độ trễ đồng bộ. Quyết định được ghi vào ADR cùng bối cảnh có số liệu, phương án bị loại và điều kiện xem lại, để một năm sau team không phải mất hai tuần đo lại từ đầu. Bài tình huống cuối khoá thêm một đợt flash sale với tải dự kiến 8.000 request/giây vào cửa hàng đang chạy ổn ở 200 request/giây, và bạn so sánh hai kiến trúc ghép từ những thành phần đã học bằng cùng một kịch bản load test k6.
Nội dung khóa học
Các bài còn lại mở sau khi ghi danh
- Thiết kế hệ thống bắt đầu từ requirement, tải cao điểm và constraintCourse opening: requirements, workload numbers and back-of-the-envelope estimates before choosing load balancer, cache, queue, replica and partitionBài đọc · 12 phútHọc thử
- Request đi qua những chặng nào và state đang nằm ở đâuRequest path from client to database: DNS, load balancer, app instances, stateful vs stateless tiers, in-memory sessions, shared session store, sticky sessions, diagram conventionsBài đọc · 20 phútHọc thử
- Đọc p99, throughput, error rate và saturation trên dashboardService dashboard metrics: latency percentiles (p50, p95, p99) vs mean, success vs error latency, throughput vs latency, error rate denominator, utilization vs saturationBài đọc · 16 phútHọc thử
- Tính năng qua hết test vẫn không dùng được vì thiếu non-functional requirementFunctional vs non-functional requirements: quality attributes (latency, throughput, availability, durability, consistency, security/privacy, cost, operability) and why they drive the architectureBài đọc · 22 phútCần đăng nhập
- Ghi rõ constraint để loại bớt phương án trước khi so sánhDesign constraints vs requirements: budget, team skills, existing technology and infrastructure; eliminating options before tradeoff analysisBài đọc · 17 phútCần đăng nhập
- Thay yêu cầu “nhanh và luôn chạy” bằng SLO và error budgetSLI, SLO and SLA, p99 latency, request-based error budget and error budget policy, availability as downtime minutes, RPO and RTO, prioritizing conflicting quality attributes (latency vs cost)Bài đọc · 19 phútCần đăng nhập
- Mô tả workload bằng tải cao điểm theo từng phút, không chỉ bằng số trung bìnhWorkload characterization: daily average vs per-minute peak, burst duration, peak-to-average ratio, read/write ratio at peak, payload size, growth driver, counting requests per minute from access logsBài đọc · 17 phútCần đăng nhập
- Ước lượng số máy, dung lượng và băng thông trước khi làm tính năngBack-of-the-envelope estimation: storage per year, peak bandwidth, Little’s Law for concurrent requests, headroom, verifying estimates against production metricsBài đọc · 21 phútCần đăng nhập
- Source of truth: dữ liệu nào là gốc, dữ liệu nào dựng lại đượcSource of truth and system of record per data type, derived data (cache, search index, reporting tables), rebuildability from the source, business decisions read from the system of record, invariant definitionBài đọc · 19 phútCần đăng nhập
- Khi nào cần đặt load balancer, reverse proxy hay API gateway trước appLoad balancer, health checks, horizontal scaling of stateless instances, N+1 capacity, reverse proxy, API gateway, edge policies, extra network hop, single point of failureBài đọc · 17 phútCần đăng nhập
- Khi nào cần cache và nó gánh bớt được bao nhiêu tải đọc cho databaseCaching read-heavy workloads: cache-aside, hot set, hit ratio and miss ratio, remaining database load, TTL as a staleness window, cache as a derived copy, operating costBài đọc · 18 phútCần đăng nhập
- Dùng queue để API không phải chờ những việc xử lý lâuMessage queue and background workers: synchronous vs deferred work, enqueue in the request path, burst absorption, queue depth vs queue lag, worker throughput and headroomBài đọc · 18 phútCần đăng nhập
- Read replica gánh bớt tải đọc cho database primaryRead replicas: read/write split, offloading read queries from the primary, replication lag as stale reads, writes still bound to the primary, a standby copy for availability, replica is not a backupBài đọc · 16 phútCần đăng nhập
- Partition khi một bảng quá lớn và sharding khi một máy không ghi kịpTable partitioning vs sharding: time-based partitions, dropping a partition instead of DELETE, partition key and partition pruning, cross-partition queries, hot partition, single-node write ceilingBài đọc · 18 phútCần đăng nhập
- Đưa file và ảnh ra khỏi database bằng object storage và CDNObject storage vs database for binary files, object key and metadata, CDN edge cache and origin offload, hit ratio by bytes, egress and storage cost estimate, stale cached objects, public URLsBài đọc · 20 phútCần đăng nhập
- Hệ thống lớn dần thì thêm thành phần nào, khi nào và vì saoScaling a system rung by rung: symptom-driven additions of cache, object storage and CDN, queue and worker, load balancer and read replica, and what is not needed yet at each rungBài đọc · 19 phútCần đăng nhập
- Thiết kế dịch vụ rút gọn link từ requirement tới kiến trúcURL shortener case: requirements and back-of-the-envelope estimate, skewed read workload, cache-aside on the redirect path, hit ratio, p99 before/after, short code generation with counter + base62 vs truncated hashBài đọc · 20 phútCần đăng nhập
- Thêm instance mà throughput không tăng thì bottleneck nằm ở đâuFinding the first bottleneck: full request-path architecture, USE method (utilization, saturation, errors) per stage, resource ceiling estimate, database connection limit, scaling a tier that is not the bottleneckBài đọc · 19 phútCần đăng nhập
- Lỗi ở một service phụ lan ra cả hệ thống như thế nàoCascading failures: synchronous calls holding threads, shared resources, hard vs optional dependencies, serial and parallel availability mathBài đọc · 19 phútCần đăng nhập
- Lưu hàng triệu đơn hàng mỗi ngày mà báo cáo không làm chậm việc đặt hàngSeparating OLTP from OLAP on a 300M-row orders table: diagnosing shared disk contention from a recurring time window with USE, a dedicated reporting read replica, monthly range partitioning with partition pruning, before/after p99Bài đọc · 22 phútCần đăng nhập
- Thiết lập hai phương án thiết kế khác nhau cho cùng một yêu cầuDesign alternatives from one set of requirements, constraints and workload: genuine options vs strawman, explicit and checkable assumptions, Postgres full-text search with pg_trgm vs Elasticsearch synced from PostgresBài đọc · 21 phútCần đăng nhập
- So sánh hai phương án thiết kế bằng số liệu thay vì ưu nhược điểmComparing design options with measurable criteria: p99 latency under expected load, monthly cost, components to operate, failure modes, derived-data sync lag, requirement thresholds as gates, decision with revisit conditionsBài đọc · 19 phútCần đăng nhập
- Ghi lại quyết định kiến trúc để một năm sau vẫn biết vì saoArchitecture Decision Records: context with measured numbers, decision, rejected alternatives with reasons, tracked assumptions, revisit triggers, status and supersessionBài đọc · 20 phútCần đăng nhập
- Thiết kế lại hệ thống khi flash sale đẩy tải lên gấp 40 lầnFlash sale redesign: re-reading requirements and assumptions, capacity re-estimate, read replicas vs cache plus order queue, k6 comparison of p99, throughput and error rateBài đọc · 24 phútCần đăng nhập
Vì sao có khóa học này
Ngày nay, dựng thêm một thành phần chỉ mất vài phút. Redis, queue hay read replica đều có sẵn dưới dạng managed service, còn coding agent vẽ được một sơ đồ có đủ load balancer, cache, queue và replica chỉ từ một đoạn mô tả tính năng.
Vì việc dựng đã rẻ, câu hỏi khó dồn về phía bạn: với tải cao điểm, ngân sách và số người trong team hiện tại, hệ thống có cần thành phần đó không, và cần từ lúc nào. Muốn trả lời, bạn cần những đầu vào đó được ghi lại thành văn bản và số liệu, không chỉ là ước chừng của từng người trong team.
Khi thiếu số liệu, sai lầm thường đi theo một trong hai hướng, và người gánh hậu quả là bạn. Dựng thừa thì bạn phải vận hành cả những thành phần mà team chưa từng xử lý sự cố với chúng: một cụm Cassandra hỏng lúc 3 giờ sáng có thể mất hơn 4 giờ mới chạy lại vì cả team chỉ quen Postgres, trong khi hóa đơn tháng đầu đã gần gấp ba ngân sách. Dựng thiếu thì dashboard báo mọi thứ ổn suốt nhiều tháng, rồi hệ thống trả lỗi đúng vào mấy phút khuyến mãi, lúc nhiều người mua nhất. Còn khi sự cố đã xảy ra, bạn dễ thêm máy vào chặng không phải bottleneck, hoặc ngồi trong một buổi họp mà ai cũng có lý nhưng không ai có số liệu để chốt.
Thứ giúp bạn tránh cả hai hướng sai là vài phép tính có đơn vị, làm được bằng giấy bút hoặc một bảng tính: tải cao điểm theo phút, số request đồng thời theo Little’s Law, hit ratio cần đạt để database còn headroom, số phút downtime mà SLO cho phép. Có những phép tính này, bạn trả lời được hệ thống có chịu nổi đợt tải sắp tới hay không trước khi sự cố xảy ra, giải thích được vì sao chọn phương án này mà loại phương án kia, và biết thành phần nào chưa cần thêm. Trước mỗi mùa Black Friday Cyber Monday, Shopify cũng bắt đầu bằng dự báo tải và load test, tức là cùng loại phép tính này, chỉ ở quy mô lớn hơn nhiều.
Sau khoá học, khi marketing báo một đợt khuyến mãi hay product manager hỏi cần bao nhiêu máy, bạn trả lời bằng một phép tính có giả định thay vì cảm giác khi nhìn biểu đồ. Với mỗi thành phần thêm vào, bạn chỉ ra được triệu chứng đã dẫn tới nó, và ADR bạn để lại đủ để người vào team một năm sau hiểu vì sao hệ thống được thiết kế như hiện tại.
Những vấn đề thường gặp khi thiết kế hệ thống
Nhiều sự cố về tải bắt đầu từ một quyết định đưa ra trước khi có số đo: thêm máy theo thói quen, tin vào số trung bình, hoặc lấy kết quả benchmark của một endpoint làm sức chịu tải của cả tính năng. Mỗi dòng dưới đây ghép một điều bạn thấy trên dashboard với nguyên nhân thật của nó.
- Dấu hiệuTăng số instance của app từ 3 lên 6, throughput vẫn giữ ở 1.200 request/giây còn p99 tăng từ 180 ms lên 650 msThực raCPU của Postgres primary đã gần chạm giới hạn, nên thêm instance app chỉ dồn thêm truy vấn vào đúng chặng đang bão hòa.
- Dấu hiệuDashboard báo trung bình 40 request/giây nhưng nginx trả 502 lúc 20:00 mỗi tốiThực raSố trung bình theo ngày che mất 3 phút tải tăng lên 900 request/giây sau mỗi lần gửi push notification khuyến mãi, gấp ba mức app chịu được.
- Dấu hiệuBenchmark đạt 2.000 request/giây nên một instance được coi là dư sức cho 500 request/giâyThực raBenchmark đo trên
/healthvới 5 ms mỗi request, còn API chat mất 80 ms nên mỗi instance chỉ chịu khoảng 125 request/giây. - Dấu hiệuChạy app trên ba instance thay vì một, instance nào cũng dưới 40% CPU mà người dùng liên tục bị đăng xuấtThực raSession nằm trong RAM của từng instance, và load balancer gửi request tới instance không có session đó.
- Dấu hiệuCheckout trả 504 trong khi CPU của app mới 15%Thực raLatency của service gợi ý sản phẩm tăng từ 40 ms lên 8 giây, trang chi tiết sản phẩm gọi nó đồng bộ và giữ hết 200 thread của app trong lúc chờ.
- Dấu hiệuĐúng 8:00 mỗi sáng, p99 của API đặt hàng tăng từ 80 ms lên 2,5 giây dù số request mỗi giây không đổiThực raJob báo cáo doanh thu quét bảng
orderstrên cùng Postgres primary và tranh chấp đĩa với API đặt hàng. - Dấu hiệuSearch index và bảng báo cáo lệch với Postgres sau một sự cố đồng bộ, không ai nói được bản nào đúngThực raTeam chưa chỉ định source of truth cho từng loại dữ liệu, nên không ai biết phải dựng lại các bản dẫn xuất từ đâu.
Các bài trong khoá lần lượt phân tích những tình huống này, từ số liệu trên dashboard tới nguyên nhân và cách xử lý.
Câu hỏi thường gặp
Mình thanh toán bằng cách nào?
Bạn thanh toán bằng chuyển khoản ngân hàng qua mã VietQR ở bước checkout. 200Lab không thu thập thông tin thẻ của bạn.
Thanh toán xong bao lâu thì vào học được?
Hệ thống tự đối soát giao dịch, thường trong vài phút là khóa học có trong trang học của bạn. Bạn nhớ giữ nguyên nội dung chuyển khoản mà hệ thống đưa ra.
Mã QR hết hạn thì sao?
Mỗi đơn hàng có hiệu lực 30 phút. Nếu quá thời gian đó, bạn mở lại đơn và tạo mã QR mới, không cần đặt lại từ đầu.
Mình được truy cập khóa học trong bao lâu?
Thời hạn truy cập đi theo gói bạn mua và được ghi ngay dưới giá ở hộp mua.
Mình có nhận được các cập nhật của khóa học sau khi mua không?
Có. Khi khóa học được bổ sung hoặc cập nhật bài học, bạn nhận được các thay đổi đó trong suốt thời hạn truy cập của mình, không phải trả thêm.
Mình học trên điện thoại được không?
Được. 200Lab chạy trên trình duyệt của cả máy tính lẫn điện thoại, bạn không cần cài ứng dụng. Tiến độ học được lưu theo tài khoản nên bạn đổi thiết bị vẫn học tiếp được.
Học xong mình có nhận Certificate không?
Có. Khi hoàn thành khóa học bạn nhận Certificate có mã xác thực. Người khác có thể kiểm tra mã đó trên trang xác thực Certificate của 200Lab nếu bạn chọn công khai.
Mình có thể học thử trước khi mua không?
Có. Khóa học này có bài học thử: bạn bấm nút Học thử ngay trong hộp mua, và các bài đó được đánh dấu trong chương trình học.
Bắt đầu từ đâu
Bài mở đầu đặt hai bản thiết kế cạnh nhau. Bản thứ nhất có bảy thành phần cho một cửa hàng chỉ nhận 30 request/giây lúc cao điểm; bản thứ hai chỉ có một app và một Postgres, và Postgres quá tải trong đêm khuyến mãi khi tải tăng lên 2.000 request/giây. Bài chỉ ra cách biết một bản thiết kế đang thừa hay thiếu so với tải cao điểm, và vì sao hai bản ngược nhau lại sai ở cùng một chỗ: cả hai được vẽ khi đầu vào thiết kế còn chưa được ghi lại. Từ bài này trở đi, đầu vào thiết kế là điểm xuất phát của mọi quyết định.