PHẦN I · HÀNH TRÌNH TIẾN HOÁ
Chương 0. Đo lường một hệ thống đang tăng trưởng
- Mỗi giai đoạn hình thành từ giới hạn của giai đoạn trước. Kiến trúc một máy chủ đáp ứng được cho tới khi ứng dụng và cơ sở dữ liệu tranh chấp tài nguyên. Khi tách cơ sở dữ liệu ra máy riêng, cơ sở dữ liệu trở thành nút cổ chai. Bộ nhớ đệm và bản sao giảm tải cho nút cổ chai đó nhưng sinh ra dữ liệu cũ và độ trễ sao chép. Vì vậy mỗi chương mở đầu bằng hai nội dung: lý do hệ thống phải chuyển tới giai đoạn này, và vấn đề giai đoạn này để lại cho chương sau.
- Microservices chủ yếu giải quyết bài toán tổ chức đội phát triển. Một monolith được chia module tốt vẫn chịu được tải rất lớn. Việc tách dịch vụ thường bắt đầu khi nhiều đội không còn triển khai độc lập được (chương 8).
- Tách cơ sở dữ liệu theo dịch vụ đồng nghĩa với việc mất giao dịch chung. Từ thời điểm này, hệ thống mới cần tới kiến trúc hướng sự kiện, saga, outbox và CDC (chương 11, 12, 13).
- Bản sao không thay thế được bản sao lưu. Lệnh xoá nhầm được sao chép sang bản sao gần như ngay lập tức. Chỉ bản sao lưu kết hợp với log lưu trữ (PITR) mới đưa dữ liệu về được thời điểm trước lỗi (chương 15).
- Cơ sở dữ liệu có lịch sử riêng, song song với lịch sử kiến trúc ứng dụng. Cơ sở dữ liệu phát triển từ mô hình quan hệ sang NoSQL, distributed SQL, kiến trúc tách lưu trữ khỏi tính toán, rồi tới cơ sở dữ liệu vector. Hiểu write-ahead log, MVCC và cơ chế sao chép là điều kiện để vận hành đúng bản sao, CDC và PITR (chương 20, 21).
- ML đưa vào hai đặc điểm mà phần mềm thông thường không có. Thứ nhất, hành vi của hệ thống phụ thuộc vào dữ liệu: chất lượng model giảm dần khi dữ liệu thay đổi, dù mã nguồn không đổi. Thứ hai, GPU là tài nguyên đắt nhất. LLM còn bổ sung câu trả lời không xác định và chi phí tính theo token (chương 22, 23).
- Các ngôn ngữ khác nhau ở ba lựa chọn nền tảng. Đó là cách dịch mã nguồn xuống máy, cách quản lý bộ nhớ và cách thực thi song song. Ba lựa chọn này tạo ra ngách riêng cho từng ngôn ngữ, nên các ngôn ngữ không thay thế được nhau (chương 24, 25).
- Mạng có mặt từ khi hệ thống có hai máy. Nhiều sự cố có biểu hiện như lỗi ứng dụng nhưng nguyên nhân nằm ở DNS, hết thời gian chờ, tường lửa hoặc cân bằng tải. Trên cloud và Kubernetes, mạng trở thành cấu hình (chương 26, 27).
- Không bỏ qua giai đoạn. Chuyển lên Kubernetes hay microservices khi chưa chạm giới hạn đồng nghĩa với việc trả chi phí vận hành trước khi nhận được lợi ích (chương 29).
- 0.1Tình huống: sự cố trong đêm khuyến mãi
- 0.2Năm hướng tăng trưởng của một hệ thống
- 0.3Đo lường độ trễ và độ sẵn sàng
- 0.4Mô hình hàng đợi và mức sử dụng
- 0.5Định luật Little và nguyên nhân sự cố
- 0.6Giới hạn của việc bổ sung máy
- 0.7Nguyên tắc đủ dùng
- 0.8Ước lượng năng lực cho Chợ Phố
- 0.9Hướng tiếp theo
Đã có trong KB: 00-foundation/consistency-tradeoffs.md · 00-foundation/well-architected-pillars.md
Chương 1. Kiến trúc một máy chủ
Vì sao phải tới đây
Ở giai đoạn đầu, số người dùng còn ít và yêu cầu chính là đưa sản phẩm ra nhanh. Một máy chủ đáp ứng đủ nhu cầu này.
Vấn đề để lại
Ứng dụng và cơ sở dữ liệu tranh chấp CPU, bộ nhớ trong và ổ đĩa. Máy chủ là điểm lỗi đơn: khi máy hỏng, toàn bộ hệ thống ngừng hoạt động.
- 1.1Tình huống: bản sao lưu chưa từng được khôi phục
- 1.2Kiến trúc một máy chủ
- 1.3Phân tích nguyên nhân: mã thoát của đường ống lệnh
- 1.4Đánh giá thiệt hại: mục tiêu điểm khôi phục
- 1.5Thiết kế quy trình sao lưu có tự kiểm tra
- 1.6Kiểm chứng bằng khôi phục thử và mục tiêu thời gian khôi phục
- 1.7Tranh chấp tài nguyên trên một máy chủ
- 1.8Điểm lỗi đơn và độ sẵn sàng
- 1.9Mở rộng theo chiều dọc
- 1.10Hướng tiếp theo
Pattern liên quan: D1 · Tính toán và mở rộng · D12 · Sao lưu, độ sẵn sàng cao, khôi phục sau thảm hoạ
Đã có trong KB: 04-case-library/small-crud-app.md
Chương 2. Tách cơ sở dữ liệu ra máy riêng
Vì sao phải tới đây
Ứng dụng và cơ sở dữ liệu tranh chấp tài nguyên của nhau. Mục tiêu là nâng cấp và sao lưu từng thành phần một cách độc lập.
Vấn đề để lại
Hai máy giao tiếp qua mạng, nên hệ thống phát sinh thêm độ trễ, lỗi kết nối và giới hạn về số kết nối.
- 2.1Tình huống: hai triệu chứng sau khi tách
- 2.2Tách cơ sở dữ liệu và mô hình ba tầng
- 2.3Mạng trở thành một phần của hệ thống
- 2.4Bí ẩn thứ nhất: truy vấn N+1
- 2.5Gộp truy vấn bằng JOIN và IN
- 2.6Bí ẩn thứ hai: kết nối nhàn rỗi bị cắt
- 2.7Giữ sống và giới hạn tuổi kết nối
- 2.8Định cỡ: cần bao nhiêu kết nối
- 2.9Object storage cho ảnh sản phẩm
- 2.10Hướng tiếp theo
Pattern liên quan: D1 · Tính toán và mở rộng · D3 · Lưu trữ và mô hình dữ liệu · D22 · Mạng
Chương 3. Chạy nhiều máy chủ ứng dụng sau cân bằng tải
Vì sao phải tới đây
Một máy chủ ứng dụng không còn đáp ứng được lưu lượng truy cập, trong khi việc nâng cấp máy đã chạm giới hạn hoặc quá tốn kém.
Vấn đề để lại
Nếu ứng dụng lưu phiên đăng nhập hoặc tệp tạm trên từng máy, một yêu cầu được chuyển sang máy khác sẽ mất trạng thái.
- 3.1Tình huống: thêm một máy, khách bị đăng xuất
- 3.2Cân bằng tải và reverse proxy
- 3.3Cân bằng tải tầng 4 và tầng 7
- 3.4Thuật toán chia tải
- 3.5Phân tích nguyên nhân: phiên nằm trong bộ nhớ từng máy
- 3.6Sticky session và giới hạn của nó
- 3.7Kho phiên dùng chung
- 3.8Token tự chứa: JWT
- 3.9Health check: máy treo vẫn nhận yêu cầu
- 3.10Liveness và readiness
- 3.11Tự động thêm bớt máy
- 3.12Hướng tiếp theo
Pattern liên quan: D1 · Tính toán và mở rộng · D9 · API và giao tiếp · D22 · Mạng
Đã có trong KB: 03-patterns/session-mgmt · 02-decision/compute-selection.md
Chương 4. Bộ nhớ đệm và CDN
Vì sao phải tới đây
Sau khi bổ sung máy chủ ứng dụng, cơ sở dữ liệu trở thành nút cổ chai. Phần lớn tải lúc này là các lượt đọc lặp lại trên cùng một tập dữ liệu.
Vấn đề để lại
Bộ nhớ đệm có thể trả về dữ liệu cũ. Khi nhiều khoá hết hạn cùng lúc, cơ sở dữ liệu chịu hiện tượng dồn tải.
- 4.1Tình huống: giá cũ và cơn tăng tải lúc nửa đêm
- 4.2Nguyên lý: lưu kết quả đọc gần nơi dùng
- 4.3Bộ nhớ đệm trong tiến trình và bộ nhớ đệm dùng chung
- 4.4Bốn cách đọc ghi qua bộ nhớ đệm
- 4.5Định lượng: tỉ lệ trúng và tải còn lại trên cơ sở dữ liệu
- 4.6Chẩn đoán sự cố lúc 00:00
- 4.7Hiện tượng dồn tải khi khoá hết hạn
- 4.8Ba biện pháp chống dồn tải
- 4.9Giá cũ: vô hiệu hoá khi dữ liệu đổi
- 4.10CDN cho ảnh và tệp tĩnh
- 4.11Bộ nhớ đệm tại biên cho nội dung động
- 4.12Hướng tiếp theo
Pattern liên quan: D8 · Bộ nhớ đệm · D22 · Mạng
Đã có trong KB: 03-patterns/caching · 02-decision/caching-strategy.md
Chương 5. Mở rộng cơ sở dữ liệu
Vì sao phải tới đây
Bộ nhớ đệm không giảm được tải ghi, và khối lượng dữ liệu tăng dần vượt quá năng lực của một máy cơ sở dữ liệu.
Vấn đề để lại
Bản sao cập nhật chậm hơn primary, nên có thời điểm một lượt đọc không thấy dữ liệu vừa ghi. Sau khi chia shard, phép JOIN và giao dịch trải trên nhiều shard trở nên khó thực hiện.
- 5.1Tình huống: địa chỉ cũ và primary cũ
- 5.2Sao chép và bản sao chỉ đọc
- 5.3Độ trễ sao chép và cách đo
- 5.4Đọc dữ liệu vừa ghi
- 5.5Sao chép đồng bộ hay bất đồng bộ
- 5.6Primary, standby và failover
- 5.7Partitioning: chia bảng theo cột và theo hàng
- 5.8Sharding: chia dữ liệu ra nhiều máy
- 5.9Chợ Phố đã cần sharding chưa
- 5.10Mỗi loại dữ liệu một loại cơ sở dữ liệu
- 5.11Hướng tiếp theo
Pattern liên quan: D3 · Lưu trữ và mô hình dữ liệu · D12 · Sao lưu, độ sẵn sàng cao, khôi phục sau thảm hoạ · D19 · Bên trong cơ sở dữ liệu
Đã có trong KB: 03-patterns/data-partitioning.md · 03-patterns/storage-partition · 02-decision/database-selection.md
Chương 6. Xử lý bất đồng bộ
Vì sao phải tới đây
Các tác vụ nặng như gửi email, xuất báo cáo và xử lý ảnh làm yêu cầu chậm và thường vượt quá thời gian chờ.
Vấn đề để lại
Thông điệp có thể bị gửi trùng, bị mất hoặc đến sai thứ tự. Hệ thống cần cơ chế thử lại, hàng đợi cho thông điệp lỗi và bên tiêu thụ xử lý trùng an toàn.
- 6.1Tác vụ nền, worker và tác vụ định kỳ
- 6.2Hàng đợi thông điệp: xác nhận đã xử lý (ack), thử lại, hàng đợi thông điệp lỗi (dead letter queue)
- 6.3Tách tác vụ nặng ra khỏi luồng xử lý yêu cầu
- 6.4Backpressure và giới hạn tốc độ (rate limiting)
Pattern liên quan: D5 · Truyền thông điệp và tích hợp · D10 · Chịu lỗi
Đã có trong KB: 03-patterns/delivery-guarantee · 03-patterns/rate-limiting · 04-case-library/distributed-job-scheduler.md
Chương 7. Từ máy vật lý sang máy ảo, rồi lên cloud
Vì sao phải tới đây
Khi số máy chủ tăng, cấu hình thực hiện thủ công bắt đầu sai lệch giữa các máy, và việc dựng một máy mới mất khoảng một tuần.
Vấn đề để lại
Khi hạ tầng được mô tả bằng mã, mọi thay đổi hạ tầng cần quy trình xem xét và quản lý trạng thái. Việc chuyển lên cloud đặt thêm bài toán chi phí và sự phụ thuộc vào nhà cung cấp.
- 7.1Máy vật lý và dịch vụ thuê chỗ đặt máy (colocation)
- 7.2Ảo hoá: hypervisor, máy ảo, snapshot
- 7.3Quản lý cấu hình bằng Ansible, Chef, Puppet và hiện tượng sai lệch cấu hình giữa các máy
- 7.4Hạ tầng bất biến: thay máy bằng image mới thay vì sửa máy đang chạy
- 7.5Cloud: IaaS, PaaS, SaaS; region và vùng sẵn sàng
- 7.6Hạ tầng dạng mã (IaC): state, plan, apply
- 7.7CI/CD: build, kiểm thử, đóng gói, triển khai
- 7.8Hybrid cloud và multi-cloud
Pattern liên quan: D11 · Triển khai và phát hành · D1 · Tính toán và mở rộng
Đã có trong KB: 00-foundation/cloud-models.md · 02-decision/cloud-selection.md · 03-patterns/hybrid-cloud.md
Chương 8. Từ monolith sang microservices
Vì sao phải tới đây
Mã nguồn và đội phát triển cùng tăng. Toàn bộ hệ thống được triển khai như một khối, một lỗi có thể làm ngừng mọi chức năng, và các đội cản trở công việc của nhau.
Vấn đề để lại
Lời gọi hàm trở thành lời gọi qua mạng. Giao dịch trải trên nhiều dịch vụ, việc gỡ lỗi khó hơn, và API cần được quản lý phiên bản.
- 8.1Monolith: ưu điểm thực sự và thời điểm kiến trúc này không còn phù hợp
- 8.2Modular monolith: phân chia module rõ ràng bên trong một khối
- 8.3SOA và ESB: bài học từ thế hệ trước
- 8.4Microservices: bounded context theo DDD, định luật Conway, mỗi dịch vụ một cơ sở dữ liệu
- 8.5Các cách tách dần: strangler fig, branch by abstraction
- 8.6Chi phí của việc tách: mạng, giao dịch phân tán, gỡ lỗi, phiên bản API
- 8.7Các cách tách sai: distributed monolith, dịch vụ quá nhỏ, dùng chung cơ sở dữ liệu
Pattern liên quan: D2 · Kiến trúc tổng thể · D16 · Migration và hiện đại hoá
Đã có trong KB: 03-patterns/modular-monolith.md · 03-patterns/microservices.md · 03-patterns/strangler-fig.md · 04-case-library/legacy-modernization.md
Chương 9. Container và Kubernetes
Vì sao phải tới đây
Hàng chục dịch vụ chạy trên máy ảo, mỗi dịch vụ được đóng gói theo một cách riêng, việc xếp chỗ chạy làm thủ công và tài nguyên máy không được dùng hết.
Vấn đề để lại
Hệ thống có thêm một nền tảng phức tạp cần vận hành, gồm mạng trong cluster, giới hạn tài nguyên và nâng cấp cluster.
- 9.1Khác biệt giữa container và máy ảo; image, registry, layer
- 9.2Các bộ điều phối: Swarm, Mesos, Nomad và Kubernetes
- 9.3Khái niệm cốt lõi của Kubernetes: Pod, Deployment, Service, Ingress, ConfigMap, Secret, StatefulSet
- 9.4Xếp lịch, mức tài nguyên tối thiểu và tối đa của container, HPA, VPA, cluster autoscaler
- 9.5Khám phá dịch vụ qua DNS nội bộ
- 9.6Helm, Kustomize và GitOps với ArgoCD hoặc Flux
- 9.7Kubernetes do nhà cung cấp cloud quản lý, chế độ Autopilot, container serverless
- 9.8Ứng dụng có trạng thái trên Kubernetes: operator, PVC
Pattern liên quan: D1 · Tính toán và mở rộng · D11 · Triển khai và phát hành · D22 · Mạng
Đã có trong KB: 02-decision/deployment-model-selection.md
Chương 10. Giao tiếp giữa các dịch vụ
Vì sao phải tới đây
Nhiều dịch vụ gọi lẫn nhau, và mỗi dịch vụ tự xử lý xác thực, thử lại và định tuyến theo cách riêng.
Vấn đề để lại
Chuỗi lời gọi đồng bộ dài thêm. Một dịch vụ chậm làm chậm toàn bộ các dịch vụ đứng trước nó trong chuỗi.
- 10.1Lời gọi đồng bộ bằng REST, gRPC, GraphQL
- 10.2API gateway và backend for frontend (BFF)
- 10.3Service mesh: sidecar, mTLS, chính sách định tuyến
- 10.4Quản lý phiên bản API, tương thích ngược, kiểm thử hợp đồng (contract testing)
- 10.5Giới hạn thời gian chờ (timeout), thử lại (retry), circuit breaker
Pattern liên quan: D9 · API và giao tiếp · D10 · Chịu lỗi · D22 · Mạng
Đã có trong KB: 03-patterns/routing · 03-patterns/resilience · 02-decision/api-design-principles.md · 02-decision/integration-selection.md
Chương 11. Kiến trúc hướng sự kiện và Pub/Sub
Vì sao phải tới đây
Lời gọi đồng bộ làm các dịch vụ phụ thuộc chặt vào nhau, trong khi một sự kiện thường cần nhiều bên cùng phản ứng.
Vấn đề để lại
Khó xác định bên nào đang nhận sự kiện nào. Hệ thống phải xử lý thứ tự, trùng lặp và sự thay đổi của schema sự kiện theo thời gian.
- 11.1Khác biệt giữa Pub/Sub và hàng đợi; topic, subscription, consumer group
- 11.2Broker dạng log (Kafka, Pub/Sub, Kinesis) và broker truyền thống (RabbitMQ)
- 11.3Mức đảm bảo giao nhận: tối đa một lần, ít nhất một lần, đúng một lần; bên tiêu thụ xử lý trùng an toàn
- 11.4Giữ thứ tự bằng khoá phân vùng (partition key)
- 11.5Fan-out: một sự kiện được chuyển tới nhiều nơi nhận
- 11.6Sự kiện thông báo và sự kiện mang theo dữ liệu
- 11.7Event sourcing
- 11.8CQRS
- 11.9Schema registry và phiên bản sự kiện
Pattern liên quan: D5 · Truyền thông điệp và tích hợp · D7 · Hướng sự kiện · D17 · Thời gian thực và đồng bộ
Đã có trong KB: 03-patterns/event-driven.md · 03-patterns/delivery-guarantee · 03-patterns/ordering · 03-patterns/fan-out
Chương 12. Giữ dữ liệu nhất quán khi mỗi dịch vụ có cơ sở dữ liệu riêng
Vì sao phải tới đây
Mỗi dịch vụ có cơ sở dữ liệu riêng. Một nghiệp vụ phải ghi vào nhiều nơi trong khi không còn giao dịch chung.
Vấn đề để lại
Dữ liệu chỉ nhất quán sau một khoảng thời gian (eventual consistency). Thiết kế phải có bước bù trừ, cơ chế khử trùng, và chấp nhận việc đọc dữ liệu chưa đồng bộ.
- 12.1Vấn đề ghi vào hai nơi (dual-write)
- 12.2Two-phase commit và lý do ít được sử dụng
- 12.3Saga: điều phối tập trung (orchestration) hoặc phối hợp phân tán (choreography); bước bù trừ
- 12.4Transactional outbox và inbox
- 12.5Khoá idempotency và khử trùng
- 12.6Nhất quán sau một khoảng thời gian và mô hình đọc riêng
- 12.7Giải quyết xung đột, CRDT
Pattern liên quan: D4 · Nhất quán và giao dịch
Đã có trong KB: 03-patterns/conflict-resolution · 03-patterns/multi-device-sync
Chương 13. CDC và đường đi của dữ liệu
Vì sao phải tới đây
Thay đổi trong cơ sở dữ liệu cần được chuyển sang hệ tìm kiếm, bộ nhớ đệm và kho dữ liệu mà không sửa ứng dụng và không ghi vào hai nơi.
Vấn đề để lại
Hệ thống phải vận hành log của cơ sở dữ liệu: giữ log đủ lâu, theo dõi độ trễ, xử lý thay đổi schema và chịu tải của lần snapshot đầu tiên.
- 13.1Từ ETL theo lô sang ELT, rồi sang xử lý luồng (streaming)
- 13.2Change Data Capture: đọc bằng truy vấn hoặc đọc log (WAL, binlog, oplog)
- 13.3Debezium và connector; snapshot ban đầu, sau đó đọc log liên tục
- 13.4Kết hợp CDC với outbox
- 13.5Dùng CDC để đồng bộ chỉ mục tìm kiếm, bộ nhớ đệm và kho dữ liệu
- 13.6Data lake, data warehouse, lakehouse
- 13.7Kiến trúc Lambda và Kappa
- 13.8Vận hành CDC: replication slot, độ trễ, thay đổi schema
Pattern liên quan: D6 · Di chuyển dữ liệu · D18 · Tìm kiếm và phân tích
Đã có trong KB: 03-patterns/pipeline-handler.md · 03-patterns/search-indexing · 04-case-library/reporting-system.md
Chương 14. Thay đổi schema và di chuyển dữ liệu
Vì sao phải tới đây
Khi triển khai liên tục, nhiều phiên bản mã nguồn chạy đồng thời. Schema phải được thay đổi mà không dừng hệ thống.
Vấn đề để lại
Một thay đổi được tách thành nhiều bước, và mỗi bước phải tương thích theo cả hai chiều trong suốt thời gian chuyển đổi.
- 14.1Công cụ migration và đánh số phiên bản schema
- 14.2Mở rộng trước, thu hẹp sau (expand–contract)
- 14.3Migration không gián đoạn hệ thống, bổ sung dữ liệu cũ (backfill)
- 14.4Đọc hai nơi và ghi hai nơi khi chuyển sang cơ sở dữ liệu khác
Pattern liên quan: D16 · Migration và hiện đại hoá
Đã có trong KB: 03-patterns/schema-migration
Chương 15. Sao lưu, PITR và khôi phục sau thảm hoạ
Vì sao phải tới đây
Dữ liệu trở thành tài sản thiết yếu. Bản sao không bảo vệ được dữ liệu trước lỗi do con người, như xoá nhầm hay migration hỏng.
Vấn đề để lại
RPO và RTO càng nhỏ thì chi phí càng cao. Một kế hoạch khôi phục chưa được diễn tập thì chưa thể khẳng định là thực hiện được.
- 15.1Sao lưu toàn phần, tăng dần, chênh lệch; sao lưu logic và sao lưu vật lý
- 15.2PITR: bản sao lưu nền kết hợp log lưu trữ để khôi phục về một thời điểm bất kỳ; thời hạn lưu giữ
- 15.3RPO, RTO và chi phí tương ứng
- 15.4Snapshot và sao chép sang region khác
- 15.5Diễn tập khôi phục: bản sao lưu chưa được khôi phục thử thì chưa được kiểm chứng
- 15.6Các mức khôi phục sau thảm hoạ: sao lưu và khôi phục, pilot light, warm standby, active-active
- 15.7Nhiều zone, nhiều region, chuyển region khi có sự cố
- 15.8Kiến trúc cell để khoanh vùng sự cố
Pattern liên quan: D12 · Sao lưu, độ sẵn sàng cao, khôi phục sau thảm hoạ
Đã có trong KB: 03-patterns/regional-failover · 03-patterns/cell-architecture
Chương 16. Phát hành phiên bản mới
Vì sao phải tới đây
Hệ thống được triển khai nhiều lần mỗi ngày, trong khi một phiên bản lỗi ảnh hưởng tới toàn bộ người dùng cùng lúc.
Vấn đề để lại
Nhiều phiên bản chạy song song. Feature flag tồn tại lâu trở thành nợ kỹ thuật.
- 16.1Thay toàn bộ một lần, sau đó thay dần từng máy (rolling)
- 16.2Blue/green, canary, phát hành từng bước
- 16.3Feature flag, dark launch
- 16.4Quay về phiên bản cũ hay sửa lỗi rồi tiếp tục (roll back, roll forward)
Pattern liên quan: D11 · Triển khai và phát hành
Đã có trong KB: 03-patterns/deployment-strategy
Chương 17. Quan sát hệ thống và SRE
Vì sao phải tới đây
Một yêu cầu đi qua nhiều dịch vụ, nên việc đọc log trên từng máy không còn đủ để tìm ra lỗi.
Vấn đề để lại
Khối lượng log, metric và trace rất lớn và tốn chi phí lưu trữ. Khi cảnh báo quá nhiều, đội vận hành không còn theo dõi chúng.
- 17.1Log, metric, trace và profiling
- 17.2OpenTelemetry và correlation ID
- 17.3SLI, SLO, error budget
- 17.4Cảnh báo, trực sự cố, xử lý sự cố, postmortem
- 17.5Chaos engineering
Pattern liên quan: D13 · Quan sát hệ thống
Đã có trong KB: 00-foundation/sli-slo-error-budget.md
Chương 18. Bảo mật qua từng giai đoạn
Vì sao phải tới đây
Trong hệ thống phân tán, không còn một vành đai mạng nào có thể được tin cậy.
Vấn đề để lại
Mỗi lời gọi cần danh tính và quyền. Secret, khoá mã hoá và image đều phải được quản lý.
- 18.1Từ tường lửa vành đai sang zero trust
- 18.2Xác thực và phân quyền: phiên đăng nhập, OAuth2 và OIDC, danh tính cho dịch vụ (workload identity)
- 18.3Quản lý secret
- 18.4Mã hoá khi lưu trữ, khi truyền và mã hoá đầu cuối
- 18.5Chuỗi cung ứng phần mềm: quét image, ký image, chặn image chưa ký khi triển khai
- 18.6Cô lập dữ liệu giữa các khách thuê (multi-tenancy)
Pattern liên quan: D14 · Bảo mật · D15 · Đa khách thuê · D22 · Mạng
Đã có trong KB: 02-decision/security-selection.md · 03-patterns/encryption · 03-patterns/key-management · 03-patterns/multi-tenancy.md
Chương 19. Xu hướng gần đây
Vì sao phải tới đây
Việc vận hành nền tảng tốn nhiều công sức. Tổ chức muốn trả chi phí theo mức sử dụng và để lập trình viên tự phục vụ.
Vấn đề để lại
Hệ thống phụ thuộc chặt vào nhà cung cấp, chịu độ trễ khởi động nguội (cold start), và chi phí khó dự báo.
- 19.1Serverless và FaaS
- 19.2Điện toán biên (edge computing)
- 19.3Platform engineering và internal developer platform
- 19.4FinOps: quản lý chi phí cloud
- 19.5Khối lượng công việc AI và LLM, nền tảng agent
Pattern liên quan: D1 · Tính toán và mở rộng · D2 · Kiến trúc tổng thể · D20 · ML và AI · D21 · Ngôn ngữ và runtime
Đã có trong KB: 03-patterns/serverless.md · 04-case-library/ai-agent-platform.md
CÁC DÒNG CHUYÊN SÂU · CƠ SỞ DỮ LIỆU, ML VÀ AI, NGÔN NGỮ, MẠNG
Chương 20. Lịch sử cơ sở dữ liệu: từ tệp phẳng tới vector
Vì sao phải tới đây
Mỗi thế hệ ứng dụng cần một kiểu dữ liệu và một cách mở rộng mà thế hệ cơ sở dữ liệu trước không đáp ứng được.
Vấn đề để lại
Không còn một cơ sở dữ liệu duy nhất cho mọi mục đích. Chọn sai mô hình dữ liệu thì chi phí thay đổi về sau rất lớn.
- 20.1Tệp phẳng, mô hình phân cấp (IMS), mô hình mạng (CODASYL)
- 20.2Mô hình quan hệ của Codd năm 1970, SQL, ACID
- 20.3OLTP và OLAP: data warehouse, star schema, lưu trữ theo cột
- 20.4NoSQL khởi đầu từ Bigtable và Dynamo: key-value, document, wide-column, graph
- 20.5BASE và mức nhất quán điều chỉnh được
- 20.6NewSQL và distributed SQL: Spanner, CockroachDB, TiDB, YugabyteDB
- 20.7Cơ sở dữ liệu trên cloud tách lưu trữ khỏi tính toán (Aurora, AlloyDB, Neon); cơ sở dữ liệu serverless
- 20.8Cơ sở dữ liệu chuyên dụng: chuỗi thời gian, tìm kiếm, sổ cái, dữ liệu bản đồ (PostGIS)
- 20.9HTAP: một hệ thống cho cả giao dịch và phân tích
- 20.10Cơ sở dữ liệu vector và chỉ mục vector trong cơ sở dữ liệu phổ biến (pgvector)
Pattern liên quan: D3 · Lưu trữ và mô hình dữ liệu · D19 · Bên trong cơ sở dữ liệu
Đã có trong KB: 02-decision/database-selection.md
Chương 21. Bên trong một cơ sở dữ liệu
Vì sao phải tới đây
Để mở rộng cơ sở dữ liệu và vận hành đúng CDC và PITR, cần hiểu cách cơ sở dữ liệu ghi, đọc và sao chép dữ liệu.
Vấn đề để lại
Mỗi tham số điều chỉnh được đều là một sự đánh đổi: ghi nhanh hơn thì đọc chậm hơn, độ bền dữ liệu cao hơn thì độ trễ lớn hơn.
- 21.1Storage engine: B-tree và LSM-tree, page, buffer pool, compaction
- 21.2Write-ahead log, checkpoint, fsync và độ bền dữ liệu
- 21.3Giao dịch, ACID, MVCC và việc dọn các phiên bản cũ
- 21.4Các mức cô lập (isolation) và hiện tượng đọc tương ứng: dirty read, non-repeatable read, phantom, write skew
- 21.5Khoá, deadlock, khoá lạc quan
- 21.6Các loại chỉ mục: B-tree, hash, GIN, GiST, covering, partial, chỉ mục trên JSON
- 21.7Bộ lập kế hoạch truy vấn, thống kê, cách đọc kế hoạch thực thi
- 21.8Các kiểu sao chép: một leader, nhiều leader, không leader (quorum)
- 21.9Đồng thuận: Raft, Paxos; bầu leader; split brain
- 21.10Mỗi kết nối một tiến trình hay một luồng; công cụ nhóm kết nối như PgBouncer; proxy
- 21.11Cơ sở dữ liệu do cloud quản lý hay tự vận hành; cơ sở dữ liệu trên Kubernetes bằng operator
Pattern liên quan: D19 · Bên trong cơ sở dữ liệu · D4 · Nhất quán và giao dịch · D12 · Sao lưu, độ sẵn sàng cao, khôi phục sau thảm hoạ
Đã có trong KB: 02-decision/database-selection.md · 03-patterns/data-partitioning.md
Chương 22. Kiến trúc ML và MLOps
Vì sao phải tới đây
Khi model được đưa vào vận hành thực tế, mã nguồn chỉ là một phần nhỏ. Dữ liệu, feature và model đều cần quản lý phiên bản và đường ống xử lý.
Vấn đề để lại
Chất lượng model giảm dần mà không phát sinh lỗi khi dữ liệu thay đổi. Cách tính feature lúc huấn luyện và lúc suy luận dễ lệch nhau.
- 22.1Lịch sử: luật viết tay, ML cổ điển chạy theo lô, deep learning trên GPU, foundation model
- 22.2Vòng đời model: thu thập dữ liệu, xây dựng feature, huấn luyện, đánh giá, triển khai, theo dõi
- 22.3Đường ống dữ liệu, phiên bản dữ liệu, gán nhãn
- 22.4Feature store: phần offline và online; độ lệch giữa huấn luyện và suy luận
- 22.5Huấn luyện phân tán trên GPU, TPU; theo dõi thí nghiệm
- 22.6Model registry và phiên bản model
- 22.7Suy luận theo lô, theo từng yêu cầu và theo luồng dữ liệu
- 22.8Đưa model mới vào vận hành: shadow, canary, A/B test
- 22.9Theo dõi data drift và concept drift
- 22.10Các mức trưởng thành MLOps: thủ công, đường ống tự động, CI/CD cho model
- 22.11Xếp lịch GPU trên Kubernetes và chi phí
Pattern liên quan: D20 · ML và AI · D6 · Di chuyển dữ liệu · D11 · Triển khai và phát hành
Chương 23. Kiến trúc LLM, RAG và agent
Vì sao phải tới đây
Foundation model được dùng qua API hoặc tự vận hành. Dữ liệu riêng của tổ chức cần được đưa vào mà không phải huấn luyện lại model.
Vấn đề để lại
Câu trả lời không xác định, chi phí tính theo token và độ trễ cao. Hệ thống có thêm rủi ro prompt injection và rò rỉ dữ liệu.
- 23.1Gọi qua API hay tự vận hành; LLM gateway, định tuyến giữa nhiều model
- 23.2Suy luận: gom lô (batching), bộ nhớ đệm KV, lượng tử hoá (quantization), bộ nhớ GPU
- 23.3Prompt, đầu ra có cấu trúc, gọi công cụ (function calling)
- 23.4RAG: chia đoạn, embedding, chỉ mục vector (HNSW, IVF), tìm kiếm kết hợp, xếp hạng lại
- 23.5Đồng bộ dữ liệu nguồn sang chỉ mục vector, kết nối với CDC ở chương 13
- 23.6Lựa chọn giữa fine-tune, RAG và điều chỉnh prompt
- 23.7Agent: vòng lập kế hoạch, hành động, quan sát; hệ nhiều agent; bộ nhớ; điều phối
- 23.8Đánh giá: bộ kiểm thử offline, dùng LLM để chấm điểm, kiểm thử hồi quy
- 23.9Guardrail: chặn prompt injection, che dữ liệu cá nhân, kiểm tra đầu ra
- 23.10Bộ nhớ đệm ngữ nghĩa, bộ nhớ đệm prompt, kiểm soát chi phí và độ trễ
- 23.11Quan sát LLM: trace từng bước, số token, chi phí
Pattern liên quan: D20 · ML và AI · D18 · Tìm kiếm và phân tích · D14 · Bảo mật
Đã có trong KB: 04-case-library/ai-agent-platform.md · 03-patterns/search-indexing
Chương 24. Cách ngôn ngữ lập trình được thực thi trên máy tính
Vì sao phải tới đây
Mọi kiến trúc cuối cùng đều chạy trên một runtime. Runtime quyết định thời gian khởi động, lượng bộ nhớ sử dụng và cách thực thi song song.
Vấn đề để lại
Không ngôn ngữ nào đồng thời đạt hiệu năng cao nhất, an toàn bộ nhớ cao nhất và tốc độ phát triển nhanh nhất. Mỗi ngôn ngữ chấp nhận hy sinh một tiêu chí.
- 24.1Máy tính chỉ thực thi lệnh của CPU. Mỗi ngôn ngữ là một cách dịch mã nguồn xuống các lệnh đó, thông qua thanh ghi, bộ nhớ đệm, bộ nhớ trong và lời gọi hệ thống
- 24.2Lịch sử: mã máy, assembly, Fortran và COBOL, C, C++, Java và C# chạy trên máy ảo, các ngôn ngữ kịch bản (Perl, PHP, Python, JavaScript), sau đó là Go, Rust, Kotlin, TypeScript
- 24.3Cách thực thi: biên dịch trước ra mã máy (AOT), bytecode chạy trên máy ảo có JIT, trình thông dịch, engine JIT như V8, WebAssembly
- 24.4Cách quản lý bộ nhớ: cấp phát và giải phóng thủ công (C), RAII (C++), ownership (Rust), garbage collector (Java, Go, C#, JavaScript), đếm tham chiếu (Python, Swift)
- 24.5Cách thực thi song song: luồng của hệ điều hành, goroutine và virtual thread, event loop (Node.js, asyncio), actor (Erlang, Elixir); GIL của CPython và bản build không có GIL
- 24.6Hệ thống kiểu: tĩnh hay động, chặt hay lỏng, suy luận kiểu, chống lỗi null
- 24.7Runtime khi triển khai: tệp nhị phân độc lập hay cần cài runtime; thời gian khởi động, kích thước image, khởi động nguội; AOT cho Java và .NET (GraalVM native image, .NET Native AOT từ .NET 7)
- 24.8Gọi chéo ngôn ngữ (FFI): Python phục vụ được ML nhờ gọi xuống C, C++ và CUDA; JNI; WebAssembly
- 24.9Lý do các ngôn ngữ không thay thế được nhau: ba lựa chọn nền tảng về cách dịch, cách quản lý bộ nhớ và cách thực thi song song đã gắn mỗi ngôn ngữ với một ngách riêng
Pattern liên quan: D21 · Ngôn ngữ và runtime · D1 · Tính toán và mở rộng
Đã có trong KB: 02-decision/compute-selection.md
Chương 25. Thế mạnh của từng ngôn ngữ và tiêu chí lựa chọn
Vì sao phải tới đây
Sau khi đã nắm cơ chế ở chương 24, câu hỏi còn lại là công việc nào nên dùng ngôn ngữ nào và vì sao.
Vấn đề để lại
Một hệ thống dùng nhiều ngôn ngữ thì tốn thêm chi phí vận hành, khó tuyển dụng hơn và khó dùng chung thư viện.
- 25.1C và C++: hệ điều hành, thiết bị nhúng, game engine, engine cơ sở dữ liệu, giao dịch tần suất cao
- 25.2Rust: phần mềm hệ thống cần an toàn bộ nhớ mà không dùng garbage collector, công cụ hạ tầng, WebAssembly
- 25.3Go: hạ tầng cloud như Kubernetes, Docker, Terraform; các dịch vụ mạng
- 25.4Java và Kotlin: hệ thống doanh nghiệp phía máy chủ, big data trên JVM (Kafka, Spark, Flink), Android
- 25.5C# và .NET: ứng dụng doanh nghiệp, hệ sinh thái Microsoft, game với Unity
- 25.6Python: xử lý dữ liệu, ML và AI, viết kịch bản, tích hợp các hệ thống
- 25.7JavaScript và TypeScript: giao diện web, phía máy chủ với Node.js, full-stack
- 25.8Erlang và Elixir: viễn thông, nhắn tin, hệ thống tự phục hồi khi lỗi, chạy trên máy ảo BEAM
- 25.9SQL: ngôn ngữ khai báo chuyên cho dữ liệu
- 25.10Các ngách khác: Swift, Scala, PHP, Ruby, R, Julia, CUDA, Solidity
- 25.11Tiêu chí lựa chọn: năng lực hiện có của đội, thư viện sẵn có, hiệu năng, độ trễ do garbage collector, cách triển khai, thị trường tuyển dụng
- 25.12Microservices viết bằng nhiều ngôn ngữ: lợi ích và chi phí
- 25.13Bảng so sánh các ngôn ngữ theo cách thực thi, bộ nhớ, thực thi song song, thời gian khởi động và ngách
Pattern liên quan: D21 · Ngôn ngữ và runtime · D2 · Kiến trúc tổng thể · D20 · ML và AI
Chương 26. Mạng máy tính: nền tảng
Vì sao phải tới đây
Từ chương 2, mọi thành phần giao tiếp với nhau qua mạng. Nhiều lỗi có biểu hiện như lỗi ứng dụng nhưng nguyên nhân thực sự nằm ở mạng.
Vấn đề để lại
Mỗi tầng mạng thêm độ trễ và một dạng lỗi riêng. Thiết kế phải tính đến mạng chậm, mất kết nối và kết nối chập chờn.
- 26.1Mô hình OSI và TCP/IP: chức năng của từng tầng
- 26.2Địa chỉ IP, subnet, CIDR; IPv4 và IPv6
- 26.3TCP và UDP: bắt tay, kiểm soát tắc nghẽn, duy trì kết nối (keep-alive)
- 26.4DNS: phân giải tên, TTL, bộ nhớ đệm DNS
- 26.5HTTP/1.1, HTTP/2, HTTP/3 và QUIC: vấn đề mà mỗi phiên bản giải quyết
- 26.6TLS: bắt tay, chứng chỉ, mTLS
- 26.7Độ trễ thực tế: trong một máy, trong một zone, giữa các region, giữa các châu lục
- 26.8Lịch sử: mạng nội bộ, Internet công cộng, CDN, mạng định nghĩa bằng phần mềm (SDN)
Pattern liên quan: D22 · Mạng
Chương 27. Mạng trong cloud và Kubernetes
Vì sao phải tới đây
Trên cloud và Kubernetes, mạng được định nghĩa bằng cấu hình thay cho cáp vật lý, gồm VPC, tường lửa, bảng định tuyến và chính sách mạng.
Vấn đề để lại
Cấu hình mạng sai hiếm khi tạo ra thông báo lỗi rõ ràng. Yêu cầu bị treo hoặc bị từ chối mà không hiển thị nguyên nhân.
- 27.1VPC, subnet, bảng định tuyến, quy tắc tường lửa, security group
- 27.2NAT gateway và kiểm soát lưu lượng đi ra ngoài (egress)
- 27.3Kết nối các mạng: VPN, peering, interconnect, mô hình hub-and-spoke
- 27.4Gọi dịch vụ cloud qua đường kết nối riêng: private endpoint, Private Service Connect
- 27.5Cân bằng tải của cloud: toàn cầu hay theo region, tầng 4 hay tầng 7, anycast
- 27.6Mạng trong Kubernetes: CNI, Service, kube-proxy, Ingress, Gateway API
- 27.7Network policy và eBPF
- 27.8Service mesh: kiến trúc có sidecar và không có sidecar
- 27.9Chẩn đoán mạng: traceroute, tcpdump, đọc log của cân bằng tải và tường lửa
Pattern liên quan: D22 · Mạng · D14 · Bảo mật
Đã có trong KB: 03-patterns/routing · 03-patterns/regional-failover
PHẦN II · PATTERN THEO DOMAIN
D1. Tính toán và mở rộng
- D1.1Mở rộng theo chiều dọc và mở rộng theo chiều ngang
- D1.2Dịch vụ không giữ trạng thái
- D1.3Tự động điều chỉnh số máy
- D1.4Thuật toán phân phối tải
- D1.5Sidecar
- D1.6Ambassador
- D1.7Adapter
Xuất hiện ở: 1 · Kiến trúc một máy chủ · 2 · Tách cơ sở dữ liệu · 3 · Nhiều máy chủ ứng dụng · 7 · Máy vật lý, máy ảo, cloud · 9 · Container và Kubernetes · 19 · Xu hướng gần đây · 24 · Thực thi ngôn ngữ lập trình
D2. Kiến trúc tổng thể
- D2.1Kiến trúc phân tầng
- D2.2Hexagonal và Clean Architecture
- D2.3Modular monolith
- D2.4Microservices
- D2.5SOA
- D2.6Serverless
- D2.7Kiến trúc cell
- D2.8Strangler fig
- D2.9Anti-corruption layer
Xuất hiện ở: 8 · Monolith sang microservices · 19 · Xu hướng gần đây · 25 · Chọn ngôn ngữ
Đã có trong KB: 03-patterns/architectural-decisions
D3. Lưu trữ và mô hình dữ liệu
- D3.1Mỗi dịch vụ một cơ sở dữ liệu
- D3.2Dùng chung cơ sở dữ liệu (cần tránh)
- D3.3Mỗi loại dữ liệu một loại cơ sở dữ liệu
- D3.4Partitioning và sharding
- D3.5Consistent hashing
- D3.6Materialized view
- D3.7Bảng chỉ mục riêng
Xuất hiện ở: 2 · Tách cơ sở dữ liệu · 5 · Mở rộng cơ sở dữ liệu · 20 · Lịch sử cơ sở dữ liệu
Đã có trong KB: 03-patterns/storage-partition
D4. Nhất quán và giao dịch
- D4.1Two-phase commit
- D4.2Saga
- D4.3Outbox và inbox
- D4.4Bên tiêu thụ xử lý trùng an toàn
- D4.5Khoá lạc quan và khoá bi quan
- D4.6Khoá phân tán
- D4.7Fencing token
- D4.8CRDT
Xuất hiện ở: 12 · Nhất quán khi tách cơ sở dữ liệu · 21 · Bên trong cơ sở dữ liệu
Đã có trong KB: 03-patterns/conflict-resolution
D5. Truyền thông điệp và tích hợp
- D5.1Hàng đợi
- D5.2Pub/Sub
- D5.3Fan-out
- D5.4Nhiều bên tiêu thụ chia nhau xử lý
- D5.5Hàng đợi có độ ưu tiên
- D5.6Hàng đợi thông điệp lỗi (dead letter queue)
- D5.7Topic riêng cho thử lại
- D5.8Khoá giữ thứ tự
- D5.9Claim check
- D5.10Yêu cầu–phản hồi
- D5.11Xác nhận đã nhận (delivery receipt)
Xuất hiện ở: 6 · Xử lý bất đồng bộ · 11 · Hướng sự kiện và Pub/Sub
Đã có trong KB: 03-patterns/fan-out · 03-patterns/ordering · 03-patterns/delivery-receipt
D6. Di chuyển dữ liệu
- D6.1CDC
- D6.2ETL và ELT
- D6.3Sao chép dữ liệu
- D6.4Sự kiện mang theo dữ liệu
- D6.5Bổ sung dữ liệu cũ (backfill)
- D6.6Luồng thay đổi sang hệ tìm kiếm, bộ nhớ đệm và kho dữ liệu
Xuất hiện ở: 13 · CDC và đường đi của dữ liệu · 22 · ML và MLOps
Đã có trong KB: 03-patterns/pipeline-handler.md
D7. Hướng sự kiện
- D7.1Sự kiện thông báo
- D7.2Event sourcing
- D7.3CQRS
- D7.4Event store
- D7.5Snapshot
- D7.6Projection
- D7.7Thay đổi schema sự kiện
Xuất hiện ở: 11 · Hướng sự kiện và Pub/Sub
Đã có trong KB: 03-patterns/event-driven.md
D8. Bộ nhớ đệm
- D8.1Nạp khi cần
- D8.2Đọc xuyên và ghi xuyên
- D8.3Ghi sau
- D8.4Làm mới trước khi hết hạn
- D8.5Lưu cả kết quả rỗng
- D8.6Gộp các yêu cầu trùng
- D8.7Bộ nhớ đệm nhiều tầng
Xuất hiện ở: 4 · Bộ nhớ đệm và CDN
Đã có trong KB: 03-patterns/caching
D9. API và giao tiếp
- D9.1API gateway
- D9.2Backend for frontend
- D9.3Service mesh
- D9.4Phiên bản API
- D9.5Phân trang
- D9.6Giới hạn tốc độ
- D9.7Điều tiết lưu lượng (throttling)
- D9.8Long polling, WebSocket, SSE
Xuất hiện ở: 3 · Nhiều máy chủ ứng dụng · 10 · Giao tiếp giữa các dịch vụ
Đã có trong KB: 03-patterns/pagination · 03-patterns/rate-limiting · 03-patterns/push-notification
D10. Chịu lỗi
- D10.1Timeout
- D10.2Thử lại có backoff và jitter
- D10.3Circuit breaker
- D10.4Bulkhead
- D10.5Fallback
- D10.6Giảm tải chủ động (load shedding)
- D10.7Backpressure
- D10.8Health check
- D10.9Suy giảm chức năng có kiểm soát thay vì ngừng hoạt động
Xuất hiện ở: 6 · Xử lý bất đồng bộ · 10 · Giao tiếp giữa các dịch vụ
Đã có trong KB: 03-patterns/resilience
D11. Triển khai và phát hành
- D11.1Rolling
- D11.2Blue/green
- D11.3Canary
- D11.4Feature flag
- D11.5Chạy thử bằng lưu lượng thật (shadow)
- D11.6GitOps
- D11.7Hạ tầng bất biến
Xuất hiện ở: 7 · Máy vật lý, máy ảo, cloud · 9 · Container và Kubernetes · 16 · Phát hành phiên bản mới · 22 · ML và MLOps
Đã có trong KB: 03-patterns/deployment-strategy
D12. Sao lưu, độ sẵn sàng cao, khôi phục sau thảm hoạ
- D12.1Sao lưu toàn phần và tăng dần
- D12.2PITR
- D12.3Snapshot
- D12.4Standby nóng, ấm, lạnh
- D12.5Active–passive
- D12.6Active–active
- D12.7Chuyển region
- D12.8Quorum
Xuất hiện ở: 1 · Kiến trúc một máy chủ · 5 · Mở rộng cơ sở dữ liệu · 15 · Sao lưu, PITR, khôi phục · 21 · Bên trong cơ sở dữ liệu
Đã có trong KB: 03-patterns/regional-failover
D13. Quan sát hệ thống
- D13.1Log có cấu trúc
- D13.2Correlation ID
- D13.3Distributed tracing
- D13.4Metric RED và USE
- D13.5Cảnh báo theo SLO
- D13.6Audit log
Xuất hiện ở: 17 · Quan sát hệ thống, SRE
Đã có trong KB: 00-foundation/sli-slo-error-budget.md
D14. Bảo mật
- D14.1Zero trust
- D14.2mTLS
- D14.3Xác thực bằng token
- D14.4Kho secret
- D14.5Envelope encryption
- D14.6Xoay vòng khoá
- D14.7Quyền tối thiểu
- D14.8Chính sách dạng mã (policy as code)
Xuất hiện ở: 18 · Bảo mật qua từng giai đoạn · 23 · LLM, RAG và agent · 27 · Mạng trong cloud và Kubernetes
Đã có trong KB: 03-patterns/encryption · 03-patterns/key-management
D15. Đa khách thuê
- D15.1Mỗi khách thuê một bộ tài nguyên riêng (silo)
- D15.2Dùng chung toàn bộ (pool)
- D15.3Kết hợp (bridge)
- D15.4Định tuyến theo khách thuê
- D15.5Ngăn một khách thuê chiếm dụng tài nguyên
Xuất hiện ở: 18 · Bảo mật qua từng giai đoạn
Đã có trong KB: 03-patterns/multi-tenancy.md · 03-patterns/cell-architecture
D16. Migration và hiện đại hoá
- D16.1Strangler fig
- D16.2Branch by abstraction
- D16.3Expand–contract
- D16.4Ghi hai nơi
- D16.5Đọc hai nơi
- D16.6Đọc thử song song (shadow read)
- D16.7Chạy song song hai hệ thống
Xuất hiện ở: 8 · Monolith sang microservices · 14 · Thay đổi schema, di chuyển dữ liệu
Đã có trong KB: 03-patterns/strangler-fig.md · 03-patterns/schema-migration
D17. Thời gian thực và đồng bộ
- D17.1Trạng thái trực tuyến (presence)
- D17.2Pub/Sub thời gian thực
- D17.3Đồng bộ trạng thái
- D17.4Đồng bộ thời gian, đồng hồ logic
- D17.5Đồng bộ nhiều thiết bị
Xuất hiện ở: 11 · Hướng sự kiện và Pub/Sub
Đã có trong KB: 03-patterns/presence · 03-patterns/time-sync · 03-patterns/state-sync-game · 03-patterns/multi-device-sync
D18. Tìm kiếm và phân tích
- D18.1Chỉ mục đảo (inverted index)
- D18.2Đồng bộ chỉ mục bằng CDC
- D18.3OLTP và OLAP
- D18.4Tính tổng hợp trước
- D18.5Lambda và Kappa
Xuất hiện ở: 13 · CDC và đường đi của dữ liệu · 23 · LLM, RAG và agent
Đã có trong KB: 03-patterns/search-indexing
D19. Bên trong cơ sở dữ liệu
- D19.1B-tree và LSM-tree
- D19.2Write-ahead log
- D19.3MVCC
- D19.4Mức cô lập
- D19.5Các loại chỉ mục
- D19.6Kế hoạch thực thi
- D19.7Một leader, nhiều leader, không leader
- D19.8Đọc ghi theo quorum
- D19.9Raft và Paxos
- D19.10Tách lưu trữ khỏi tính toán
- D19.11Nhóm kết nối
Xuất hiện ở: 5 · Mở rộng cơ sở dữ liệu · 20 · Lịch sử cơ sở dữ liệu · 21 · Bên trong cơ sở dữ liệu
Đã có trong KB: 02-decision/database-selection.md
D20. ML và AI
- D20.1Feature store
- D20.2Đường ống huấn luyện
- D20.3Model registry
- D20.4Suy luận theo lô, theo yêu cầu, theo luồng
- D20.5Shadow và canary cho model
- D20.6Theo dõi drift
- D20.7RAG
- D20.8Chỉ mục vector
- D20.9Tìm kiếm kết hợp và xếp hạng lại
- D20.10LLM gateway
- D20.11Bộ nhớ đệm ngữ nghĩa
- D20.12Guardrail
- D20.13Bộ đánh giá
- D20.14Điều phối agent
Xuất hiện ở: 19 · Xu hướng gần đây · 22 · ML và MLOps · 23 · LLM, RAG và agent · 25 · Chọn ngôn ngữ
Đã có trong KB: 04-case-library/ai-agent-platform.md
D21. Ngôn ngữ và runtime
- D21.1Nhóm luồng, nhóm worker
- D21.2Event loop
- D21.3Actor
- D21.4Goroutine và channel (CSP)
- D21.5async/await, future, promise
- D21.6Nhiều tiến trình để vượt giới hạn của GIL
- D21.7Object pool, arena allocator
- D21.8Zero-copy I/O
- D21.9Gọi C từ ngôn ngữ khác (FFI)
- D21.10Sidecar cho hệ thống nhiều ngôn ngữ
- D21.11Plugin bằng WebAssembly
- D21.12Giảm khởi động nguội: AOT native image, giữ sẵn instance
Xuất hiện ở: 19 · Xu hướng gần đây · 24 · Thực thi ngôn ngữ lập trình · 25 · Chọn ngôn ngữ
Đã có trong KB: 02-decision/compute-selection.md
D22. Mạng
- D22.1Cân bằng tải tầng 4 và tầng 7
- D22.2Reverse proxy
- D22.3Anycast và cân bằng tải toàn cầu
- D22.4CDN
- D22.5Chuyển đổi dự phòng (failover) bằng DNS
- D22.6Khám phá dịch vụ
- D22.7Hub-and-spoke
- D22.8VPC peering
- D22.9Private endpoint
- D22.10NAT và kiểm soát egress
- D22.11mTLS
- D22.12Duy trì kết nối và nhóm kết nối
- D22.13Ghép kênh HTTP/2
- D22.14Network policy
Xuất hiện ở: 2 · Tách cơ sở dữ liệu · 3 · Nhiều máy chủ ứng dụng · 4 · Bộ nhớ đệm và CDN · 9 · Container và Kubernetes · 10 · Giao tiếp giữa các dịch vụ · 18 · Bảo mật qua từng giai đoạn · 26 · Nền tảng mạng · 27 · Mạng trong cloud và Kubernetes
Đã có trong KB: 03-patterns/routing · 03-patterns/regional-failover
PHẦN III · TỔNG HỢP
Chương 28. Ma trận giai đoạn và domain
- 28.1Bảng đối chiếu giữa domain và các chương liên quan
- 28.2Lộ trình tham khảo cho ba quy mô: công ty khởi nghiệp, công ty đang tăng trưởng, doanh nghiệp lớn
Chương 29. Các sai lầm thường gặp theo từng giai đoạn
- 29.1Áp dụng quá sớm: microservices hoặc Kubernetes khi chưa có nhu cầu
- 29.2Áp dụng quá muộn: hệ thống đã lớn nhưng chưa có bản sao lưu được kiểm chứng và chưa có công cụ quan sát
- 29.3Distributed monolith, dùng chung cơ sở dữ liệu, dịch vụ gọi nhau quá nhiều, ghi hai nơi không có outbox
Chuyển lên microservices hoặc Kubernetes khi chưa chạm giới hạn.
Nội dung dự kiến: dấu hiệu nhận biết, chi phí vận hành phát sinh, cách quay về modular monolith.
Hệ thống đã lớn nhưng bản sao lưu chưa từng được khôi phục thử và chưa có công cụ quan sát.
Nội dung dự kiến: các sự cố điển hình khi vấn đề được phát hiện muộn.
Tách dịch vụ nhưng vẫn triển khai đồng thời và dùng chung cơ sở dữ liệu.
Nội dung dự kiến: cách nhận biết distributed monolith và cách khắc phục.
Ghi vào hai nơi mà không dùng outbox.
Nội dung dự kiến: các điểm dữ liệu bị mất khi tiến trình dừng giữa hai lần ghi (chương 12).
Một yêu cầu của người dùng sinh ra hàng chục lời gọi đồng bộ.
Nội dung dự kiến: cách đo, cách gộp lời gọi, thời điểm nên chuyển sang sự kiện.
Chọn ngôn ngữ theo sở thích thay vì theo ngách.
Nội dung dự kiến: các ví dụ như chọn runtime khởi động chậm cho serverless hoặc dùng Python cho tác vụ nặng về CPU (chương 25).
Quy lỗi cho ứng dụng khi nguyên nhân nằm ở mạng.
Nội dung dự kiến: dấu hiệu của lỗi DNS, hết thời gian chờ, MTU và tường lửa (chương 26).
Chương 30. Kiểm tra trước khi chuyển sang giai đoạn sau
- 30.1Ngưỡng đo cho từng lần chuyển
- 30.2Các câu hỏi cần trả lời trước khi chuyển
Bốn câu hỏi trước mỗi lần chuyển
- Trục nào đã chạm giới hạn, và được đo bằng chỉ số nào: lưu lượng truy cập, độ trễ p99, dung lượng, số đội, số lần triển khai mỗi ngày?
- Giai đoạn hiện tại đã được khai thác hết chưa: chỉ mục, bộ nhớ đệm, mở rộng theo chiều dọc, phân chia module?
- Giai đoạn mới sẽ để lại vấn đề gì, và đội có đủ năng lực vận hành không?
- Nếu chuyển đổi không phù hợp, hệ thống quay lại giai đoạn trước bằng cách nào?
Đã có trong KB: 06-validation/design-review-checklist.md
Chương 31. Một hệ thống qua toàn bộ các giai đoạn
- 31.1Trình bày một hệ thống đi qua lần lượt các chương 1 đến 27
- 31.2Liên kết với các tình huống có sẵn trong KB
Gợi ý: chọn một sản phẩm giả định, chẳng hạn một trang thương mại điện tử. Trình bày lần lượt các mốc 1 nghìn, 100 nghìn và 10 triệu người dùng. Tại mỗi mốc, ghi rõ hệ thống chuyển sang chương nào và chỉ số nào buộc phải chuyển.
Đã có trong KB: 04-case-library/
PHỤ LỤC
Phụ lục A. Thuật ngữ
- Điểm lỗi đơn (SPOF)
- Thành phần mà khi hỏng thì toàn bộ hệ thống ngừng hoạt động.
- Không giữ trạng thái (stateless)
- Tính chất của dịch vụ không lưu trạng thái giữa các yêu cầu, nhờ đó mỗi yêu cầu có thể được xử lý trên bất kỳ máy nào.
- Cân bằng tải tầng 4, tầng 7
- Cân bằng tải tầng 4 phân phối theo kết nối TCP hoặc UDP. Cân bằng tải tầng 7 phân phối theo nội dung HTTP như đường dẫn hoặc header.
- Độ trễ sao chép (replication lag)
- Khoảng thời gian từ lúc primary ghi một thay đổi tới lúc bản sao nhận được thay đổi đó.
- Sharding
- Phân chia dữ liệu của một bảng ra nhiều cơ sở dữ liệu theo một khoá, mỗi cơ sở dữ liệu giữ một phần.
- Dồn tải (cache stampede)
- Hiện tượng nhiều yêu cầu cùng gặp một khoá vừa hết hạn trong bộ nhớ đệm và cùng truy vấn cơ sở dữ liệu tại một thời điểm.
- Hạ tầng bất biến
- Nguyên tắc không sửa máy đang chạy. Mọi thay đổi được thực hiện bằng cách dựng image mới rồi thay máy.
- Bounded context
- Phạm vi trong đó một mô hình nghiệp vụ và hệ thuật ngữ của nó mang một nghĩa thống nhất (theo DDD).
- Service mesh
- Lớp proxy đặt cạnh mỗi dịch vụ, đảm nhận mTLS, thử lại và định tuyến thay cho mã ứng dụng.
- Ghi hai nơi (dual-write)
- Ứng dụng ghi cùng một thay đổi vào hai nơi mà không có giao dịch chung.
- Outbox
- Kỹ thuật ghi sự kiện vào một bảng trong cùng giao dịch với dữ liệu nghiệp vụ, sau đó một tiến trình khác đọc bảng này và phát sự kiện ra ngoài.
- Saga
- Chuỗi giao dịch cục bộ trên nhiều dịch vụ. Khi một bước thất bại, hệ thống chạy các bước bù trừ cho những bước đã hoàn tất.
- Idempotency
- Tính chất của thao tác mà việc thực hiện nhiều lần cho cùng kết quả như thực hiện một lần. Tính chất này là điều kiện để việc thử lại được an toàn.
- Event sourcing, CQRS
- Event sourcing lưu chuỗi sự kiện thay vì trạng thái cuối cùng. CQRS tách mô hình ghi khỏi mô hình đọc.
- CDC
- Change data capture: kỹ thuật đọc log giao dịch của cơ sở dữ liệu để phát mọi thay đổi ra ngoài.
- PITR
- Point-in-time recovery: khôi phục cơ sở dữ liệu về một thời điểm bất kỳ bằng bản sao lưu nền kết hợp với log lưu trữ.
- RPO, RTO
- Mục tiêu điểm khôi phục (RPO) là lượng dữ liệu tối đa được phép mất, tính bằng thời gian. Mục tiêu thời gian khôi phục (RTO) là thời gian tối đa được phép để hoàn tất việc khôi phục.
- Canary
- Phát hành phiên bản mới cho một phần nhỏ lưu lượng, theo dõi kết quả rồi mới mở rộng.
- SLI, SLO, error budget
- SLI là chỉ số đo chất lượng dịch vụ. SLO là mục tiêu cho chỉ số đó. Error budget là mức lỗi được phép trước khi phải tạm dừng phát hành tính năng mới.
- Zero trust
- Mô hình bảo mật không tin cậy một lời gọi chỉ vì lời gọi đó xuất phát từ mạng nội bộ. Mọi lời gọi đều phải được xác thực và kiểm tra quyền.
- Kiến trúc cell
- Kiến trúc chia hệ thống thành nhiều bản độc lập gọi là cell. Mỗi cell phục vụ một phần người dùng, nên một sự cố chỉ ảnh hưởng tới phần người dùng đó.
- MVCC
- Cơ chế lưu nhiều phiên bản của cùng một hàng để thao tác đọc không phải chờ thao tác ghi.
- LSM-tree
- Cấu trúc lưu trữ ghi vào bộ nhớ trước, sau đó xả ra tệp và gộp dần. Cấu trúc này cho phép ghi nhanh, nhưng khi đọc phải tra cứu nhiều tầng.
- Feature store
- Kho lưu feature dùng chung cho huấn luyện và suy luận, để hai giai đoạn tính feature theo cùng một cách.
- Data drift
- Hiện tượng dữ liệu lúc suy luận lệch dần so với dữ liệu huấn luyện, làm chất lượng model giảm.
- RAG
- Kỹ thuật tìm các đoạn tài liệu liên quan rồi đưa vào prompt, để LLM trả lời dựa trên dữ liệu riêng.
- AOT, JIT
- AOT dịch mã nguồn ra mã máy trước khi chạy. JIT dịch trong lúc chạy và ưu tiên những đoạn mã được thực thi nhiều.
- Garbage collector
- Thành phần của runtime tự tìm và giải phóng bộ nhớ không còn được dùng. Đổi lại, chương trình đôi khi phải tạm dừng ngắn và tốn thêm bộ nhớ.
- GIL
- Khoá toàn cục của CPython: tại một thời điểm chỉ một luồng được thực thi bytecode Python. Python 3.13 có bản build không GIL ở dạng thử nghiệm, và từ 3.14 bản build này được hỗ trợ chính thức (PEP 703, PEP 779). Tuy vậy, đây vẫn là bản cài đặt riêng và không phải mặc định.
- FFI
- Cơ chế cho phép mã viết bằng một ngôn ngữ gọi hàm viết bằng ngôn ngữ khác, thường là C.
- Khởi động nguội (cold start)
- Độ trễ ở lần thực thi đầu tiên do runtime phải khởi động, thường gặp ở serverless và JVM.
- CIDR
- Cách ký hiệu một dải địa chỉ IP. Ví dụ, 10.0.0.0/16 là 65.536 địa chỉ bắt đầu từ 10.0.0.0.
- Anycast
- Kỹ thuật cho phép nhiều máy ở nhiều vị trí cùng nhận một địa chỉ IP. Người dùng được định tuyến tới máy gần nhất.
- Egress
- Lưu lượng đi từ bên trong hệ thống ra ngoài. Lưu lượng này thường cần được kiểm soát để ngăn rò rỉ dữ liệu.
Phụ lục B. Tài liệu tham khảo
- Martin Kleppmann, Designing Data-Intensive Applications: sao chép, phân vùng, giao dịch, xử lý luồng; dùng cho chương 5, 11, 12, 13.
- Alex Petrov, Database Internals: storage engine, sao chép, đồng thuận; dùng cho chương 21 và D19.
- Sam Newman, Building Microservices và Monolith to Microservices: dùng cho chương 8 và 14.
- Michael Nygard, Release It!: các pattern giữ hệ thống ổn định; dùng cho chương 10 và D10.
- Google, Site Reliability Engineering: dùng cho chương 17.
- Gregor Hohpe, Bobby Woolf, Enterprise Integration Patterns: dùng cho D5.
- Chris Richardson, microservices.io: saga, outbox, CQRS; dùng cho chương 12, D4, D7.
- Chip Huyen, Designing Machine Learning Systems và AI Engineering: dùng cho chương 22 và 23.
- D. Sculley và cộng sự, Hidden Technical Debt in Machine Learning Systems, NeurIPS 2015: dùng cho chương 22.
- Randal Bryant, David O'Hallaron, Computer Systems: A Programmer's Perspective: từ mã máy, bộ nhớ tới tiến trình; dùng cho chương 24.
- Robert Nystrom, Crafting Interpreters: trình thông dịch, máy ảo bytecode, garbage collector; dùng cho chương 24.
- Ilya Grigorik, High Performance Browser Networking: TCP, TLS, HTTP/2, độ trễ; dùng cho chương 26.
Phụ lục C. Khung viết cho chương và pattern
Mỗi chương ở Phần I
Bối cảnh: kiến trúc hệ thống tại thời điểm đó, kèm sơ đồ.
Lý do chuyển: giới hạn đã bị chạm tới, kèm số liệu.
Giải pháp: thay đổi cụ thể của kiến trúc.
Vấn đề để lại: chi phí mới phát sinh, đồng thời là lý do của chương sau.
Pattern liên quan: liên kết sang Phần II.
Sai lầm thường gặp.
Khi nào chưa cần: dấu hiệu cho thấy việc chuyển là quá sớm.
Mỗi pattern ở Phần II
Vấn đề được giải quyết. Cơ chế hoạt động. Khi nào nên dùng và khi nào không. Sự đánh đổi. Các biến thể. Công nghệ tiêu biểu. Pattern liên quan.
Pattern nào đã có tệp trong core/system-design-knowledge/03-patterns/ thì liên kết sang tệp đó thay vì chép lại.
Mỗi ngôn ngữ ở chương 25
Ngách. Cách thực thi. Cách quản lý bộ nhớ. Cách thực thi song song. Thế mạnh và nguyên nhân. Điểm yếu. Khi nào nên chọn, khi nào nên tránh. Hệ sinh thái tiêu biểu.
Hai nội dung mở đầu mỗi chương
Mỗi chương đã có sẵn hai nội dung: lý do phải chuyển tới giai đoạn này, và vấn đề để lại. Vấn đề để lại của một chương là lý do của chương sau. Khi viết, cần giữ mạch liên kết này.
Phụ lục D. Giới hạn mặc định hay gặp
- D.1Máy chủ ứng dụng và runtime: Tomcat, HikariCP, nginx, Node.js, Go
- D.2Cơ sở dữ liệu và nhóm kết nối: PostgreSQL, MySQL, PgBouncer, Redis
- D.3Hệ điều hành, cân bằng tải, Kubernetes: somaxconn, AWS ALB, GCP LB, probe