diff --git a/README-ja.md b/README-ja.md index 74400bdd70..38febcfa9a 100644 --- a/README-ja.md +++ b/README-ja.md @@ -1,4 +1,4 @@ -*[English](README.md) ∙ [日本語](README-ja.md) ∙ [简体中文](README-zh-Hans.md) ∙ [繁體中文](README-zh-TW.md) | [العَرَبِيَّة‎](https://github.com/donnemartin/system-design-primer/issues/170) ∙ [বাংলা](https://github.com/donnemartin/system-design-primer/issues/220) ∙ [Português do Brasil](https://github.com/donnemartin/system-design-primer/issues/40) ∙ [Deutsch](https://github.com/donnemartin/system-design-primer/issues/186) ∙ [ελληνικά](https://github.com/donnemartin/system-design-primer/issues/130) ∙ [עברית](https://github.com/donnemartin/system-design-primer/issues/272) ∙ [Italiano](https://github.com/donnemartin/system-design-primer/issues/104) ∙ [한국어](https://github.com/donnemartin/system-design-primer/issues/102) ∙ [فارسی](https://github.com/donnemartin/system-design-primer/issues/110) ∙ [Polski](https://github.com/donnemartin/system-design-primer/issues/68) ∙ [русский язык](https://github.com/donnemartin/system-design-primer/issues/87) ∙ [Español](https://github.com/donnemartin/system-design-primer/issues/136) ∙ [ภาษาไทย](https://github.com/donnemartin/system-design-primer/issues/187) ∙ [Türkçe](https://github.com/donnemartin/system-design-primer/issues/39) ∙ [tiếng Việt](https://github.com/donnemartin/system-design-primer/issues/127) ∙ [Français](https://github.com/donnemartin/system-design-primer/issues/250) | [Add Translation](https://github.com/donnemartin/system-design-primer/issues/28)* +*[English](README.md) ∙ [日本語](README-ja.md) ∙ [简体中文](README-zh-Hans.md) ∙ [繁體中文](README-zh-TW.md) | [العَرَبِيَّة‎](https://github.com/donnemartin/system-design-primer/issues/170) ∙ [বাংলা](https://github.com/donnemartin/system-design-primer/issues/220) ∙ [Português do Brasil](https://github.com/donnemartin/system-design-primer/issues/40) ∙ [Deutsch](https://github.com/donnemartin/system-design-primer/issues/186) ∙ [ελληνικά](https://github.com/donnemartin/system-design-primer/issues/130) ∙ [עברית](https://github.com/donnemartin/system-design-primer/issues/272) ∙ [Italiano](https://github.com/donnemartin/system-design-primer/issues/104) ∙ [한국어](https://github.com/donnemartin/system-design-primer/issues/102) ∙ [فارسی](https://github.com/donnemartin/system-design-primer/issues/110) ∙ [Polski](https://github.com/donnemartin/system-design-primer/issues/68) ∙ [русский язык](https://github.com/donnemartin/system-design-primer/issues/87) ∙ [Español](https://github.com/donnemartin/system-design-primer/issues/136) ∙ [ภาษาไทย](https://github.com/donnemartin/system-design-primer/issues/187) ∙ [Türkçe](https://github.com/donnemartin/system-design-primer/issues/39) ∙ [tiếng Việt](README-vi.md) ∙ [Français](https://github.com/donnemartin/system-design-primer/issues/250) | [Add Translation](https://github.com/donnemartin/system-design-primer/issues/28)* # システム設計入門 diff --git a/README-vi.md b/README-vi.md new file mode 100644 index 0000000000..94222eebe9 --- /dev/null +++ b/README-vi.md @@ -0,0 +1,1839 @@ +*[English](README.md) ∙ [日本語](README-ja.md) ∙ [简体中文](README-zh-Hans.md) ∙ [繁體中文](README-zh-TW.md) | [العَرَبِيَّة‎](https://github.com/donnemartin/system-design-primer/issues/170) ∙ [বাংলা](https://github.com/donnemartin/system-design-primer/issues/220) ∙ [Português do Brasil](https://github.com/donnemartin/system-design-primer/issues/40) ∙ [Deutsch](https://github.com/donnemartin/system-design-primer/issues/186) ∙ [ελληνικά](https://github.com/donnemartin/system-design-primer/issues/130) ∙ [עברית](https://github.com/donnemartin/system-design-primer/issues/272) ∙ [Italiano](https://github.com/donnemartin/system-design-primer/issues/104) ∙ [한국어](https://github.com/donnemartin/system-design-primer/issues/102) ∙ [فارسی](https://github.com/donnemartin/system-design-primer/issues/110) ∙ [Polski](https://github.com/donnemartin/system-design-primer/issues/68) ∙ [русский язык](https://github.com/donnemartin/system-design-primer/issues/87) ∙ [Español](https://github.com/donnemartin/system-design-primer/issues/136) ∙ [ภาษาไทย](https://github.com/donnemartin/system-design-primer/issues/187) ∙ [Türkçe](https://github.com/donnemartin/system-design-primer/issues/39) ∙ [tiếng Việt](README-vi.md) ∙ [Français](https://github.com/donnemartin/system-design-primer/issues/250) | [Add Translation](https://github.com/donnemartin/system-design-primer/issues/28)* + +**Hãy giúp [dịch](TRANSLATIONS.md) hướng dẫn này!** + +# Cẩm nang Thiết kế Hệ thống + +

+ +
+

+ +## Động lực + +> Học cách thiết kế các hệ thống quy mô lớn. +> +> Chuẩn bị cho phỏng vấn thiết kế hệ thống. + +### Học cách thiết kế các hệ thống quy mô lớn + +Học cách thiết kế các hệ thống có khả năng mở rộng sẽ giúp bạn trở thành một kỹ sư tốt hơn. + +Thiết kế hệ thống là một chủ đề rộng. Có **rất nhiều tài nguyên rải rác trên web** về các nguyên tắc thiết kế hệ thống. + +Repo này là một **bộ sưu tập có tổ chức** các tài nguyên giúp bạn học cách xây dựng hệ thống ở quy mô lớn. + +### Học từ cộng đồng mã nguồn mở + +Đây là một dự án mã nguồn mở được cập nhật liên tục. + +[Đóng góp](#đóng-góp) luôn được hoan nghênh! + +### Chuẩn bị cho phỏng vấn thiết kế hệ thống + +Bên cạnh phỏng vấn lập trình, thiết kế hệ thống là một **thành phần bắt buộc** trong **quy trình phỏng vấn kỹ thuật** tại nhiều công ty công nghệ. + +**Luyện các câu hỏi phỏng vấn thiết kế hệ thống thường gặp** và **so sánh** kết quả của bạn với **lời giải mẫu**: thảo luận, mã nguồn và sơ đồ. + +Các chủ đề bổ sung để ôn phỏng vấn: + +* [Hướng dẫn học](#hướng-dẫn-học) +* [Cách tiếp cận một câu hỏi phỏng vấn thiết kế hệ thống](#cách-tiếp-cận-một-câu-hỏi-phỏng-vấn-thiết-kế-hệ-thống) +* [Câu hỏi phỏng vấn thiết kế hệ thống, **kèm lời giải**](#câu-hỏi-phỏng-vấn-thiết-kế-hệ-thống-kèm-lời-giải) +* [Câu hỏi phỏng vấn thiết kế hướng đối tượng, **kèm lời giải**](#câu-hỏi-phỏng-vấn-thiết-kế-hướng-đối-tượng-kèm-lời-giải) +* [Câu hỏi phỏng vấn thiết kế hệ thống bổ sung](#câu-hỏi-phỏng-vấn-thiết-kế-hệ-thống-bổ-sung) + +## Thẻ ghi nhớ Anki + +

+ +
+

+ +Các bộ [thẻ ghi nhớ Anki](https://apps.ankiweb.net/) đi kèm sử dụng cơ chế lặp cách quãng để giúp bạn ghi nhớ các khái niệm thiết kế hệ thống quan trọng. + +* [Bộ thẻ thiết kế hệ thống](https://github.com/donnemartin/system-design-primer/tree/master/resources/flash_cards/System%20Design.apkg) +* [Bộ thẻ bài tập thiết kế hệ thống](https://github.com/donnemartin/system-design-primer/tree/master/resources/flash_cards/System%20Design%20Exercises.apkg) +* [Bộ thẻ bài tập thiết kế hướng đối tượng](https://github.com/donnemartin/system-design-primer/tree/master/resources/flash_cards/OO%20Design.apkg) + +Rất tiện để ôn luyện khi đang di chuyển. + +### Tài nguyên lập trình: Thử thách lập trình tương tác + +Bạn đang tìm tài nguyên để chuẩn bị cho [**phỏng vấn lập trình**](https://github.com/donnemartin/interactive-coding-challenges)? + +

+ +
+

+ +Hãy xem repo "chị em" [**Interactive Coding Challenges**](https://github.com/donnemartin/interactive-coding-challenges), trong đó có thêm một bộ thẻ Anki: + +* [Bộ thẻ lập trình](https://github.com/donnemartin/interactive-coding-challenges/tree/master/anki_cards/Coding.apkg) + +## Đóng góp + +> Học từ cộng đồng. + +Hãy thoải mái gửi pull request để giúp: + +* Sửa lỗi +* Cải thiện các phần +* Thêm phần mới +* [Dịch](https://github.com/donnemartin/system-design-primer/issues/28) + +Nội dung cần chỉnh sửa thêm được đặt ở phần [đang phát triển](#đang-phát-triển). + +Xem [Hướng dẫn đóng góp](CONTRIBUTING.md). + +## Mục lục các chủ đề thiết kế hệ thống + +> Tóm tắt các chủ đề thiết kế hệ thống, gồm ưu và nhược điểm. **Mọi thứ đều là đánh đổi**. +> +> Mỗi phần có liên kết tới tài nguyên chuyên sâu hơn. + +

+ +
+

+ +* [Các chủ đề thiết kế hệ thống: bắt đầu từ đây](#các-chủ-đề-thiết-kế-hệ-thống-bắt-đầu-từ-đây) + * [Bước 1: Xem bài giảng video về khả năng mở rộng](#bước-1-xem-bài-giảng-video-về-khả-năng-mở-rộng) + * [Bước 2: Đọc bài viết về khả năng mở rộng](#bước-2-đọc-bài-viết-về-khả-năng-mở-rộng) + * [Bước tiếp theo](#bước-tiếp-theo) +* [Hiệu năng vs khả năng mở rộng](#hiệu-năng-vs-khả-năng-mở-rộng) +* [Độ trễ vs thông lượng](#độ-trễ-vs-thông-lượng) +* [Tính sẵn sàng vs tính nhất quán](#tính-sẵn-sàng-vs-tính-nhất-quán) + * [Định lý CAP](#định-lý-cap) + * [CP - tính nhất quán và chịu phân mảnh](#cp---tính-nhất-quán-và-chịu-phân-mảnh) + * [AP - tính sẵn sàng và chịu phân mảnh](#ap---tính-sẵn-sàng-và-chịu-phân-mảnh) +* [Mẫu hình nhất quán](#mẫu-hình-nhất-quán) + * [Nhất quán yếu](#nhất-quán-yếu) + * [Nhất quán cuối cùng](#nhất-quán-cuối-cùng) + * [Nhất quán mạnh](#nhất-quán-mạnh) +* [Mẫu hình sẵn sàng](#mẫu-hình-sẵn-sàng) + * [Chuyển đổi dự phòng](#chuyển-đổi-dự-phòng) + * [Sao chép](#sao-chép) + * [Tính sẵn sàng theo con số](#tính-sẵn-sàng-theo-con-số) +* [Hệ thống tên miền](#hệ-thống-tên-miền) +* [Mạng phân phối nội dung](#mạng-phân-phối-nội-dung) + * [CDN đẩy (push)](#cdn-đẩy-push) + * [CDN kéo (pull)](#cdn-kéo-pull) +* [Bộ cân bằng tải](#bộ-cân-bằng-tải) + * [Chủ động-bị động](#chủ-động-bị-động) + * [Chủ động-chủ động](#chủ-động-chủ-động) + * [Cân bằng tải tầng 4](#cân-bằng-tải-tầng-4) + * [Cân bằng tải tầng 7](#cân-bằng-tải-tầng-7) + * [Mở rộng ngang](#mở-rộng-ngang) +* [Reverse proxy (máy chủ web)](#reverse-proxy-máy-chủ-web) + * [Bộ cân bằng tải vs reverse proxy](#bộ-cân-bằng-tải-vs-reverse-proxy) +* [Tầng ứng dụng](#tầng-ứng-dụng) + * [Vi dịch vụ](#vi-dịch-vụ) + * [Khám phá dịch vụ](#khám-phá-dịch-vụ) +* [Cơ sở dữ liệu](#cơ-sở-dữ-liệu) + * [Hệ quản trị CSDL quan hệ (RDBMS)](#hệ-quản-trị-csdl-quan-hệ-rdbms) + * [Sao chép master-slave](#sao-chép-master-slave) + * [Sao chép master-master](#sao-chép-master-master) + * [Liên kết (federation)](#liên-kết-federation) + * [Phân mảnh (sharding)](#phân-mảnh-sharding) + * [Phi chuẩn hóa](#phi-chuẩn-hóa) + * [Tối ưu SQL](#tối-ưu-sql) + * [NoSQL](#nosql) + * [Kho khóa-giá trị](#kho-khóa-giá-trị) + * [Kho tài liệu](#kho-tài-liệu) + * [Kho cột rộng](#kho-cột-rộng) + * [CSDL đồ thị](#csdl-đồ-thị) + * [SQL hay NoSQL](#sql-hay-nosql) +* [Bộ nhớ đệm](#bộ-nhớ-đệm) + * [Đệm phía client](#đệm-phía-client) + * [Đệm CDN](#đệm-cdn) + * [Đệm máy chủ web](#đệm-máy-chủ-web) + * [Đệm cơ sở dữ liệu](#đệm-cơ-sở-dữ-liệu) + * [Đệm tầng ứng dụng](#đệm-tầng-ứng-dụng) + * [Đệm ở mức truy vấn CSDL](#đệm-ở-mức-truy-vấn-csdl) + * [Đệm ở mức đối tượng](#đệm-ở-mức-đối-tượng) + * [Khi nào cập nhật cache](#khi-nào-cập-nhật-cache) + * [Cache-aside](#cache-aside) + * [Write-through](#write-through) + * [Write-behind (write-back)](#write-behind-write-back) + * [Refresh-ahead](#refresh-ahead) +* [Bất đồng bộ](#bất-đồng-bộ) + * [Hàng đợi thông điệp](#hàng-đợi-thông-điệp) + * [Hàng đợi tác vụ](#hàng-đợi-tác-vụ) + * [Back pressure](#back-pressure) +* [Giao tiếp](#giao-tiếp) + * [Giao thức điều khiển truyền tải (TCP)](#giao-thức-điều-khiển-truyền-tải-tcp) + * [Giao thức datagram người dùng (UDP)](#giao-thức-datagram-người-dùng-udp) + * [Gọi thủ tục từ xa (RPC)](#gọi-thủ-tục-từ-xa-rpc) + * [Chuyển trạng thái biểu diễn (REST)](#chuyển-trạng-thái-biểu-diễn-rest) +* [Bảo mật](#bảo-mật) +* [Phụ lục](#phụ-lục) + * [Bảng lũy thừa của 2](#bảng-lũy-thừa-của-2) + * [Các con số độ trễ mà lập trình viên nên biết](#các-con-số-độ-trễ-mà-lập-trình-viên-nên-biết) + * [Câu hỏi phỏng vấn thiết kế hệ thống bổ sung](#câu-hỏi-phỏng-vấn-thiết-kế-hệ-thống-bổ-sung) + * [Kiến trúc thực tế](#kiến-trúc-thực-tế) + * [Kiến trúc công ty](#kiến-trúc-công-ty) + * [Blog kỹ thuật của công ty](#blog-kỹ-thuật-của-công-ty) +* [Đang phát triển](#đang-phát-triển) +* [Ghi công](#ghi-công) +* [Thông tin liên hệ](#thông-tin-liên-hệ) +* [Giấy phép](#giấy-phép) + +## Hướng dẫn học + +> Gợi ý các chủ đề nên xem theo mốc thời gian phỏng vấn (ngắn, trung bình, dài). + +![Imgur](images/OfVllex.png) + +**H: Khi phỏng vấn, tôi có cần biết hết mọi thứ ở đây không?** + +**Đ: Không, bạn không cần biết hết mọi thứ ở đây để chuẩn bị cho phỏng vấn**. + +Những gì bạn được hỏi trong phỏng vấn phụ thuộc vào các yếu tố như: + +* Bạn có bao nhiêu kinh nghiệm +* Nền tảng kỹ thuật của bạn là gì +* Bạn đang ứng tuyển vào vị trí nào +* Bạn đang phỏng vấn với công ty nào +* May mắn + +Những ứng viên nhiều kinh nghiệm thường được kỳ vọng biết nhiều hơn về thiết kế hệ thống. Kiến trúc sư hoặc trưởng nhóm có thể được kỳ vọng biết nhiều hơn so với các cá nhân đóng góp (individual contributors). Các công ty công nghệ hàng đầu có thể có một hoặc nhiều vòng phỏng vấn thiết kế. + +Hãy bắt đầu rộng rồi đi sâu vào một vài mảng. Sẽ hữu ích nếu bạn biết một chút về các chủ đề thiết kế hệ thống quan trọng. Hãy điều chỉnh hướng dẫn dưới đây theo mốc thời gian, kinh nghiệm, vị trí bạn ứng tuyển và công ty bạn phỏng vấn. + +* **Thời gian ngắn** - Ưu tiên **độ rộng** các chủ đề. Luyện giải **một vài** câu hỏi phỏng vấn. +* **Thời gian trung bình** - Ưu tiên **độ rộng** và **một phần độ sâu**. Luyện giải **nhiều** câu hỏi phỏng vấn. +* **Thời gian dài** - Ưu tiên **độ rộng** và **độ sâu hơn**. Luyện giải **hầu hết** câu hỏi phỏng vấn. + +| | Ngắn | Trung bình | Dài | +|---|---|---|---| +| Đọc qua [Các chủ đề thiết kế hệ thống](#mục-lục-các-chủ-đề-thiết-kế-hệ-thống) để hiểu tổng quan cách hệ thống vận hành | :+1: | :+1: | :+1: | +| Đọc một vài bài trong [Blog kỹ thuật của công ty](#blog-kỹ-thuật-của-công-ty) mà bạn đang phỏng vấn | :+1: | :+1: | :+1: | +| Đọc một vài [Kiến trúc thực tế](#kiến-trúc-thực-tế) | :+1: | :+1: | :+1: | +| Xem [Cách tiếp cận một câu hỏi phỏng vấn thiết kế hệ thống](#cách-tiếp-cận-một-câu-hỏi-phỏng-vấn-thiết-kế-hệ-thống) | :+1: | :+1: | :+1: | +| Luyện [Câu hỏi phỏng vấn thiết kế hệ thống kèm lời giải](#câu-hỏi-phỏng-vấn-thiết-kế-hệ-thống-kèm-lời-giải) | Một vài | Nhiều | Hầu hết | +| Luyện [Câu hỏi phỏng vấn thiết kế hướng đối tượng kèm lời giải](#câu-hỏi-phỏng-vấn-thiết-kế-hướng-đối-tượng-kèm-lời-giải) | Một vài | Nhiều | Hầu hết | +| Xem [Câu hỏi phỏng vấn thiết kế hệ thống bổ sung](#câu-hỏi-phỏng-vấn-thiết-kế-hệ-thống-bổ-sung) | Một vài | Nhiều | Hầu hết | + +## Cách tiếp cận một câu hỏi phỏng vấn thiết kế hệ thống + +> Cách xử lý một câu hỏi phỏng vấn thiết kế hệ thống. + +Phỏng vấn thiết kế hệ thống là một **cuộc trò chuyện mở**. Bạn được kỳ vọng sẽ dẫn dắt cuộc trò chuyện đó. + +Bạn có thể dùng các bước sau để dẫn dắt thảo luận. Để củng cố quy trình này, hãy luyện phần [Câu hỏi phỏng vấn thiết kế hệ thống kèm lời giải](#câu-hỏi-phỏng-vấn-thiết-kế-hệ-thống-kèm-lời-giải) theo các bước bên dưới. + +### Bước 1: Phác thảo trường hợp sử dụng (use case), ràng buộc, và giả định + +Thu thập yêu cầu và khoanh phạm vi bài toán. Đặt câu hỏi để làm rõ trường hợp sử dụng và ràng buộc. Thảo luận các giả định. + +* Ai sẽ dùng? +* Họ sẽ dùng như thế nào? +* Có bao nhiêu người dùng? +* Hệ thống làm gì? +* Đầu vào và đầu ra của hệ thống là gì? +* Ta dự kiến xử lý bao nhiêu dữ liệu? +* Ta dự kiến bao nhiêu yêu cầu mỗi giây? +* Tỷ lệ đọc/ghi kỳ vọng là bao nhiêu? + +### Bước 2: Tạo thiết kế mức cao + +Phác thảo thiết kế mức cao với mọi thành phần quan trọng. + +* Phác thảo các thành phần chính và kết nối +* Giải thích và bảo vệ ý tưởng + +### Bước 3: Thiết kế các thành phần lõi + +Đi sâu vào chi tiết cho từng thành phần lõi. Ví dụ, nếu bạn được yêu cầu [thiết kế dịch vụ rút gọn URL](solutions/system_design/pastebin/README.md), hãy thảo luận: + +* Tạo và lưu hash của URL đầy đủ + * [MD5](solutions/system_design/pastebin/README.md) và [Base62](solutions/system_design/pastebin/README.md) + * Va chạm hash + * SQL hay NoSQL + * Lược đồ cơ sở dữ liệu +* Ánh xạ URL đã hash về URL đầy đủ + * Truy vấn cơ sở dữ liệu +* Thiết kế API và hướng đối tượng + +### Bước 4: Mở rộng thiết kế + +Xác định và xử lý nút thắt, dựa trên các ràng buộc. Ví dụ, bạn có cần các thứ sau để giải quyết vấn đề mở rộng không? + +* Bộ cân bằng tải +* Mở rộng ngang +* Cache +* Phân mảnh cơ sở dữ liệu + +Thảo luận các giải pháp và đánh đổi. Mọi thứ đều là đánh đổi. Giải quyết nút thắt theo [các nguyên tắc thiết kế hệ thống mở rộng](#mục-lục-các-chủ-đề-thiết-kế-hệ-thống). + +### Tính toán nhanh trên giấy + +Bạn có thể được hỏi ước lượng nhanh bằng tay. Hãy tham khảo [Phụ lục](#phụ-lục) cho các tài nguyên sau: + +* [Dùng ước lượng nhanh trên giấy](http://highscalability.com/blog/2011/1/26/google-pro-tip-use-back-of-the-envelope-calculations-to-choo.html) +* [Bảng lũy thừa của 2](#bảng-lũy-thừa-của-2) +* [Các con số độ trễ mà lập trình viên nên biết](#các-con-số-độ-trễ-mà-lập-trình-viên-nên-biết) + +### Nguồn và đọc thêm + +Xem các liên kết sau để hiểu rõ hơn bạn sẽ gặp gì: + +* [Cách "điểm cao" trong phỏng vấn thiết kế hệ thống](https://web.archive.org/web/20210505130322/https://www.palantir.com/2011/10/how-to-rock-a-systems-design-interview/) +* [Phỏng vấn thiết kế hệ thống](http://www.hiredintech.com/system-design) +* [Giới thiệu về phỏng vấn kiến trúc và thiết kế hệ thống](https://www.youtube.com/watch?v=ZgdS0EUmn70) +* [Mẫu thiết kế hệ thống](https://leetcode.com/discuss/career/229177/My-System-Design-Template) + +## Câu hỏi phỏng vấn thiết kế hệ thống kèm lời giải + +> Các câu hỏi phỏng vấn thiết kế hệ thống thường gặp kèm thảo luận mẫu, mã nguồn và sơ đồ. +> +> Lời giải được liên kết tới nội dung trong thư mục `solutions/`. + +| Câu hỏi | | +|---|---| +| Thiết kế Pastebin.com (hoặc Bit.ly) | [Lời giải](solutions/system_design/pastebin/README.md) | +| Thiết kế timeline và tìm kiếm của Twitter (hoặc feed và tìm kiếm của Facebook) | [Lời giải](solutions/system_design/twitter/README.md) | +| Thiết kế web crawler | [Lời giải](solutions/system_design/web_crawler/README.md) | +| Thiết kế Mint.com | [Lời giải](solutions/system_design/mint/README.md) | +| Thiết kế cấu trúc dữ liệu cho mạng xã hội | [Lời giải](solutions/system_design/social_graph/README.md) | +| Thiết kế kho khóa-giá trị cho công cụ tìm kiếm | [Lời giải](solutions/system_design/query_cache/README.md) | +| Thiết kế tính năng xếp hạng bán hàng theo danh mục của Amazon | [Lời giải](solutions/system_design/sales_rank/README.md) | +| Thiết kế hệ thống mở rộng tới hàng triệu người dùng trên AWS | [Lời giải](solutions/system_design/scaling_aws/README.md) | +| Thêm câu hỏi thiết kế hệ thống | [Đóng góp](#đóng-góp) | + +### Thiết kế Pastebin.com (hoặc Bit.ly) + +[Xem bài tập và lời giải](solutions/system_design/pastebin/README.md) + +![Imgur](images/4edXG0T.png) + +### Thiết kế timeline và tìm kiếm của Twitter (hoặc feed và tìm kiếm của Facebook) + +[Xem bài tập và lời giải](solutions/system_design/twitter/README.md) + +![Imgur](images/jrUBAF7.png) + +### Thiết kế web crawler + +[Xem bài tập và lời giải](solutions/system_design/web_crawler/README.md) + +![Imgur](images/bWxPtQA.png) + +### Thiết kế Mint.com + +[Xem bài tập và lời giải](solutions/system_design/mint/README.md) + +![Imgur](images/V5q57vU.png) + +### Thiết kế cấu trúc dữ liệu cho mạng xã hội + +[Xem bài tập và lời giải](solutions/system_design/social_graph/README.md) + +![Imgur](images/cdCv5g7.png) + +### Thiết kế kho khóa-giá trị cho công cụ tìm kiếm + +[Xem bài tập và lời giải](solutions/system_design/query_cache/README.md) + +![Imgur](images/4j99mhe.png) + +### Thiết kế tính năng xếp hạng bán hàng theo danh mục của Amazon + +[Xem bài tập và lời giải](solutions/system_design/sales_rank/README.md) + +![Imgur](images/MzExP06.png) + +### Thiết kế hệ thống mở rộng tới hàng triệu người dùng trên AWS + +[Xem bài tập và lời giải](solutions/system_design/scaling_aws/README.md) + +![Imgur](images/jj3A5N8.png) + +## Câu hỏi phỏng vấn thiết kế hướng đối tượng kèm lời giải + +> Các câu hỏi phỏng vấn thiết kế hướng đối tượng thường gặp kèm thảo luận mẫu, mã nguồn và sơ đồ. +> +> Lời giải được liên kết tới nội dung trong thư mục `solutions/`. + +>**Lưu ý: Phần này đang phát triển** + +| Câu hỏi | | +|---|---| +| Thiết kế hash map | [Lời giải](solutions/object_oriented_design/hash_table/hash_map.ipynb) | +| Thiết kế cache ít được dùng gần đây nhất (LRU) | [Lời giải](solutions/object_oriented_design/lru_cache/lru_cache.ipynb) | +| Thiết kế tổng đài | [Lời giải](solutions/object_oriented_design/call_center/call_center.ipynb) | +| Thiết kế bộ bài | [Lời giải](solutions/object_oriented_design/deck_of_cards/deck_of_cards.ipynb) | +| Thiết kế bãi đỗ xe | [Lời giải](solutions/object_oriented_design/parking_lot/parking_lot.ipynb) | +| Thiết kế máy chủ chat | [Lời giải](solutions/object_oriented_design/online_chat/online_chat.ipynb) | +| Thiết kế mảng vòng | [Đóng góp](#đóng-góp) | +| Thêm câu hỏi thiết kế hướng đối tượng | [Đóng góp](#đóng-góp) | + +## Các chủ đề thiết kế hệ thống: bắt đầu từ đây + +Mới làm quen với thiết kế hệ thống? + +Trước tiên, bạn cần hiểu các nguyên tắc cơ bản: chúng là gì, được dùng ra sao, ưu và nhược điểm. + +### Bước 1: Xem bài giảng video về khả năng mở rộng + +[Bài giảng về khả năng mở rộng tại Harvard](https://www.youtube.com/watch?v=-W9F__D3oY4) + +* Các chủ đề được đề cập: + * Mở rộng dọc + * Mở rộng ngang + * Cache + * Cân bằng tải + * Sao chép cơ sở dữ liệu + * Phân vùng cơ sở dữ liệu + +### Bước 2: Đọc bài viết về khả năng mở rộng + +[Scalability](https://web.archive.org/web/20221030091841/http://www.lecloud.net/tagged/scalability/chrono) + +* Các chủ đề được đề cập: + * [Clones](https://web.archive.org/web/20220530193911/https://www.lecloud.net/post/7295452622/scalability-for-dummies-part-1-clones) + * [Databases](https://web.archive.org/web/20220602114024/https://www.lecloud.net/post/7994751381/scalability-for-dummies-part-2-database) + * [Caches](https://web.archive.org/web/20230126233752/https://www.lecloud.net/post/9246290032/scalability-for-dummies-part-3-cache) + * [Bất đồng bộ](https://web.archive.org/web/20220926171507/https://www.lecloud.net/post/9699762917/scalability-for-dummies-part-4-asynchronism) + +### Bước tiếp theo + +Tiếp theo, chúng ta sẽ xem các đánh đổi ở mức cao: + +* **Hiệu năng** vs **khả năng mở rộng** +* **Độ trễ** vs **thông lượng** +* **Tính sẵn sàng** vs **tính nhất quán** + +Hãy nhớ rằng **mọi thứ đều là đánh đổi**. + +Sau đó chúng ta sẽ đi sâu vào các chủ đề cụ thể như DNS, CDN và cân bằng tải. + +## Hiệu năng vs khả năng mở rộng + +Một dịch vụ được gọi là **có khả năng mở rộng** nếu khi thêm tài nguyên thì **hiệu năng** tăng tương xứng. Nói chung, tăng hiệu năng nghĩa là phục vụ nhiều đơn vị công việc hơn, nhưng cũng có thể là xử lý các đơn vị công việc lớn hơn, chẳng hạn khi dữ liệu tăng lên.1 + +Một cách khác để nhìn về hiệu năng và khả năng mở rộng: + +* Nếu bạn có vấn đề về **hiệu năng**, hệ thống của bạn chậm với một người dùng đơn. +* Nếu bạn có vấn đề về **khả năng mở rộng**, hệ thống của bạn nhanh với một người dùng đơn nhưng chậm khi tải lớn. + +### Nguồn và đọc thêm + +* [Một vài lời về khả năng mở rộng](http://www.allthingsdistributed.com/2006/03/a_word_on_scalability.html) +* [Khả năng mở rộng, tính sẵn sàng, ổn định, các mẫu hình](http://www.slideshare.net/jboner/scalability-availability-stability-patterns/) + +## Độ trễ vs thông lượng + +**Độ trễ** là thời gian để thực hiện một hành động hoặc tạo ra một kết quả. + +**Thông lượng** là số lượng các hành động hoặc kết quả như vậy trên một đơn vị thời gian. + +Nói chung, bạn nên nhắm đến **thông lượng tối đa** với **độ trễ chấp nhận được**. + +### Nguồn và đọc thêm + +* [Hiểu về độ trễ vs thông lượng](https://community.cadence.com/cadence_blogs_8/b/fv/posts/understanding-latency-vs-throughput) + +## Tính sẵn sàng vs tính nhất quán + +### Định lý CAP + +

+ +
+ Nguồn: Xem lại định lý CAP +

+ +Trong một hệ thống phân tán, bạn chỉ có thể đảm bảo hai trong ba thuộc tính sau: + +* **Tính nhất quán** - Mỗi lần đọc nhận được bản ghi mới nhất hoặc lỗi +* **Tính sẵn sàng** - Mỗi yêu cầu đều nhận được phản hồi, nhưng không đảm bảo đó là bản mới nhất +* **Khả năng chịu phân mảnh** - Hệ thống vẫn hoạt động dù mạng bị chia cắt do lỗi + +*Mạng không đáng tin cậy, nên bạn cần chịu phân mảnh. Bạn phải đánh đổi phần mềm giữa nhất quán và sẵn sàng.* + +#### CP - tính nhất quán và chịu phân mảnh + +Chờ phản hồi từ nút bị phân mảnh có thể gây timeout. CP phù hợp nếu nghiệp vụ yêu cầu đọc/ghi nguyên tử. + +#### AP - tính sẵn sàng và chịu phân mảnh + +Phản hồi trả về phiên bản dữ liệu sẵn có nhất trên bất kỳ nút nào, có thể không phải bản mới nhất. Ghi có thể mất thời gian lan truyền khi phân mảnh được khôi phục. + +AP phù hợp nếu nghiệp vụ cho phép [nhất quán cuối cùng](#nhất-quán-cuối-cùng) hoặc khi hệ thống phải tiếp tục hoạt động dù có lỗi bên ngoài. + +### Nguồn và đọc thêm + +* [Xem lại định lý CAP](https://robertgreiner.com/cap-theorem-revisited/) +* [Giới thiệu định lý CAP bằng tiếng Anh đơn giản](http://ksat.me/a-plain-english-introduction-to-cap-theorem) +* [CAP FAQ](https://github.com/henryr/cap-faq) +* [Định lý CAP](https://www.youtube.com/watch?v=k-Yaq8AHlFA) + +## Mẫu hình nhất quán + +Khi có nhiều bản sao dữ liệu, ta phải chọn cách đồng bộ để client có góc nhìn nhất quán. Nhắc lại định nghĩa nhất quán từ [định lý CAP](#định-lý-cap) - mỗi lần đọc nhận được bản ghi mới nhất hoặc lỗi. + +### Nhất quán yếu + +Sau khi ghi, việc đọc có thể thấy hoặc không thấy dữ liệu. Tiếp cận theo kiểu best effort. + +Cách tiếp cận này thấy trong các hệ thống như memcached. Nhất quán yếu phù hợp cho các trường hợp thời gian thực như VoIP, video chat, và game nhiều người chơi thời gian thực. Ví dụ, nếu bạn đang gọi điện và mất sóng vài giây, khi có kết nối lại bạn sẽ không nghe phần đã nói trong lúc mất kết nối. + +### Nhất quán cuối cùng + +Sau khi ghi, đọc sẽ thấy dữ liệu **sau một thời gian** (thường là mili giây). Dữ liệu được sao chép bất đồng bộ. + +Cách tiếp cận này thấy trong các hệ thống như DNS và email. Nhất quán cuối cùng phù hợp cho các hệ thống có tính sẵn sàng cao. + +### Nhất quán mạnh + +Sau khi ghi, đọc sẽ thấy dữ liệu. Dữ liệu được sao chép đồng bộ. + +Cách tiếp cận này thấy trong hệ thống tệp và RDBMS. Nhất quán mạnh phù hợp cho các hệ thống cần giao dịch. + +### Nguồn và đọc thêm + +* [Giao dịch giữa các trung tâm dữ liệu](http://snarfed.org/transactions_across_datacenters_io.html) + +## Mẫu hình sẵn sàng + +Có hai mẫu hình bổ sung nhau để hỗ trợ tính sẵn sàng cao: **chuyển đổi dự phòng** và **sao chép**. + +### Chuyển đổi dự phòng + +#### Chủ động-bị động + +Với chuyển đổi dự phòng chủ động-bị động, heartbeat được gửi giữa máy chủ chủ động và máy chủ bị động dự phòng. Nếu heartbeat bị gián đoạn, máy chủ bị động sẽ nhận IP của máy chủ chủ động và tiếp tục phục vụ. + +Thời gian gián đoạn phụ thuộc vào việc máy chủ bị động đã chạy ở chế độ "nóng" hay cần khởi động từ "lạnh". Chỉ máy chủ chủ động xử lý lưu lượng. + +Chủ động-bị động cũng được gọi là chuyển đổi dự phòng master-slave. + +#### Chủ động-chủ động + +Ở chế độ chủ động-chủ động, cả hai máy chủ cùng xử lý lưu lượng, chia tải giữa chúng. + +Nếu là máy chủ public-facing, DNS cần biết IP public của cả hai máy. Nếu là internal-facing, logic ứng dụng cần biết cả hai máy. + +Chủ động-chủ động cũng được gọi là chuyển đổi dự phòng master-master. + +### Nhược điểm: chuyển đổi dự phòng + +* Chuyển đổi dự phòng cần thêm phần cứng và tăng độ phức tạp. +* Có thể mất dữ liệu nếu hệ thống chủ động hỏng trước khi dữ liệu mới được sao chép sang hệ thống bị động. + +### Sao chép + +#### Master-slave và master-master + +Chủ đề này được bàn kỹ hơn trong phần [Cơ sở dữ liệu](#cơ-sở-dữ-liệu): + +* [Sao chép master-slave](#sao-chép-master-slave) +* [Sao chép master-master](#sao-chép-master-master) + +### Tính sẵn sàng theo con số + +Tính sẵn sàng thường được đo bằng uptime (hoặc downtime) theo phần trăm thời gian dịch vụ sẵn sàng. Tính sẵn sàng thường được đo bằng số lượng số 9 — một dịch vụ có 99,99% tính sẵn sàng được nói là có bốn số 9. + +#### 99.9% tính sẵn sàng - ba số 9 + +| Thời lượng | Downtime chấp nhận được| +|---------------------|------------------------| +| Downtime mỗi năm | 8h 45m 57s | +| Downtime mỗi tháng | 43m 49.7s | +| Downtime mỗi tuần | 10m 4.8s | +| Downtime mỗi ngày | 1m 26.4s | + +#### 99.99% tính sẵn sàng - bốn số 9 + +| Thời lượng | Downtime chấp nhận được| +|---------------------|------------------------| +| Downtime mỗi năm | 52m 35.7s | +| Downtime mỗi tháng | 4m 23s | +| Downtime mỗi tuần | 1m 5s | +| Downtime mỗi ngày | 8.6s | + +#### Tính sẵn sàng song song vs nối tiếp + +Nếu một dịch vụ gồm nhiều thành phần có thể lỗi, tính sẵn sàng tổng thể phụ thuộc vào việc các thành phần mắc nối tiếp hay song song. + +###### Nối tiếp + +Tính sẵn sàng tổng thể giảm khi hai thành phần có tính sẵn sàng < 100% mắc nối tiếp: + +``` +Availability (Total) = Availability (Foo) * Availability (Bar) +``` + +Nếu cả `Foo` và `Bar` đều có 99.9% tính sẵn sàng, tính sẵn sàng tổng nối tiếp là 99.8%. + +###### Song song + +Tính sẵn sàng tổng thể tăng khi hai thành phần có tính sẵn sàng < 100% mắc song song: + +``` +Availability (Total) = 1 - (1 - Availability (Foo)) * (1 - Availability (Bar)) +``` + +Nếu cả `Foo` và `Bar` đều có 99.9% tính sẵn sàng, tính sẵn sàng tổng song song là 99.9999%. + +## Hệ thống tên miền + +

+ +
+ Nguồn: DNS security presentation +

+ +Hệ thống tên miền (DNS) chuyển một tên miền như www.example.com thành một địa chỉ IP. + +DNS có cấu trúc phân cấp, với một vài máy chủ có thẩm quyền ở tầng cao nhất. Router hoặc ISP của bạn cung cấp thông tin về máy chủ DNS cần liên hệ khi tra cứu. Các máy chủ DNS tầng thấp sẽ cache ánh xạ, có thể bị cũ do độ trễ lan truyền DNS. Kết quả DNS cũng có thể được cache bởi trình duyệt hoặc hệ điều hành trong một khoảng thời gian, được xác định bởi [time to live (TTL)](https://en.wikipedia.org/wiki/Time_to_live). + +* **Bản ghi NS (name server)** - Chỉ định máy chủ DNS cho domain/subdomain. +* **Bản ghi MX (mail exchange)** - Chỉ định máy chủ mail để nhận thư. +* **Bản ghi A (address)** - Trỏ một tên đến một địa chỉ IP. +* **CNAME (canonical)** - Trỏ một tên tới một tên khác hoặc `CNAME` (example.com tới www.example.com) hoặc tới một bản ghi `A`. + +Các dịch vụ như [CloudFlare](https://www.cloudflare.com/dns/) và [Route 53](https://aws.amazon.com/route53/) cung cấp DNS quản lý. Một số dịch vụ DNS có thể định tuyến lưu lượng theo nhiều phương thức: + +* [Weighted round robin](https://www.jscape.com/blog/load-balancing-algorithms) + * Ngăn lưu lượng đến máy chủ đang bảo trì + * Cân bằng giữa các cụm có kích thước khác nhau + * A/B testing +* [Dựa trên độ trễ](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-policy-latency.html) +* [Dựa trên vị trí địa lý](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-policy-geo.html) + +### Nhược điểm: DNS + +* Truy cập máy chủ DNS gây thêm độ trễ nhỏ, dù được giảm nhờ cache như mô tả ở trên. +* Quản lý máy chủ DNS có thể phức tạp và thường do [chính phủ, ISP, và công ty lớn](http://superuser.com/questions/472695/who-controls-the-dns-servers/472729) quản lý. +* Dịch vụ DNS gần đây bị [tấn công DDoS](http://dyn.com/blog/dyn-analysis-summary-of-friday-october-21-attack/), khiến người dùng không thể truy cập các website như Twitter nếu không biết IP của Twitter. + +### Nguồn và đọc thêm + +* [Kiến trúc DNS](https://technet.microsoft.com/en-us/library/dd197427(v=ws.10).aspx) +* [Wikipedia](https://en.wikipedia.org/wiki/Domain_Name_System) +* [Các bài viết về DNS](https://support.dnsimple.com/categories/dns/) + +## Mạng phân phối nội dung + +

+ +
+ Nguồn: Why use a CDN +

+ +Mạng phân phối nội dung (CDN) là một mạng máy chủ proxy phân tán toàn cầu, phục vụ nội dung từ vị trí gần người dùng. Thông thường, các tệp tĩnh như HTML/CSS/JS, ảnh, và video được phục vụ từ CDN, dù một số CDN như CloudFront của Amazon hỗ trợ nội dung động. DNS của website sẽ nói cho client biết máy chủ nào cần liên hệ. + +Phục vụ nội dung từ CDN có thể cải thiện hiệu năng đáng kể theo hai cách: + +* Người dùng nhận nội dung từ trung tâm dữ liệu gần họ +* Máy chủ của bạn không phải xử lý các yêu cầu mà CDN đã phục vụ + +### CDN đẩy (push) + +CDN đẩy nhận nội dung mới mỗi khi có thay đổi trên máy chủ của bạn. Bạn chịu trách nhiệm cung cấp nội dung, tải trực tiếp lên CDN và viết lại URL để trỏ tới CDN. Bạn có thể cấu hình khi nào nội dung hết hạn và khi nào cập nhật. Nội dung chỉ được tải lên khi mới hoặc thay đổi, giảm traffic nhưng tăng lưu trữ. + +Các website có ít traffic hoặc nội dung ít cập nhật phù hợp với CDN đẩy. Nội dung được đặt trên CDN một lần, thay vì bị kéo lại định kỳ. + +### CDN kéo (pull) + +CDN kéo lấy nội dung mới từ máy chủ của bạn khi người dùng đầu tiên yêu cầu. Bạn giữ nội dung trên máy chủ và viết lại URL để trỏ tới CDN. Điều này khiến yêu cầu đầu tiên chậm hơn cho đến khi nội dung được cache trên CDN. + +[Time-to-live (TTL)](https://en.wikipedia.org/wiki/Time_to_live) quyết định nội dung được cache bao lâu. CDN kéo tối thiểu hóa dung lượng lưu trữ trên CDN, nhưng có thể tạo traffic dư nếu tệp hết hạn và bị kéo lại trước khi thực sự thay đổi. + +Website có traffic lớn phù hợp với CDN kéo, vì lưu lượng được phân tán đều hơn khi chỉ những nội dung mới được truy cập còn nằm trên CDN. + +### Nhược điểm: CDN + +* Chi phí CDN có thể lớn tùy theo traffic, dù cần so sánh với chi phí phát sinh nếu không dùng CDN. +* Nội dung có thể bị cũ nếu cập nhật trước khi TTL hết hạn. +* CDN yêu cầu thay đổi URL của nội dung tĩnh để trỏ tới CDN. + +### Nguồn và đọc thêm + +* [Phân phối nội dung toàn cầu](https://figshare.com/articles/Globally_distributed_content_delivery/6605972) +* [Khác biệt giữa CDN push và pull](https://www.geeksforgeeks.org/system-design/pull-cdn-vs-push-cdn/) +* [Wikipedia](https://en.wikipedia.org/wiki/Content_delivery_network) + +## Bộ cân bằng tải + +

+ +
+ Nguồn: Scalable system design patterns +

+ +Bộ cân bằng tải phân phối các yêu cầu từ client tới tài nguyên tính toán như máy chủ ứng dụng và cơ sở dữ liệu. Trong mọi trường hợp, bộ cân bằng tải trả phản hồi từ tài nguyên tính toán về cho client phù hợp. Bộ cân bằng tải hiệu quả trong việc: + +* Ngăn yêu cầu tới máy chủ không khỏe +* Ngăn quá tải tài nguyên +* Giúp loại bỏ một điểm lỗi đơn + +Bộ cân bằng tải có thể triển khai bằng phần cứng (đắt) hoặc bằng phần mềm như HAProxy. + +Lợi ích bổ sung gồm: + +* **SSL termination** - Giải mã yêu cầu vào và mã hóa phản hồi ra để các máy chủ backend không phải làm các thao tác tốn tài nguyên này + * Không cần cài [chứng chỉ X.509](https://en.wikipedia.org/wiki/X.509) trên từng máy chủ +* **Session persistence** - Phát cookie và định tuyến yêu cầu của một client tới cùng một instance nếu web app không tự quản lý session + +Để bảo vệ trước lỗi, thường thiết lập nhiều bộ cân bằng tải, ở chế độ [chủ động-bị động](#chủ-động-bị-động) hoặc [chủ động-chủ động](#chủ-động-chủ-động). + +Bộ cân bằng tải có thể định tuyến dựa trên nhiều chỉ số, gồm: + +* Ngẫu nhiên +* Ít tải nhất +* Session/cookie +* [Round robin hoặc weighted round robin](https://www.g33kinfo.com/info/round-robin-vs-weighted-round-robin-lb) +* [Tầng 4](#cân-bằng-tải-tầng-4) +* [Tầng 7](#cân-bằng-tải-tầng-7) + +### Cân bằng tải tầng 4 + +Bộ cân bằng tải tầng 4 nhìn vào thông tin ở [tầng vận chuyển](#giao-tiếp) để quyết định phân phối yêu cầu. Thường gồm IP nguồn, IP đích, và cổng trong header, nhưng không xem nội dung gói. Bộ cân bằng tải tầng 4 chuyển tiếp gói mạng tới và từ máy chủ upstream, thực hiện [NAT](https://web.archive.org/web/20240117134735/https://www.nginx.com/resources/glossary/layer-4-load-balancing/). + +### Cân bằng tải tầng 7 + +Bộ cân bằng tải tầng 7 nhìn vào [tầng ứng dụng](#giao-tiếp) để quyết định phân phối yêu cầu. Việc này có thể bao gồm nội dung header, message, và cookie. Bộ cân bằng tải tầng 7 kết thúc lưu lượng mạng, đọc message, quyết định cân bằng tải, rồi mở kết nối tới máy chủ được chọn. Ví dụ, một bộ cân bằng tải tầng 7 có thể điều hướng lưu lượng video tới máy chủ lưu video trong khi điều hướng lưu lượng thanh toán nhạy cảm tới máy chủ được tăng cường bảo mật. + +Đổi lại sự linh hoạt, cân bằng tải tầng 4 cần ít thời gian và tài nguyên tính toán hơn tầng 7, dù tác động hiệu năng có thể nhỏ trên phần cứng phổ thông hiện nay. + +### Mở rộng ngang + +Bộ cân bằng tải cũng hỗ trợ mở rộng ngang, cải thiện hiệu năng và tính sẵn sàng. Mở rộng ra nhiều máy phổ thông tiết kiệm chi phí hơn và có tính sẵn sàng cao hơn so với mở rộng lên một máy chủ đơn trên phần cứng đắt tiền, gọi là **mở rộng dọc**. Ngoài ra, việc tuyển dụng kỹ năng làm việc trên phần cứng phổ thông thường dễ hơn so với hệ thống doanh nghiệp chuyên biệt. + +#### Nhược điểm: mở rộng ngang + +* Mở rộng ngang tăng độ phức tạp và cần nhân bản máy chủ + * Máy chủ nên stateless: không chứa dữ liệu người dùng như session hay ảnh hồ sơ + * Session có thể lưu trong kho dữ liệu tập trung như [cơ sở dữ liệu](#cơ-sở-dữ-liệu) (SQL, NoSQL) hoặc [cache](#bộ-nhớ-đệm) bền vững (Redis, Memcached) +* Các máy chủ downstream như cache và cơ sở dữ liệu cần xử lý nhiều kết nối đồng thời hơn khi các máy upstream mở rộng + +### Nhược điểm: bộ cân bằng tải + +* Bộ cân bằng tải có thể trở thành nút cổ chai hiệu năng nếu không đủ tài nguyên hoặc cấu hình sai. +* Thêm bộ cân bằng tải để loại bỏ một điểm lỗi đơn làm tăng độ phức tạp. +* Một bộ cân bằng tải đơn lẻ là một điểm lỗi đơn; cấu hình nhiều bộ cân bằng tải làm tăng độ phức tạp hơn nữa. + +### Nguồn và đọc thêm + +* [Kiến trúc NGINX](https://www.nginx.com/blog/inside-nginx-how-we-designed-for-performance-scale/) +* [Hướng dẫn kiến trúc HAProxy](http://www.haproxy.org/download/1.2/doc/architecture.txt) +* [Scalability](https://web.archive.org/web/20220530193911/https://www.lecloud.net/post/7295452622/scalability-for-dummies-part-1-clones) +* [Wikipedia](https://en.wikipedia.org/wiki/Load_balancing_(computing)) +* [Cân bằng tải tầng 4](https://www.nginx.com/resources/glossary/layer-4-load-balancing/) +* [Cân bằng tải tầng 7](https://www.nginx.com/resources/glossary/layer-7-load-balancing/) +* [Cấu hình ELB listener](http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-listener-config.html) + +## Reverse proxy (máy chủ web) + +

+ +
+ Nguồn: Wikipedia +
+

+ +Reverse proxy là một máy chủ web tập trung các dịch vụ nội bộ và cung cấp giao diện thống nhất cho bên ngoài. Request từ client được chuyển tới máy chủ có thể xử lý trước khi reverse proxy trả phản hồi của máy chủ về cho client. + +Lợi ích bổ sung gồm: + +* **Tăng bảo mật** - Ẩn thông tin máy chủ backend, chặn IP, giới hạn số kết nối mỗi client +* **Tăng khả năng mở rộng và linh hoạt** - Client chỉ thấy IP của reverse proxy, cho phép bạn mở rộng máy chủ hoặc thay đổi cấu hình +* **SSL termination** - Giải mã yêu cầu vào và mã hóa phản hồi ra để máy chủ backend không phải làm các thao tác tốn tài nguyên này + * Không cần cài [chứng chỉ X.509](https://en.wikipedia.org/wiki/X.509) trên từng máy chủ +* **Nén** - Nén phản hồi từ máy chủ +* **Cache** - Trả phản hồi cho các yêu cầu đã được cache +* **Nội dung tĩnh** - Phục vụ nội dung tĩnh trực tiếp + * HTML/CSS/JS + * Ảnh + * Video + * V.v. + +### Bộ cân bằng tải vs reverse proxy + +* Triển khai bộ cân bằng tải hữu ích khi bạn có nhiều máy chủ. Thường bộ cân bằng tải định tuyến lưu lượng tới một nhóm máy chủ cùng chức năng. +* Reverse proxy vẫn hữu ích ngay cả khi chỉ có một web server hoặc application server, mở ra các lợi ích ở phần trước. +* Các giải pháp như NGINX và HAProxy hỗ trợ cả reverse proxy tầng 7 và cân bằng tải. + +### Nhược điểm: reverse proxy + +* Thêm reverse proxy làm tăng độ phức tạp. +* Một reverse proxy đơn lẻ là một điểm lỗi đơn; cấu hình nhiều reverse proxy (ví dụ [failover](https://en.wikipedia.org/wiki/Failover)) làm tăng độ phức tạp hơn nữa. + +### Nguồn và đọc thêm + +* [Reverse proxy vs load balancer](https://www.nginx.com/resources/glossary/reverse-proxy-vs-load-balancer/) +* [Kiến trúc NGINX](https://www.nginx.com/blog/inside-nginx-how-we-designed-for-performance-scale/) +* [Hướng dẫn kiến trúc HAProxy](http://www.haproxy.org/download/1.2/doc/architecture.txt) +* [Wikipedia](https://en.wikipedia.org/wiki/Reverse_proxy) + +## Tầng ứng dụng + +

+ +
+ Nguồn: Intro to architecting systems for scale +

+ +Tách tầng web khỏi tầng ứng dụng (còn gọi là tầng nền tảng) cho phép bạn mở rộng và cấu hình hai tầng độc lập. Thêm API mới dẫn đến thêm máy chủ ứng dụng mà không nhất thiết phải thêm máy chủ web. **Nguyên tắc trách nhiệm đơn** khuyến khích các dịch vụ nhỏ và tự chủ phối hợp với nhau. Nhóm nhỏ với dịch vụ nhỏ có thể lập kế hoạch tích cực hơn cho tăng trưởng nhanh. + +Các worker trong tầng ứng dụng cũng giúp hỗ trợ [bất đồng bộ](#bất-đồng-bộ). + +### Vi dịch vụ + +Liên quan tới thảo luận này là [vi dịch vụ](https://en.wikipedia.org/wiki/Microservices), có thể hiểu là một tập các dịch vụ nhỏ, mô-đun, có thể triển khai độc lập. Mỗi dịch vụ chạy một tiến trình riêng và giao tiếp qua cơ chế nhẹ, được định nghĩa rõ ràng, để phục vụ mục tiêu nghiệp vụ. 1 + +Ví dụ, Pinterest có thể có các vi dịch vụ: hồ sơ người dùng, người theo dõi, bảng tin, tìm kiếm, tải ảnh, v.v. + +### Khám phá dịch vụ + +Các hệ thống như [Consul](https://www.consul.io/docs/index.html), [Etcd](https://coreos.com/etcd/docs/latest), và [Zookeeper](http://www.slideshare.net/sauravhaloi/introduction-to-apache-zookeeper) giúp các dịch vụ tìm thấy nhau bằng cách theo dõi tên, địa chỉ và cổng đã đăng ký. [Health checks](https://www.consul.io/intro/getting-started/checks.html) giúp xác minh tình trạng dịch vụ và thường được thực hiện qua điểm cuối (endpoint) [HTTP](#giao-thức-truyền-siêu-văn-bản-http). Cả Consul và Etcd đều có [kho khóa-giá trị](#kho-khóa-giá-trị) tích hợp, hữu ích cho lưu cấu hình và dữ liệu dùng chung. + +### Nhược điểm: tầng ứng dụng + +* Thêm tầng ứng dụng với các dịch vụ liên kết lỏng (loosely coupled) yêu cầu cách tiếp cận khác về kiến trúc, vận hành và quy trình (so với hệ thống đơn khối). +* Vi dịch vụ có thể làm tăng độ phức tạp về triển khai và vận hành. + +### Nguồn và đọc thêm + +* [Intro to architecting systems for scale](http://lethain.com/introduction-to-architecting-systems-for-scale) +* [Crack the system design interview](http://www.puncsky.com/blog/2016-02-13-crack-the-system-design-interview) +* [Service oriented architecture](https://en.wikipedia.org/wiki/Service-oriented_architecture) +* [Introduction to Zookeeper](http://www.slideshare.net/sauravhaloi/introduction-to-apache-zookeeper) +* [What you need to know about building microservices](https://cloudncode.wordpress.com/2016/07/22/msa-getting-started/) + +## Cơ sở dữ liệu + +

+ +
+ Nguồn: Scaling up to your first 10 million users +

+ +### Hệ quản trị CSDL quan hệ (RDBMS) + +Cơ sở dữ liệu quan hệ như SQL là tập các dữ liệu được tổ chức thành bảng. + +**ACID** là tập các thuộc tính của [giao dịch](https://en.wikipedia.org/wiki/Database_transaction) trong cơ sở dữ liệu quan hệ. + +* **Atomicity** - Mỗi giao dịch hoặc là toàn bộ hoặc không có gì +* **Consistency** - Mỗi giao dịch sẽ đưa cơ sở dữ liệu từ trạng thái hợp lệ này sang trạng thái hợp lệ khác +* **Isolation** - Thực thi giao dịch đồng thời có kết quả như thể chúng được thực thi tuần tự +* **Durability** - Khi giao dịch đã được commit, nó sẽ được giữ bền + +Có nhiều kỹ thuật để mở rộng cơ sở dữ liệu quan hệ: **sao chép master-slave**, **sao chép master-master**, **liên kết (federation)**, **phân mảnh (sharding)**, **phi chuẩn hóa**, và **tối ưu SQL**. + +#### Sao chép master-slave + +Master phục vụ đọc và ghi, đồng thời sao chép ghi sang một hoặc nhiều slave chỉ phục vụ đọc. Slave có thể tiếp tục sao chép sang slave khác theo dạng cây. Nếu master offline, hệ thống vẫn có thể chạy ở chế độ chỉ đọc cho đến khi một slave được nâng lên làm master hoặc một master mới được provision. + +

+ +
+ Nguồn: Scalability, availability, stability, patterns +

+ +##### Nhược điểm: sao chép master-slave + +* Cần thêm logic để nâng slave lên thành master. +* Xem [Nhược điểm: sao chép](#nhược-điểm-sao-chép) cho các điểm liên quan tới **cả** master-slave và master-master. + +#### Sao chép master-master + +Cả hai master đều phục vụ đọc và ghi, đồng thời phối hợp với nhau khi ghi. Nếu một master down, hệ thống vẫn có thể tiếp tục đọc và ghi. + +

+ +
+ Nguồn: Scalability, availability, stability, patterns +

+ +##### Nhược điểm: sao chép master-master + +* Bạn cần bộ cân bằng tải hoặc phải thay đổi logic ứng dụng để quyết định ghi vào đâu. +* Phần lớn hệ thống master-master hoặc có tính nhất quán lỏng (vi phạm ACID) hoặc có độ trễ ghi tăng do đồng bộ. +* Giải quyết xung đột quan trọng hơn khi có nhiều nút ghi và độ trễ tăng. +* Xem [Nhược điểm: sao chép](#nhược-điểm-sao-chép) cho các điểm liên quan tới **cả** master-slave và master-master. + +##### Nhược điểm: sao chép + +* Có thể mất dữ liệu nếu master thất bại trước khi dữ liệu mới được sao chép sang nút khác. +* Ghi được phát lại lên các bản sao đọc. Nếu ghi nhiều, các bản sao đọc có thể bị nghẽn do phát lại ghi và không thể đọc nhiều. +* Càng nhiều slave đọc, càng phải sao chép nhiều, dẫn đến độ trễ sao chép lớn hơn. +* Trên một số hệ thống, ghi vào master có thể tạo nhiều luồng ghi song song, trong khi bản sao đọc chỉ hỗ trợ ghi tuần tự với một luồng. +* Sao chép đòi hỏi thêm phần cứng và tăng độ phức tạp. + +##### Nguồn và đọc thêm: sao chép + +* [Scalability, availability, stability, patterns](http://www.slideshare.net/jboner/scalability-availability-stability-patterns/) +* [Multi-master replication](https://en.wikipedia.org/wiki/Multi-master_replication) + +#### Liên kết (federation) + +

+ +
+ Nguồn: Scaling up to your first 10 million users +

+ +Liên kết (hoặc phân vùng theo chức năng) tách cơ sở dữ liệu theo chức năng. Ví dụ, thay vì một cơ sở dữ liệu đơn khối, bạn có thể có ba cơ sở dữ liệu: **diễn đàn**, **người dùng**, và **sản phẩm**, giúp giảm lưu lượng đọc/ghi cho mỗi cơ sở dữ liệu và do đó giảm độ trễ sao chép. Cơ sở dữ liệu nhỏ hơn dẫn đến nhiều dữ liệu hơn có thể nằm trong bộ nhớ, tăng cache hit nhờ tính cục bộ cache. Không có một master trung tâm tuần tự hóa ghi nên bạn có thể ghi song song, tăng thông lượng. + +##### Nhược điểm: liên kết + +* Liên kết không hiệu quả nếu schema cần các chức năng hoặc bảng quá lớn. +* Bạn phải cập nhật logic ứng dụng để quyết định đọc/ghi vào cơ sở dữ liệu nào. +* Join dữ liệu từ hai cơ sở dữ liệu phức tạp hơn với [server link](http://stackoverflow.com/questions/5145637/querying-data-by-joining-two-tables-in-two-database-on-different-servers). +* Liên kết đòi hỏi thêm phần cứng và tăng độ phức tạp. + +##### Nguồn và đọc thêm: liên kết + +* [Scaling up to your first 10 million users](https://www.youtube.com/watch?v=kKjm4ehYiMs) + +#### Phân mảnh (sharding) + +

+ +
+ Nguồn: Scalability, availability, stability, patterns +

+ +Phân mảnh phân phối dữ liệu qua các cơ sở dữ liệu khác nhau sao cho mỗi cơ sở dữ liệu chỉ quản lý một phần dữ liệu. Lấy cơ sở dữ liệu người dùng làm ví dụ, khi số người dùng tăng, ta thêm nhiều shard vào cụm. + +Tương tự lợi ích của [liên kết](#liên-kết-federation), phân mảnh làm giảm lưu lượng đọc/ghi, giảm sao chép và tăng cache hit. Kích thước chỉ mục cũng giảm, thường cải thiện hiệu năng với truy vấn nhanh hơn. Nếu một shard bị down, các shard khác vẫn hoạt động, dù bạn nên thêm cơ chế sao chép để tránh mất dữ liệu. Giống liên kết, không có master trung tâm tuần tự hóa ghi, cho phép ghi song song và tăng thông lượng. + +Cách phân mảnh phổ biến cho bảng người dùng là theo chữ cái đầu của họ hoặc theo vị trí địa lý. + +##### Nhược điểm: phân mảnh + +* Bạn phải cập nhật logic ứng dụng để làm việc với shard, có thể dẫn đến truy vấn SQL phức tạp. +* Phân phối dữ liệu có thể bị lệch trong một shard. Ví dụ, một nhóm power users trên một shard có thể làm tăng tải shard đó so với các shard khác. + * Cân bằng lại tăng độ phức tạp. Hàm phân mảnh dựa trên [consistent hashing](http://www.paperplanes.de/2011/12/9/the-magic-of-consistent-hashing.html) có thể giảm lượng dữ liệu cần chuyển. +* Join dữ liệu từ nhiều shard phức tạp hơn. +* Phân mảnh đòi hỏi thêm phần cứng và tăng độ phức tạp. + +##### Nguồn và đọc thêm: phân mảnh + +* [The coming of the shard](http://highscalability.com/blog/2009/8/6/an-unorthodox-approach-to-database-design-the-coming-of-the.html) +* [Shard database architecture](https://en.wikipedia.org/wiki/Shard_(database_architecture)) +* [Consistent hashing](http://www.paperplanes.de/2011/12/9/the-magic-of-consistent-hashing.html) + +#### Phi chuẩn hóa + +Phi chuẩn hóa cố gắng cải thiện hiệu năng đọc, đổi lại một phần hiệu năng ghi. Bản sao dữ liệu dư thừa được ghi ở nhiều bảng để tránh join tốn kém. Một số RDBMS như [PostgreSQL](https://en.wikipedia.org/wiki/PostgreSQL) và Oracle hỗ trợ [materialized views](https://en.wikipedia.org/wiki/Materialized_view) để lưu và giữ nhất quán các bản sao dư thừa. + +Khi dữ liệu được phân tán bằng các kỹ thuật như [liên kết](#liên-kết-federation) và [phân mảnh](#phân-mảnh-sharding), việc quản lý join giữa các trung tâm dữ liệu càng phức tạp. Phi chuẩn hóa có thể giúp tránh các join phức tạp như vậy. + +Trong hầu hết hệ thống, đọc có thể nhiều hơn ghi 100:1 hoặc thậm chí 1000:1. Một lần đọc phải join phức tạp có thể rất tốn kém, mất nhiều thời gian cho I/O đĩa. + +##### Nhược điểm: phi chuẩn hóa + +* Dữ liệu bị nhân bản. +* Ràng buộc giúp các bản sao dư thừa giữ đồng bộ, làm tăng độ phức tạp trong thiết kế CSDL. +* Cơ sở dữ liệu phi chuẩn hóa dưới tải ghi lớn có thể kém hiệu năng hơn so với bản chuẩn hóa. + +###### Nguồn và đọc thêm: phi chuẩn hóa + +* [Denormalization](https://en.wikipedia.org/wiki/Denormalization) + +#### Tối ưu SQL + +Tối ưu SQL là một chủ đề rộng và đã có nhiều [sách](https://www.amazon.com/s/ref=nb_sb_noss_2?url=search-alias%3Daps&field-keywords=sql+tuning) tham khảo. + +Điều quan trọng là **benchmark** và **profile** để mô phỏng và tìm nút thắt. + +* **Benchmark** - Mô phỏng tải cao với các công cụ như [ab](http://httpd.apache.org/docs/2.2/programs/ab.html). +* **Profile** - Bật các công cụ như [slow query log](http://dev.mysql.com/doc/refman/5.7/en/slow-query-log.html) để theo dõi vấn đề hiệu năng. + +Benchmark và profile có thể chỉ ra các tối ưu sau. + +##### Siết chặt schema + +* MySQL ghi ra đĩa theo các khối liên tiếp để truy cập nhanh. +* Dùng `CHAR` thay cho `VARCHAR` với trường độ dài cố định. + * `CHAR` cho phép truy cập ngẫu nhiên nhanh, còn `VARCHAR` yêu cầu tìm cuối chuỗi trước khi sang chuỗi tiếp theo. +* Dùng `TEXT` cho khối văn bản lớn như bài blog. `TEXT` cũng cho phép tìm kiếm boolean. Trường `TEXT` lưu một con trỏ trên đĩa để định vị khối văn bản. +* Dùng `INT` cho số đến 2^32 hoặc 4 tỷ. +* Dùng `DECIMAL` cho tiền tệ để tránh lỗi biểu diễn số thực. +* Tránh lưu `BLOBS` lớn, thay vào đó lưu vị trí để lấy đối tượng. +* `VARCHAR(255)` là số ký tự lớn nhất có thể đếm trong 1 byte, thường tối đa hóa việc dùng một byte trong một số RDBMS. +* Đặt ràng buộc `NOT NULL` khi phù hợp để [tăng hiệu năng tìm kiếm](http://stackoverflow.com/questions/1017239/how-do-null-values-affect-performance-in-a-database-search). + +##### Dùng chỉ mục tốt + +* Các cột bạn truy vấn (`SELECT`, `GROUP BY`, `ORDER BY`, `JOIN`) có thể nhanh hơn với chỉ mục. +* Chỉ mục thường được biểu diễn bằng [B-tree](https://en.wikipedia.org/wiki/B-tree) tự cân bằng, giữ dữ liệu đã sắp xếp và cho phép tìm kiếm, truy cập tuần tự, chèn và xóa trong thời gian logarit. +* Đặt chỉ mục có thể giữ dữ liệu trong bộ nhớ, cần thêm dung lượng. +* Ghi có thể chậm hơn vì chỉ mục cũng phải được cập nhật. +* Khi nạp lượng dữ liệu lớn, có thể nhanh hơn nếu tắt chỉ mục, nạp dữ liệu, rồi tạo lại chỉ mục. + +##### Tránh join tốn kém + +* [Phi chuẩn hóa](#phi-chuẩn-hóa) khi hiệu năng yêu cầu. + +##### Phân vùng bảng + +* Tách bảng bằng cách đưa các điểm nóng vào bảng riêng để giữ trong bộ nhớ. + +##### Tinh chỉnh query cache + +* Trong một số trường hợp, [query cache](https://dev.mysql.com/doc/refman/5.7/en/query-cache.html) có thể gây [vấn đề hiệu năng](https://www.percona.com/blog/2016/10/12/mysql-5-7-performance-tuning-immediately-after-installation/). + +##### Nguồn và đọc thêm: tối ưu SQL + +* [Mẹo tối ưu truy vấn MySQL](http://aiddroid.com/10-tips-optimizing-mysql-queries-dont-suck/) +* [Vì sao thường thấy VARCHAR(255)?](http://stackoverflow.com/questions/1217466/is-there-a-good-reason-i-see-varchar255-used-so-often-as-opposed-to-another-l) +* [Giá trị null ảnh hưởng hiệu năng ra sao?](http://stackoverflow.com/questions/1017239/how-do-null-values-affect-performance-in-a-database-search) +* [Slow query log](http://dev.mysql.com/doc/refman/5.7/en/slow-query-log.html) + +### NoSQL + +NoSQL là tập dữ liệu được biểu diễn dưới dạng **kho khóa-giá trị**, **kho tài liệu**, **kho cột rộng**, hoặc **CSDL đồ thị**. Dữ liệu được phi chuẩn hóa, và join thường được thực hiện trong code ứng dụng. Hầu hết kho NoSQL thiếu giao dịch ACID thực sự và ưu tiên [nhất quán cuối cùng](#nhất-quán-cuối-cùng). + +**BASE** thường dùng để mô tả thuộc tính của CSDL NoSQL. So với [định lý CAP](#định-lý-cap), BASE chọn tính sẵn sàng thay vì tính nhất quán. + +* **Basically available** - hệ thống đảm bảo tính sẵn sàng. +* **Soft state** - trạng thái hệ thống có thể thay đổi theo thời gian, ngay cả khi không có đầu vào. +* **Eventual consistency** - hệ thống sẽ trở nên nhất quán sau một khoảng thời gian, với điều kiện không có đầu vào trong khoảng đó. + +Ngoài việc chọn [SQL hay NoSQL](#sql-hay-nosql), bạn cũng nên hiểu loại CSDL NoSQL nào phù hợp với trường hợp sử dụng. Chúng ta sẽ xem **kho khóa-giá trị**, **kho tài liệu**, **kho cột rộng**, và **CSDL đồ thị** ở phần tiếp theo. + +#### Kho khóa-giá trị + +> Trừu tượng: bảng băm + +Kho khóa-giá trị thường cho phép đọc/ghi O(1) và thường dựa trên RAM hoặc SSD. Các kho dữ liệu có thể giữ khóa theo [thứ tự từ vựng](https://en.wikipedia.org/wiki/Lexicographical_order), cho phép truy xuất hiệu quả theo dải khóa. Kho khóa-giá trị có thể lưu metadata cùng với giá trị. + +Kho khóa-giá trị có hiệu năng cao và thường được dùng cho mô hình dữ liệu đơn giản hoặc dữ liệu thay đổi nhanh, ví dụ tầng cache trong bộ nhớ. Vì chỉ hỗ trợ tập thao tác hạn chế, độ phức tạp được đẩy sang tầng ứng dụng khi cần thao tác bổ sung. + +Kho khóa-giá trị là nền tảng cho hệ thống phức tạp hơn như kho tài liệu, và trong một số trường hợp là CSDL đồ thị. + +##### Nguồn và đọc thêm: kho khóa-giá trị + +* [Key-value database](https://en.wikipedia.org/wiki/Key-value_database) +* [Nhược điểm của kho khóa-giá trị](http://stackoverflow.com/questions/4056093/what-are-the-disadvantages-of-using-a-key-value-table-over-nullable-columns-or) +* [Kiến trúc Redis](http://qnimate.com/overview-of-redis-architecture/) +* [Kiến trúc Memcached](https://adayinthelifeof.nl/2011/02/06/memcache-internals/) + +#### Kho tài liệu + +> Trừu tượng: kho khóa-giá trị với tài liệu làm giá trị + +Kho tài liệu xoay quanh các tài liệu (XML, JSON, nhị phân, v.v.), nơi một tài liệu lưu mọi thông tin cho một đối tượng. Kho tài liệu cung cấp API hoặc ngôn ngữ truy vấn dựa trên cấu trúc bên trong tài liệu. *Lưu ý: nhiều kho khóa-giá trị có tính năng xử lý metadata của giá trị, làm mờ ranh giới giữa hai loại lưu trữ này.* + +Dựa trên cách triển khai, tài liệu được tổ chức theo bộ sưu tập, tag, metadata hoặc thư mục. Dù tài liệu có thể được nhóm, các tài liệu vẫn có thể có trường hoàn toàn khác nhau. + +Một số kho tài liệu như [MongoDB](https://www.mongodb.com/mongodb-architecture) và [CouchDB](https://blog.couchdb.org/2016/08/01/couchdb-2-0-architecture/) cũng cung cấp ngôn ngữ giống SQL để truy vấn phức tạp. [DynamoDB](http://www.read.seas.harvard.edu/~kohler/class/cs239-w08/decandia07dynamo.pdf) hỗ trợ cả khóa-giá trị lẫn tài liệu. + +Kho tài liệu có tính linh hoạt cao và thường dùng cho dữ liệu thay đổi không thường xuyên. + +##### Nguồn và đọc thêm: kho tài liệu + +* [Document-oriented database](https://en.wikipedia.org/wiki/Document-oriented_database) +* [Kiến trúc MongoDB](https://www.mongodb.com/mongodb-architecture) +* [Kiến trúc CouchDB](https://blog.couchdb.org/2016/08/01/couchdb-2-0-architecture/) +* [Kiến trúc Elasticsearch](https://www.elastic.co/blog/found-elasticsearch-from-the-bottom-up) + +#### Kho cột rộng + +

+ +
+ Nguồn: SQL & NoSQL, a brief history +

+ +> Trừu tượng: map lồng nhau `ColumnFamily>` + +Đơn vị dữ liệu cơ bản của kho cột rộng là một cột (cặp tên/giá trị). Một cột có thể được nhóm thành họ cột (tương tự bảng SQL). Họ cột siêu (super column families) nhóm nhiều họ cột. Bạn có thể truy cập từng cột độc lập bằng row key, và các cột có cùng row key tạo thành một dòng. Mỗi giá trị chứa timestamp để versioning và giải quyết xung đột. + +Google giới thiệu [Bigtable](http://www.read.seas.harvard.edu/~kohler/class/cs239-w08/chang06bigtable.pdf) như kho cột rộng đầu tiên, ảnh hưởng tới [HBase](https://www.edureka.co/blog/hbase-architecture/) mã nguồn mở trong hệ sinh thái Hadoop, và [Cassandra](http://docs.datastax.com/en/cassandra/3.0/cassandra/architecture/archIntro.html) từ Facebook. Các kho như BigTable, HBase, và Cassandra giữ khóa theo thứ tự từ vựng, cho phép truy xuất hiệu quả theo dải khóa chọn lọc. + +Kho cột rộng cung cấp tính sẵn sàng và khả năng mở rộng cao. Chúng thường dùng cho bộ dữ liệu rất lớn. + +##### Nguồn và đọc thêm: kho cột rộng + +* [SQL & NoSQL, a brief history](http://blog.grio.com/2015/11/sql-nosql-a-brief-history.html) +* [Kiến trúc Bigtable](http://www.read.seas.harvard.edu/~kohler/class/cs239-w08/chang06bigtable.pdf) +* [Kiến trúc HBase](https://www.edureka.co/blog/hbase-architecture/) +* [Kiến trúc Cassandra](http://docs.datastax.com/en/cassandra/3.0/cassandra/architecture/archIntro.html) + +#### CSDL đồ thị + +

+ +
+ Nguồn: Graph database +

+ +> Trừu tượng: đồ thị + +Trong CSDL đồ thị, mỗi nút là một bản ghi và mỗi cạnh là mối quan hệ giữa hai nút. CSDL đồ thị được tối ưu để biểu diễn các quan hệ phức tạp với nhiều khóa ngoại hoặc quan hệ nhiều-nhiều. + +CSDL đồ thị có hiệu năng cao với mô hình dữ liệu quan hệ phức tạp như mạng xã hội. Chúng tương đối mới và chưa được dùng rộng rãi; có thể khó tìm công cụ và tài nguyên phát triển. Nhiều CSDL đồ thị chỉ truy cập được qua [REST API](#chuyển-trạng-thái-biểu-diễn-rest). + +##### Nguồn và đọc thêm: đồ thị + +* [Graph database](https://en.wikipedia.org/wiki/Graph_database) +* [Neo4j](https://neo4j.com/) +* [FlockDB](https://blog.twitter.com/2010/introducing-flockdb) + +#### Nguồn và đọc thêm: NoSQL + +* [Giải thích thuật ngữ BASE](http://stackoverflow.com/questions/3342497/explanation-of-base-terminology) +* [Khảo sát và hướng dẫn quyết định NoSQL](https://medium.com/baqend-blog/nosql-databases-a-survey-and-decision-guidance-ea7823a822d#.wskogqenq) +* [Scalability](https://web.archive.org/web/20220602114024/https://www.lecloud.net/post/7994751381/scalability-for-dummies-part-2-database) +* [Giới thiệu NoSQL](https://www.youtube.com/watch?v=qI_g07C_Q5I) +* [NoSQL patterns](http://horicky.blogspot.com/2009/11/nosql-patterns.html) + +### SQL hay NoSQL + +

+ +
+ Nguồn: Transitioning from RDBMS to NoSQL +

+ +Lý do chọn **SQL**: + +* Dữ liệu có cấu trúc +* Schema nghiêm ngặt +* Dữ liệu quan hệ +* Cần join phức tạp +* Giao dịch +* Có mẫu hình mở rộng rõ ràng +* Đã trưởng thành: developer, cộng đồng, code, công cụ, v.v. +* Tra cứu theo chỉ mục rất nhanh + +Lý do chọn **NoSQL**: + +* Dữ liệu bán cấu trúc +* Schema động hoặc linh hoạt +* Dữ liệu phi quan hệ +* Không cần join phức tạp +* Lưu nhiều TB (hoặc PB) dữ liệu +* Workload rất nặng về dữ liệu +* Thông lượng IOPS rất cao + +Dữ liệu mẫu phù hợp với NoSQL: + +* Nạp nhanh dữ liệu clickstream và log +* Dữ liệu bảng xếp hạng hoặc điểm số +* Dữ liệu tạm, như giỏ hàng +* Bảng được truy cập thường xuyên ("hot") +* Bảng metadata/lookup + +##### Nguồn và đọc thêm: SQL hay NoSQL + +* [Scaling up to your first 10 million users](https://www.youtube.com/watch?v=kKjm4ehYiMs) +* [Khác biệt SQL vs NoSQL](https://www.sitepoint.com/sql-vs-nosql-differences/) + +## Bộ nhớ đệm + +

+ +
+ Nguồn: Scalable system design patterns +

+ +Cache cải thiện thời gian tải trang và giảm tải cho máy chủ và cơ sở dữ liệu. Trong mô hình này, bộ điều phối sẽ kiểm tra xem yêu cầu đã từng được thực hiện chưa và cố gắng trả lại kết quả trước đó để tiết kiệm thực thi. + +Cơ sở dữ liệu thường hưởng lợi khi đọc/ghi phân bố đều trên các phân vùng. Các mục phổ biến có thể làm lệch phân bố, gây nút thắt. Đặt cache trước cơ sở dữ liệu giúp hấp thụ tải không đều và các đợt tăng đột biến. + +### Đệm phía client + +Cache có thể nằm phía client (OS hoặc trình duyệt), [phía server](#reverse-proxy-máy-chủ-web), hoặc ở một tầng cache riêng. + +### Đệm CDN + +[CDN](#mạng-phân-phối-nội-dung) được xem là một dạng cache. + +### Đệm máy chủ web + +[Reverse proxy](#reverse-proxy-máy-chủ-web) và cache như [Varnish](https://www.varnish-cache.org/) có thể phục vụ nội dung tĩnh và động trực tiếp. Máy chủ web cũng có thể cache yêu cầu, trả phản hồi mà không cần liên hệ máy chủ ứng dụng. + +### Đệm cơ sở dữ liệu + +Cơ sở dữ liệu thường có một mức cache mặc định, tối ưu cho trường hợp chung. Điều chỉnh các cài đặt này cho pattern sử dụng cụ thể có thể tăng hiệu năng hơn nữa. + +### Đệm tầng ứng dụng + +Cache trong bộ nhớ như Memcached và Redis là kho khóa-giá trị nằm giữa ứng dụng và kho dữ liệu. Vì dữ liệu nằm trong RAM, nhanh hơn nhiều so với CSDL lưu trên đĩa. RAM hạn chế hơn đĩa nên các thuật toán [vô hiệu hóa cache](https://en.wikipedia.org/wiki/Cache_algorithms) như [least recently used (LRU)](https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU)) giúp loại bỏ mục "lạnh" và giữ dữ liệu "nóng" trong RAM. + +Redis có các tính năng bổ sung: + +* Tùy chọn lưu bền +* Cấu trúc dữ liệu tích hợp như sorted sets và lists + +Có nhiều mức cache có thể chia thành hai nhóm chính: **truy vấn cơ sở dữ liệu** và **đối tượng**: + +* Mức dòng +* Mức truy vấn +* Đối tượng tuần tự hóa hoàn chỉnh +* HTML được render hoàn chỉnh + +Nói chung, nên tránh cache dựa trên file vì làm việc nhân bản và auto-scaling khó hơn. + +### Đệm ở mức truy vấn CSDL + +Mỗi khi truy vấn CSDL, hash truy vấn làm key và lưu kết quả vào cache. Cách này gặp vấn đề hết hạn: + +* Khó xóa kết quả cache với truy vấn phức tạp +* Nếu một mảnh dữ liệu thay đổi như một ô bảng, bạn phải xóa tất cả truy vấn cache có thể chứa ô đó + +### Đệm ở mức đối tượng + +Xem dữ liệu như một đối tượng, tương tự cách bạn làm với code ứng dụng. Hãy để ứng dụng lắp ráp tập dữ liệu từ CSDL thành một instance lớp hoặc cấu trúc dữ liệu: + +* Xóa đối tượng khỏi cache nếu dữ liệu nền tảng thay đổi +* Cho phép xử lý bất đồng bộ: worker lắp ráp đối tượng bằng cách tiêu thụ đối tượng cache mới nhất + +Gợi ý các thứ nên cache: + +* Session người dùng +* Trang web đã render hoàn chỉnh +* Activity streams +* Dữ liệu đồ thị người dùng + +### Khi nào cập nhật cache + +Vì chỉ có thể lưu một lượng dữ liệu hạn chế trong cache, bạn cần xác định chiến lược cập nhật cache phù hợp nhất. + +#### Cache-aside + +

+ +
+ Nguồn: From cache to in-memory data grid +

+ +Ứng dụng chịu trách nhiệm đọc/ghi từ kho lưu trữ. Cache không tương tác trực tiếp với kho lưu trữ. Ứng dụng làm các bước: + +* Tìm entry trong cache, nếu không có thì cache miss +* Tải entry từ CSDL +* Thêm entry vào cache +* Trả entry + +```python +def get_user(self, user_id): + user = cache.get("user.{0}", user_id) + if user is None: + user = db.query("SELECT * FROM users WHERE user_id = {0}", user_id) + if user is not None: + key = "user.{0}".format(user_id) + cache.set(key, json.dumps(user)) + return user +``` + +[Memcached](https://memcached.org/) thường được dùng theo cách này. + +Các lần đọc sau với dữ liệu đã cache sẽ nhanh. Cache-aside còn được gọi là lazy loading. Chỉ dữ liệu được yêu cầu mới được cache, tránh đầy cache với dữ liệu không được yêu cầu. + +##### Nhược điểm: cache-aside + +* Mỗi cache miss tạo ra ba chuyến, có thể gây trễ đáng kể. +* Dữ liệu có thể bị cũ nếu CSDL được cập nhật. Vấn đề này được giảm bằng cách đặt TTL để buộc cập nhật cache entry, hoặc dùng write-through. +* Khi một nút lỗi, nó được thay bằng nút mới rỗng, làm tăng độ trễ. + +#### Write-through + +

+ +
+ Nguồn: Scalability, availability, stability, patterns +

+ +Ứng dụng dùng cache làm kho dữ liệu chính, đọc/ghi vào đó, trong khi cache chịu trách nhiệm đọc/ghi vào CSDL: + +* Ứng dụng thêm/cập nhật entry trong cache +* Cache ghi đồng bộ entry vào kho dữ liệu +* Trả kết quả + +Mã ứng dụng: + +```python +set_user(12345, {"foo":"bar"}) +``` + +Mã cache: + +```python +def set_user(user_id, values): + user = db.query("UPDATE Users WHERE id = {0}", user_id, values) + cache.set(user_id, user) +``` + +Write-through là thao tác chậm tổng thể do ghi, nhưng các lần đọc sau của dữ liệu vừa ghi sẽ nhanh. Người dùng thường chịu được độ trễ khi cập nhật dữ liệu hơn là khi đọc. Dữ liệu trong cache không bị cũ. + +##### Nhược điểm: write-through + +* Khi nút mới được tạo do lỗi hoặc mở rộng, nút mới sẽ không cache entry cho đến khi entry được cập nhật trong CSDL. Kết hợp cache-aside với write-through có thể giảm vấn đề này. +* Hầu hết dữ liệu được ghi có thể không bao giờ được đọc, có thể giảm bằng TTL. + +#### Write-behind (write-back) + +

+ +
+ Nguồn: Scalability, availability, stability, patterns +

+ +Trong write-behind, ứng dụng làm các bước: + +* Thêm/cập nhật entry vào cache +* Ghi bất đồng bộ entry vào kho dữ liệu, cải thiện hiệu năng ghi + +##### Nhược điểm: write-behind + +* Có thể mất dữ liệu nếu cache bị down trước khi nội dung được ghi vào kho dữ liệu. +* Write-behind phức tạp hơn cache-aside hoặc write-through. + +#### Refresh-ahead + +

+ +
+ Nguồn: From cache to in-memory data grid +

+ +Bạn có thể cấu hình cache tự động làm mới các entry được truy cập gần đây trước khi hết hạn. + +Refresh-ahead có thể giảm độ trễ so với read-through nếu cache dự đoán chính xác các mục có khả năng cần trong tương lai. + +##### Nhược điểm: refresh-ahead + +* Dự đoán không chính xác các mục cần trong tương lai có thể làm giảm hiệu năng so với không dùng refresh-ahead. + +### Nhược điểm: cache + +* Cần duy trì nhất quán giữa cache và nguồn dữ liệu chuẩn như CSDL thông qua [vô hiệu hóa cache](https://en.wikipedia.org/wiki/Cache_algorithms). +* Vô hiệu hóa cache là bài toán khó, có thêm độ phức tạp khi nào cập nhật cache. +* Cần thay đổi ứng dụng như thêm Redis hoặc memcached. + +### Nguồn và đọc thêm + +* [From cache to in-memory data grid](http://www.slideshare.net/tmatyashovsky/from-cache-to-in-memory-data-grid-introduction-to-hazelcast) +* [Scalable system design patterns](http://horicky.blogspot.com/2010/10/scalable-system-design-patterns.html) +* [Intro to architecting systems for scale](http://lethain.com/introduction-to-architecting-systems-for-scale/) +* [Scalability, availability, stability, patterns](http://www.slideshare.net/jboner/scalability-availability-stability-patterns/) +* [Scalability](https://web.archive.org/web/20230126233752/https://www.lecloud.net/post/9246290032/scalability-for-dummies-part-3-cache) +* [Chiến lược AWS ElastiCache](http://docs.aws.amazon.com/AmazonElastiCache/latest/UserGuide/Strategies.html) +* [Wikipedia](https://en.wikipedia.org/wiki/Cache_(computing)) + +## Bất đồng bộ + +

+ +
+ Nguồn: Intro to architecting systems for scale +

+ +Quy trình bất đồng bộ giúp giảm thời gian xử lý yêu cầu cho các thao tác tốn kém vốn phải thực hiện inline. Nó cũng giúp làm trước các công việc mất thời gian, như tổng hợp dữ liệu định kỳ. + +### Hàng đợi thông điệp + +Hàng đợi thông điệp nhận, giữ và chuyển thông điệp. Nếu một thao tác quá chậm để làm inline, bạn có thể dùng hàng đợi thông điệp theo quy trình: + +* Ứng dụng gửi một tác vụ (job) vào hàng đợi, rồi thông báo trạng thái tác vụ cho người dùng +* Worker lấy tác vụ từ hàng đợi, xử lý, rồi báo hoàn tất + +Người dùng không bị chặn và tác vụ được xử lý nền. Trong thời gian này, client có thể làm một lượng xử lý nhỏ để tạo cảm giác tác vụ đã hoàn tất. Ví dụ, khi đăng tweet, tweet có thể hiển thị ngay trên timeline của bạn, nhưng có thể mất một thời gian trước khi tweet thực sự tới tất cả người theo dõi. + +**[Redis](https://redis.io/)** hữu ích như message broker đơn giản nhưng có thể mất thông điệp. + +**[RabbitMQ](https://www.rabbitmq.com/)** phổ biến nhưng yêu cầu bạn thích nghi với giao thức 'AMQP' và tự quản lý node. + +**[Amazon SQS](https://aws.amazon.com/sqs/)** được host sẵn nhưng có thể có độ trễ cao và có khả năng thông điệp được gửi hai lần. + +### Hàng đợi tác vụ + +Hàng đợi tác vụ nhận tác vụ và dữ liệu liên quan, chạy chúng rồi trả kết quả. Chúng hỗ trợ lập lịch và có thể dùng để chạy các tác vụ tính toán nặng ở nền. + +**[Celery](https://docs.celeryproject.org/en/stable/)** hỗ trợ lập lịch và chủ yếu dành cho Python. + +### Back pressure + +Nếu hàng đợi tăng kích thước đáng kể, kích thước có thể vượt bộ nhớ, dẫn đến cache miss, đọc đĩa và hiệu năng còn chậm hơn. [Back pressure](http://mechanical-sympathy.blogspot.com/2012/05/apply-back-pressure-when-overloaded.html) giúp giới hạn kích thước hàng đợi, duy trì thông lượng cao và thời gian phản hồi tốt cho các tác vụ đã nằm trong hàng. Khi hàng đợi đầy, client nhận thông báo server bận hoặc mã HTTP 503 để thử lại sau. Client có thể retry sau, có thể dùng [exponential backoff](https://en.wikipedia.org/wiki/Exponential_backoff). + +### Nhược điểm: bất đồng bộ + +* Các trường hợp sử dụng như tính toán rẻ và luồng công việc thời gian thực có thể phù hợp hơn với thao tác đồng bộ, vì thêm hàng đợi làm tăng trễ và phức tạp. + +### Nguồn và đọc thêm + +* [It's all a numbers game](https://www.youtube.com/watch?v=1KRYH75wgy4) +* [Applying back pressure when overloaded](http://mechanical-sympathy.blogspot.com/2012/05/apply-back-pressure-when-overloaded.html) +* [Little's law](https://en.wikipedia.org/wiki/Little%27s_law) +* [Khác nhau giữa message queue và task queue?](https://www.quora.com/What-is-the-difference-between-a-message-queue-and-a-task-queue-Why-would-a-task-queue-require-a-message-broker-like-RabbitMQ-Redis-Celery-or-IronMQ-to-function) + +## Giao tiếp + +

+ +
+ Nguồn: OSI 7 layer model +

+ +### Giao thức truyền siêu văn bản (HTTP) + +HTTP là một phương thức để mã hóa và truyền dữ liệu giữa client và server. Đây là giao thức yêu cầu/phản hồi: client gửi yêu cầu và server trả phản hồi với nội dung liên quan và trạng thái hoàn thành của yêu cầu. HTTP tự chứa, cho phép yêu cầu/phản hồi đi qua nhiều router và server trung gian thực hiện cân bằng tải, cache, mã hóa và nén. + +Một yêu cầu HTTP cơ bản gồm một động từ (method) và một tài nguyên (endpoint). Dưới đây là các động từ HTTP phổ biến: + +| Động từ | Mô tả | Idempotent* | Safe | Cacheable | +|---|---|---|---|---| +| GET | Đọc một tài nguyên | Có | Có | Có | +| POST | Tạo một tài nguyên hoặc kích hoạt một tiến trình xử lý dữ liệu | Không | Không | Có nếu phản hồi có thông tin về độ mới | +| PUT | Tạo hoặc thay thế một tài nguyên | Có | Không | Không | +| PATCH | Cập nhật một phần tài nguyên | Không | Không | Có nếu phản hồi có thông tin về độ mới | +| DELETE | Xóa một tài nguyên | Có | Không | Không | + +*Có thể gọi nhiều lần mà không làm thay đổi kết quả. + +HTTP là giao thức tầng ứng dụng dựa trên các giao thức tầng thấp như **TCP** và **UDP**. + +#### Nguồn và đọc thêm: HTTP + +* [HTTP là gì?](https://www.nginx.com/resources/glossary/http/) +* [Khác biệt giữa HTTP và TCP](https://www.quora.com/What-is-the-difference-between-HTTP-protocol-and-TCP-protocol) +* [Khác biệt giữa PUT và PATCH](https://laracasts.com/discuss/channels/general-discussion/whats-the-differences-between-put-and-patch?page=1) + +### Giao thức điều khiển truyền tải (TCP) + +

+ +
+ Nguồn: How to make a multiplayer game +

+ +TCP là giao thức hướng kết nối trên [mạng IP](https://en.wikipedia.org/wiki/Internet_Protocol). Kết nối được thiết lập và kết thúc bằng [handshake](https://en.wikipedia.org/wiki/Handshaking). Tất cả gói gửi đi được đảm bảo đến đúng thứ tự và không bị hỏng thông qua: + +* Số thứ tự và [checksum](https://en.wikipedia.org/wiki/Transmission_Control_Protocol#Checksum_computation) cho mỗi gói +* Gói [acknowledgement](https://en.wikipedia.org/wiki/Acknowledgement_(data_networks)) và cơ chế retransmission tự động + +Nếu bên gửi không nhận phản hồi đúng, nó sẽ gửi lại gói. Nếu nhiều lần timeout, kết nối bị hủy. TCP cũng triển khai [flow control](https://en.wikipedia.org/wiki/Flow_control_(data)) và [congestion control](https://en.wikipedia.org/wiki/Network_congestion#Congestion_control). Các đảm bảo này tạo độ trễ và thường khiến truyền tải kém hiệu quả hơn UDP. + +Để đảm bảo thông lượng cao, web server có thể giữ nhiều kết nối TCP mở, dẫn tới dùng nhiều bộ nhớ. Việc duy trì nhiều kết nối mở giữa các thread của web server và một server [memcached](https://memcached.org/) có thể tốn kém. [Connection pooling](https://en.wikipedia.org/wiki/Connection_pool) giúp giảm, ngoài ra có thể chuyển sang UDP khi phù hợp. + +TCP hữu ích cho ứng dụng cần độ tin cậy cao nhưng ít nhạy thời gian. Ví dụ: web server, dữ liệu cơ sở dữ liệu, SMTP, FTP, SSH. + +Dùng TCP thay vì UDP khi: + +* Bạn cần dữ liệu đến đầy đủ và nguyên vẹn +* Bạn muốn tự động tận dụng thông lượng mạng tốt nhất + +### Giao thức datagram người dùng (UDP) + +

+ +
+ Nguồn: How to make a multiplayer game +

+ +UDP là giao thức không kết nối. Datagram (tương tự gói) chỉ được đảm bảo ở mức datagram. Datagram có thể đến không đúng thứ tự hoặc không đến. UDP không hỗ trợ kiểm soát tắc nghẽn. Không có các đảm bảo như TCP, UDP thường hiệu quả hơn. + +UDP có thể broadcast, gửi datagram tới mọi thiết bị trong subnet. Điều này hữu ích với [DHCP](https://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol) vì client chưa nhận IP, nên không thể stream TCP khi chưa có IP. + +UDP kém tin cậy hơn nhưng hoạt động tốt trong các trường hợp sử dụng thời gian thực như VoIP, video chat, streaming và game nhiều người chơi thời gian thực. + +Dùng UDP thay vì TCP khi: + +* Bạn cần độ trễ thấp nhất +* Dữ liệu đến muộn tệ hơn là mất dữ liệu +* Bạn muốn tự triển khai sửa lỗi + +#### Nguồn và đọc thêm: TCP và UDP + +* [Networking for game programming](https://gafferongames.com/post/udp_vs_tcp/) +* [Khác biệt chính giữa TCP và UDP](http://www.cyberciti.biz/faq/key-differences-between-tcp-and-udp-protocols/) +* [Khác biệt giữa TCP và UDP](http://stackoverflow.com/questions/5970383/difference-between-tcp-and-udp) +* [Transmission control protocol](https://en.wikipedia.org/wiki/Transmission_Control_Protocol) +* [User datagram protocol](https://en.wikipedia.org/wiki/User_Datagram_Protocol) +* [Scaling memcache at Facebook](http://www.cs.bu.edu/~jappavoo/jappavoo.github.com/451/papers/memcache-fb.pdf) + +### Gọi thủ tục từ xa (RPC) + +

+ +
+ Nguồn: Crack the system design interview +

+ +Trong RPC, client khiến một thủ tục được thực thi trên không gian địa chỉ khác, thường là một máy chủ từ xa. Thủ tục được lập trình như thể là lời gọi cục bộ, ẩn đi chi tiết truyền thông với server khỏi chương trình client. Lời gọi từ xa thường chậm và kém tin cậy hơn lời gọi cục bộ nên cần phân biệt RPC với gọi cục bộ. Các framework RPC phổ biến gồm [Protobuf](https://developers.google.com/protocol-buffers/), [Thrift](https://thrift.apache.org/), và [Avro](https://avro.apache.org/docs/current/). + +RPC là giao thức yêu cầu-phản hồi: + +* **Chương trình client** - Gọi thủ tục stub phía client. Tham số được đẩy vào stack như lời gọi cục bộ. +* **Stub phía client** - Marshal (đóng gói) procedure id và tham số thành thông điệp yêu cầu. +* **Module truyền thông phía client** - OS gửi message từ client tới server. +* **Module truyền thông phía server** - OS chuyển gói đến stub phía server. +* **Stub phía server** - Unmarshal kết quả, gọi thủ tục server tương ứng với procedure id và tham số. +* Phản hồi từ server lặp lại các bước trên theo chiều ngược lại. + +Ví dụ lời gọi RPC: + +``` +GET /someoperation?data=anId + +POST /anotheroperation +{ + "data":"anId"; + "anotherdata": "another value" +} +``` + +RPC tập trung vào việc cung cấp hành vi. RPC thường được dùng vì lý do hiệu năng cho giao tiếp nội bộ, vì bạn có thể tùy biến lời gọi native để phù hợp trường hợp sử dụng. + +Chọn thư viện native (SDK) khi: + +* Bạn biết rõ nền tảng mục tiêu. +* Bạn muốn kiểm soát cách "logic" của bạn được truy cập. +* Bạn muốn kiểm soát cách xử lý lỗi bên ngoài thư viện. +* Hiệu năng và trải nghiệm người dùng là ưu tiên hàng đầu. + +HTTP API theo **REST** thường dùng nhiều hơn cho API công khai. + +#### Nhược điểm: RPC + +* Client RPC bị gắn chặt với cách triển khai dịch vụ. +* Cần định nghĩa API mới cho mỗi thao tác hoặc trường hợp sử dụng. +* Khó debug RPC. +* Bạn có thể không tận dụng được công nghệ sẵn có. Ví dụ, có thể cần thêm nỗ lực để đảm bảo [RPC được cache đúng](https://web.archive.org/web/20170608193645/http://etherealbits.com/2012/12/debunking-the-myths-of-rpc-rest/) trên cache server như [Squid](http://www.squid-cache.org/). + +### Chuyển trạng thái biểu diễn (REST) + +REST là một phong cách kiến trúc áp dụng mô hình client/server, trong đó client thao tác trên tập tài nguyên do server quản lý. Server cung cấp biểu diễn tài nguyên và các hành động có thể thao tác hoặc lấy biểu diễn mới. Mọi giao tiếp phải stateless và có thể cache. + +Có bốn đặc tính của giao diện RESTful: + +* **Định danh tài nguyên (URI trong HTTP)** - dùng cùng URI bất kể thao tác nào. +* **Thay đổi bằng biểu diễn (Verb trong HTTP)** - dùng verb, header, và body. +* **Thông điệp lỗi tự mô tả (trạng thái phản hồi trong HTTP)** - dùng status code, đừng phát minh lại. +* **[HATEOAS](http://restcookbook.com/Basics/hateoas/) (giao diện HTML cho HTTP)** - dịch vụ web của bạn nên truy cập đầy đủ trong trình duyệt. + +Ví dụ lời gọi REST: + +``` +GET /someresources/anId + +PUT /someresources/anId +{"anotherdata": "another value"} +``` + +REST tập trung vào việc cung cấp dữ liệu. Nó giảm độ gắn kết giữa client/server và thường dùng cho API HTTP công khai. REST dùng phương thức tổng quát và đồng nhất để lộ tài nguyên qua URI, [biểu diễn qua header](https://github.com/for-GET/know-your-http-well/blob/master/headers.md), và hành động qua các verb như GET, POST, PUT, DELETE, PATCH. Vì stateless, REST rất tốt cho mở rộng ngang và phân vùng. + +#### Nhược điểm: REST + +* Vì REST tập trung vào dữ liệu, nó có thể không phù hợp nếu tài nguyên không được tổ chức tự nhiên hoặc truy cập theo cấu trúc đơn giản. Ví dụ, trả về tất cả bản ghi cập nhật trong giờ qua khớp một tập sự kiện cụ thể không dễ biểu diễn thành một path. Với REST, thường phải kết hợp path URI, query parameters và có thể cả phần thân yêu cầu. +* REST thường dựa vào một vài verb (GET, POST, PUT, DELETE, PATCH), đôi khi không phù hợp trường hợp sử dụng. Ví dụ, chuyển tài liệu hết hạn sang thư mục lưu trữ không dễ "khớp" vào các verb này. +* Lấy tài nguyên phức tạp với phân cấp lồng nhau cần nhiều vòng gọi giữa client và server để render một view, ví dụ lấy nội dung bài blog và các bình luận. Với ứng dụng di động trong điều kiện mạng thay đổi, các vòng gọi này rất không mong muốn. +* Theo thời gian, nhiều trường có thể được thêm vào phản hồi API và client cũ sẽ nhận tất cả trường mới, kể cả những trường không cần, làm phình nội dung tải (payload) và tăng độ trễ. + +### So sánh gọi RPC và REST + +| Thao tác | RPC | REST | +|---|---|---| +| Đăng ký | **POST** /signup | **POST** /persons | +| Hủy đăng ký | **POST** /resign
{
"personid": "1234"
} | **DELETE** /persons/1234 | +| Đọc một người | **GET** /readPerson?personid=1234 | **GET** /persons/1234 | +| Đọc danh sách vật phẩm của người | **GET** /readUsersItemsList?personid=1234 | **GET** /persons/1234/items | +| Thêm vật phẩm cho người | **POST** /addItemToUsersItemsList
{
"personid": "1234";
"itemid": "456"
} | **POST** /persons/1234/items
{
"itemid": "456"
} | +| Cập nhật vật phẩm | **POST** /modifyItem
{
"itemid": "456";
"key": "value"
} | **PUT** /items/456
{
"key": "value"
} | +| Xóa vật phẩm | **POST** /removeItem
{
"itemid": "456"
} | **DELETE** /items/456 | + +

+ Nguồn: Do you really know why you prefer REST over RPC +

+ +#### Nguồn và đọc thêm: REST và RPC + +* [Do you really know why you prefer REST over RPC](https://apihandyman.io/do-you-really-know-why-you-prefer-rest-over-rpc/) +* [Khi nào approach kiểu RPC phù hợp hơn REST?](http://programmers.stackexchange.com/a/181186) +* [REST vs JSON-RPC](http://stackoverflow.com/questions/15056878/rest-vs-json-rpc) +* [Debunking the myths of RPC and REST](https://web.archive.org/web/20170608193645/http://etherealbits.com/2012/12/debunking-the-myths-of-rpc-rest/) +* [Nhược điểm khi dùng REST](https://www.quora.com/What-are-the-drawbacks-of-using-RESTful-APIs) +* [Crack the system design interview](http://www.puncsky.com/blog/2016-02-13-crack-the-system-design-interview) +* [Thrift](https://code.facebook.com/posts/1468950976659943/) +* [Vì sao nội bộ dùng REST chứ không phải RPC](http://arstechnica.com/civis/viewtopic.php?t=1190508) + +## Bảo mật + +Phần này cần cập nhật thêm. Hãy cân nhắc [đóng góp](#đóng-góp)! + +Bảo mật là một chủ đề rộng. Trừ khi bạn có nhiều kinh nghiệm, nền tảng bảo mật, hoặc ứng tuyển vị trí yêu cầu hiểu biết bảo mật, bạn có thể không cần biết hơn những điều cơ bản: + +* Mã hóa khi truyền và khi lưu. +* Làm sạch mọi đầu vào người dùng hoặc tham số đầu vào lộ ra cho người dùng để tránh [XSS](https://en.wikipedia.org/wiki/Cross-site_scripting) và [SQL injection](https://en.wikipedia.org/wiki/SQL_injection). +* Dùng truy vấn tham số hóa để tránh SQL injection. +* Dùng nguyên tắc [least privilege](https://en.wikipedia.org/wiki/Principle_of_least_privilege). + +### Nguồn và đọc thêm + +* [API security checklist](https://github.com/shieldfy/API-Security-Checklist) +* [Security guide for developers](https://github.com/FallibleInc/security-guide-for-developers) +* [OWASP top ten](https://www.owasp.org/index.php/OWASP_Top_Ten_Cheat_Sheet) + +## Phụ lục + +Đôi khi bạn sẽ được hỏi ước lượng "back-of-the-envelope". Ví dụ, bạn có thể cần xác định mất bao lâu để tạo 100 thumbnail từ đĩa hoặc một cấu trúc dữ liệu chiếm bao nhiêu bộ nhớ. **Bảng lũy thừa của 2** và **các con số độ trễ mà lập trình viên nên biết** là các tài liệu tham khảo hữu ích. + +### Bảng lũy thừa của 2 + +``` +Lũy thừa Giá trị chính xác Giá trị xấp xỉ Bytes +--------------------------------------------------------------- +7 128 +8 256 +10 1024 1 nghìn 1 KB +16 65,536 64 KB +20 1,048,576 1 triệu 1 MB +30 1,073,741,824 1 tỷ 1 GB +32 4,294,967,296 4 GB +40 1,099,511,627,776 1 nghìn tỷ 1 TB +``` + +#### Nguồn và đọc thêm + +* [Lũy thừa của 2](https://en.wikipedia.org/wiki/Power_of_two) + +### Các con số độ trễ mà lập trình viên nên biết + +``` +Các con số so sánh độ trễ +------------------------- +Tham chiếu cache L1 0.5 ns +Sai dự đoán nhánh 5 ns +Tham chiếu cache L2 7 ns 14x cache L1 +Khóa/mở khóa mutex 25 ns +Tham chiếu bộ nhớ chính 100 ns 20x cache L2, 200x cache L1 +Nén 1K bytes bằng Zippy 10,000 ns 10 us +Gửi 1 KB bytes qua mạng 1 Gbps 10,000 ns 10 us +Đọc ngẫu nhiên 4 KB từ SSD* 150,000 ns 150 us ~1GB/sec SSD +Đọc tuần tự 1 MB từ bộ nhớ 250,000 ns 250 us +Vòng khứ hồi trong cùng datacenter 500,000 ns 500 us +Đọc tuần tự 1 MB từ SSD* 1,000,000 ns 1,000 us 1 ms ~1GB/sec SSD, 4X bộ nhớ +Seek HDD 10,000,000 ns 10,000 us 10 ms 20x vòng khứ hồi datacenter +Đọc tuần tự 1 MB từ 1 Gbps 10,000,000 ns 10,000 us 10 ms 40x bộ nhớ, 10X SSD +Đọc tuần tự 1 MB từ HDD 30,000,000 ns 30,000 us 30 ms 120x bộ nhớ, 30X SSD +Gửi gói CA->Hà Lan->CA 150,000,000 ns 150,000 us 150 ms + +Ghi chú +------ +1 ns = 10^-9 giây +1 us = 10^-6 giây = 1,000 ns +1 ms = 10^-3 giây = 1,000 us = 1,000,000 ns +``` + +Các chỉ số hữu ích dựa trên số liệu trên: + +* Đọc tuần tự từ HDD ở 30 MB/s +* Đọc tuần tự từ Ethernet 1 Gbps ở 100 MB/s +* Đọc tuần tự từ SSD ở 1 GB/s +* Đọc tuần tự từ bộ nhớ chính ở 4 GB/s +* 6-7 vòng khứ hồi toàn cầu mỗi giây +* 2,000 vòng khứ hồi mỗi giây trong một trung tâm dữ liệu + +#### Minh họa số liệu độ trễ + +![](https://camo.githubusercontent.com/77f72259e1eb58596b564d1ad823af1853bc60a3/687474703a2f2f692e696d6775722e636f6d2f6b307431652e706e67) + +#### Nguồn và đọc thêm + +* [Các con số độ trễ mà lập trình viên nên biết - 1](https://gist.github.com/jboner/2841832) +* [Các con số độ trễ mà lập trình viên nên biết - 2](https://gist.github.com/hellerbarde/2843375) +* [Designs, lessons, and advice from building large distributed systems](http://www.cs.cornell.edu/projects/ladis2009/talks/dean-keynote-ladis2009.pdf) +* [Software Engineering Advice from Building Large-Scale Distributed Systems](https://static.googleusercontent.com/media/research.google.com/en//people/jeff/stanford-295-talk.pdf) + +### Câu hỏi phỏng vấn thiết kế hệ thống bổ sung + +> Các câu hỏi phỏng vấn thiết kế hệ thống thường gặp, kèm liên kết tới tài nguyên giải. + +| Câu hỏi | Tham khảo | +|---|---| +| Thiết kế dịch vụ đồng bộ tệp như Dropbox | [youtube.com](https://www.youtube.com/watch?v=PE4gwstWhmc) | +| Thiết kế công cụ tìm kiếm như Google | [queue.acm.org](http://queue.acm.org/detail.cfm?id=988407)
[stackexchange.com](http://programmers.stackexchange.com/questions/38324/interview-question-how-would-you-implement-google-search)
[ardendertat.com](http://www.ardendertat.com/2012/01/11/implementing-search-engines/)
[stanford.edu](http://infolab.stanford.edu/~backrub/google.html) | +| Thiết kế web crawler mở rộng như Google | [quora.com](https://www.quora.com/How-can-I-build-a-web-crawler-from-scratch) | +| Thiết kế Google Docs | [code.google.com](https://code.google.com/p/google-mobwrite/)
[neil.fraser.name](https://neil.fraser.name/writing/sync/) | +| Thiết kế kho khóa-giá trị như Redis | [codecapsule.com](http://codecapsule.com/2012/11/07/ikvs-implementing-a-key-value-store-table-of-contents/)
[allthingsdistributed.com](https://www.allthingsdistributed.com/files/amazon-dynamo-sosp2007.pdf) | +| Thiết kế hệ thống cache như Memcached | [slideshare.net](http://www.slideshare.net/oemebamo/introduction-to-memcached) | +| Thiết kế hệ thống gợi ý như Amazon | [hulu.com](https://web.archive.org/web/20170406065247/http://tech.hulu.com/blog/2011/09/19/recommendation-system.html)
[ijcai13.org](http://ijcai13.org/files/tutorial_slides/td3.pdf) | +| Thiết kế hệ thống tinyurl như Bitly | [n00tc0d3r.blogspot.com](http://n00tc0d3r.blogspot.com/) | +| Thiết kế ứng dụng chat như WhatsApp | [highscalability.com](http://highscalability.com/blog/2014/2/26/the-whatsapp-architecture-facebook-bought-for-19-billion.html) +| Thiết kế hệ thống chia sẻ ảnh như Instagram | [highscalability.com](http://highscalability.com/flickr-architecture)
[highscalability.com](http://highscalability.com/blog/2011/12/6/instagram-architecture-14-million-users-terabytes-of-photos.html) | +| Thiết kế chức năng news feed của Facebook | [quora.com](http://www.quora.com/What-are-best-practices-for-building-something-like-a-News-Feed)
[quora.com](http://www.quora.com/Activity-Streams/What-are-the-scaling-issues-to-keep-in-mind-while-developing-a-social-network-feed)
[slideshare.net](http://www.slideshare.net/danmckinley/etsy-activity-feeds-architecture) | +| Thiết kế chức năng timeline của Facebook | [facebook.com](https://www.facebook.com/note.php?note_id=10150468255628920)
[highscalability.com](http://highscalability.com/blog/2012/1/23/facebook-timeline-brought-to-you-by-the-power-of-denormaliza.html) | +| Thiết kế chức năng chat của Facebook | [erlang-factory.com](http://www.erlang-factory.com/upload/presentations/31/EugeneLetuchy-ErlangatFacebook.pdf)
[facebook.com](https://www.facebook.com/note.php?note_id=14218138919&id=9445547199&index=0) | +| Thiết kế chức năng tìm kiếm đồ thị như Facebook | [facebook.com](https://www.facebook.com/notes/facebook-engineering/under-the-hood-building-out-the-infrastructure-for-graph-search/10151347573598920)
[facebook.com](https://www.facebook.com/notes/facebook-engineering/under-the-hood-indexing-and-ranking-in-graph-search/10151361720763920)
[facebook.com](https://www.facebook.com/notes/facebook-engineering/under-the-hood-the-natural-language-interface-of-graph-search/10151432733048920) | +| Thiết kế CDN như CloudFlare | [figshare.com](https://figshare.com/articles/Globally_distributed_content_delivery/6605972) | +| Thiết kế hệ thống chủ đề nóng như Twitter | [michael-noll.com](http://www.michael-noll.com/blog/2013/01/18/implementing-real-time-trending-topics-in-storm/)
[snikolov .wordpress.com](http://snikolov.wordpress.com/2012/11/14/early-detection-of-twitter-trends/) | +| Thiết kế hệ thống sinh ID ngẫu nhiên | [blog.twitter.com](https://blog.twitter.com/2010/announcing-snowflake)
[github.com](https://github.com/twitter/snowflake/) | +| Trả về top k yêu cầu trong một khoảng thời gian | [cs.ucsb.edu](https://www.cs.ucsb.edu/sites/default/files/documents/2005-23.pdf)
[wpi.edu](http://davis.wpi.edu/xmdv/docs/EDBT11-diyang.pdf) | +| Thiết kế hệ thống phục vụ dữ liệu từ nhiều trung tâm dữ liệu | [highscalability.com](http://highscalability.com/blog/2009/8/24/how-google-serves-data-from-multiple-datacenters.html) | +| Thiết kế game bài nhiều người chơi trực tuyến | [indieflashblog.com](https://web.archive.org/web/20180929181117/http://www.indieflashblog.com/how-to-create-an-asynchronous-multiplayer-game.html)
[buildnewgames.com](http://buildnewgames.com/real-time-multiplayer/) | +| Thiết kế hệ thống garbage collection | [stuffwithstuff.com](http://journal.stuffwithstuff.com/2013/12/08/babys-first-garbage-collector/)
[washington.edu](http://courses.cs.washington.edu/courses/csep521/07wi/prj/rick.pdf) | +| Thiết kế API rate limiter | [https://stripe.com/blog/](https://stripe.com/blog/rate-limiters) | +| Thiết kế sàn giao dịch (như NASDAQ hoặc Binance) | [Jane Street](https://youtu.be/b1e4t2k2KJY)
[Golang Implementation](https://around25.com/blog/building-a-trading-engine-for-a-crypto-exchange/)
[Go Implementation](http://bhomnick.net/building-a-simple-limit-order-in-go/) | +| Thêm câu hỏi thiết kế hệ thống | [Đóng góp](#đóng-góp) | + +### Kiến trúc thực tế + +> Các bài viết về cách hệ thống thực tế được thiết kế. + +

+ +
+ Nguồn: Twitter timelines at scale +

+ +**Đừng sa đà vào chi tiết vụn vặt cho các bài viết sau, thay vào đó:** + +* Nhận diện các nguyên tắc chung, công nghệ chung, và mẫu hình trong các bài viết +* Xem mỗi thành phần giải quyết vấn đề gì, hoạt động ở đâu, không hoạt động ở đâu +* Ôn lại các bài học rút ra + +|Loại | Hệ thống | Tham khảo | +|---|---|---| +| Xử lý dữ liệu | **MapReduce** - Xử lý dữ liệu phân tán từ Google | [research.google.com](http://static.googleusercontent.com/media/research.google.com/zh-CN/us/archive/mapreduce-osdi04.pdf) | +| Xử lý dữ liệu | **Spark** - Xử lý dữ liệu phân tán từ Databricks | [slideshare.net](http://www.slideshare.net/AGrishchenko/apache-spark-architecture) | +| Xử lý dữ liệu | **Storm** - Xử lý dữ liệu phân tán từ Twitter | [slideshare.net](http://www.slideshare.net/previa/storm-16094009) | +| | | | +| Kho dữ liệu | **Bigtable** - CSDL cột phân tán từ Google | [harvard.edu](http://www.read.seas.harvard.edu/~kohler/class/cs239-w08/chang06bigtable.pdf) | +| Kho dữ liệu | **HBase** - Bản triển khai Bigtable mã nguồn mở | [slideshare.net](http://www.slideshare.net/alexbaranau/intro-to-hbase) | +| Kho dữ liệu | **Cassandra** - CSDL cột phân tán từ Facebook | [slideshare.net](http://www.slideshare.net/planetcassandra/cassandra-introduction-features-30103666) +| Kho dữ liệu | **DynamoDB** - CSDL hướng tài liệu từ Amazon | [harvard.edu](http://www.read.seas.harvard.edu/~kohler/class/cs239-w08/decandia07dynamo.pdf) | +| Kho dữ liệu | **MongoDB** - CSDL hướng tài liệu | [slideshare.net](http://www.slideshare.net/mdirolf/introduction-to-mongodb) | +| Kho dữ liệu | **Spanner** - CSDL phân tán toàn cầu từ Google | [research.google.com](http://research.google.com/archive/spanner-osdi2012.pdf) | +| Kho dữ liệu | **Memcached** - Hệ thống cache bộ nhớ phân tán | [slideshare.net](http://www.slideshare.net/oemebamo/introduction-to-memcached) | +| Kho dữ liệu | **Redis** - Hệ thống cache bộ nhớ phân tán với lưu bền và kiểu dữ liệu | [slideshare.net](http://www.slideshare.net/dvirsky/introduction-to-redis) | +| | | | +| Hệ thống tệp | **Google File System (GFS)** - Hệ thống tệp phân tán | [research.google.com](http://static.googleusercontent.com/media/research.google.com/zh-CN/us/archive/gfs-sosp2003.pdf) | +| Hệ thống tệp | **Hadoop File System (HDFS)** - Bản triển khai GFS mã nguồn mở | [apache.org](http://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HdfsDesign.html) | +| | | | +| Khác | **Chubby** - Dịch vụ lock cho hệ thống phân tán liên kết lỏng từ Google | [research.google.com](http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/en/us/archive/chubby-osdi06.pdf) | +| Khác | **Dapper** - Hạ tầng theo vết hệ thống phân tán | [research.google.com](http://static.googleusercontent.com/media/research.google.com/en//pubs/archive/36356.pdf) +| Khác | **Kafka** - Hàng đợi thông điệp pub/sub từ LinkedIn | [slideshare.net](http://www.slideshare.net/mumrah/kafka-talk-tri-hug) | +| Khác | **Zookeeper** - Hạ tầng tập trung và dịch vụ đồng bộ | [slideshare.net](http://www.slideshare.net/sauravhaloi/introduction-to-apache-zookeeper) | +| | Thêm kiến trúc | [Đóng góp](#đóng-góp) | + +### Kiến trúc công ty + +| Công ty | Tham khảo | +|---|---| +| Amazon | [Amazon architecture](http://highscalability.com/amazon-architecture) | +| Cinchcast | [Sản xuất 1,500 giờ audio mỗi ngày](http://highscalability.com/blog/2012/7/16/cinchcast-architecture-producing-1500-hours-of-audio-every-d.html) | +| DataSift | [Realtime datamining ở 120,000 tweet/giây](http://highscalability.com/blog/2011/11/29/datasift-architecture-realtime-datamining-at-120000-tweets-p.html) | +| Dropbox | [Cách Dropbox mở rộng](https://www.youtube.com/watch?v=PE4gwstWhmc) | +| ESPN | [Vận hành 100,000 "duh nuh nuhs" mỗi giây](http://highscalability.com/blog/2013/11/4/espns-architecture-at-scale-operating-at-100000-duh-nuh-nuhs.html) | +| Google | [Google architecture](http://highscalability.com/google-architecture) | +| Instagram | [14 triệu người dùng, terabytes ảnh](http://highscalability.com/blog/2011/12/6/instagram-architecture-14-million-users-terabytes-of-photos.html)
[Instagram hoạt động nhờ gì](http://instagram-engineering.tumblr.com/post/13649370142/what-powers-instagram-hundreds-of-instances) | +| Justin.tv | [Kiến trúc phát trực tiếp của Justin.tv](http://highscalability.com/blog/2010/3/16/justintvs-live-video-broadcasting-architecture.html) | +| Facebook | [Scaling memcached at Facebook](https://cs.uwaterloo.ca/~brecht/courses/854-Emerging-2014/readings/key-value/fb-memcached-nsdi-2013.pdf)
[TAO: Facebook’s distributed data store for the social graph](https://cs.uwaterloo.ca/~brecht/courses/854-Emerging-2014/readings/data-store/tao-facebook-distributed-datastore-atc-2013.pdf)
[Facebook’s photo storage](https://www.usenix.org/legacy/event/osdi10/tech/full_papers/Beaver.pdf)
[How Facebook Live Streams To 800,000 Simultaneous Viewers](http://highscalability.com/blog/2016/6/27/how-facebook-live-streams-to-800000-simultaneous-viewers.html) | +| Flickr | [Flickr architecture](http://highscalability.com/flickr-architecture) | +| Mailbox | [Từ 0 đến một triệu người dùng trong 6 tuần](http://highscalability.com/blog/2013/6/18/scaling-mailbox-from-0-to-one-million-users-in-6-weeks-and-1.html) | +| Netflix | [Góc nhìn 360 độ về toàn bộ stack Netflix](http://highscalability.com/blog/2015/11/9/a-360-degree-view-of-the-entire-netflix-stack.html)
[Netflix: Điều gì xảy ra khi bạn bấm Play?](http://highscalability.com/blog/2017/12/11/netflix-what-happens-when-you-press-play.html) | +| Pinterest | [Từ 0 đến hàng chục tỷ lượt xem mỗi tháng](http://highscalability.com/blog/2013/4/15/scaling-pinterest-from-0-to-10s-of-billions-of-page-views-a.html)
[18 triệu lượt truy cập, tăng trưởng 10x, 12 nhân sự](http://highscalability.com/blog/2012/5/21/pinterest-architecture-update-18-million-visitors-10x-growth.html) | +| Playfish | [50 triệu người dùng mỗi tháng và tăng trưởng](http://highscalability.com/blog/2010/9/21/playfishs-social-gaming-architecture-50-million-monthly-user.html) | +| PlentyOfFish | [PlentyOfFish architecture](http://highscalability.com/plentyoffish-architecture) | +| Salesforce | [Cách họ xử lý 1.3 tỷ giao dịch mỗi ngày](http://highscalability.com/blog/2013/9/23/salesforce-architecture-how-they-handle-13-billion-transacti.html) | +| Stack Overflow | [Stack Overflow architecture](http://highscalability.com/blog/2009/8/5/stack-overflow-architecture.html) | +| TripAdvisor | [40M visitors, 200M dynamic page views, 30TB data](http://highscalability.com/blog/2011/6/27/tripadvisor-architecture-40m-visitors-200m-dynamic-page-view.html) | +| Tumblr | [15 tỷ lượt xem mỗi tháng](http://highscalability.com/blog/2012/2/13/tumblr-architecture-15-billion-page-views-a-month-and-harder.html) | +| Twitter | [Làm Twitter nhanh hơn 10,000%](http://highscalability.com/scaling-twitter-making-twitter-10000-percent-faster)
[Lưu 250 triệu tweet/ngày bằng MySQL](http://highscalability.com/blog/2011/12/19/how-twitter-stores-250-million-tweets-a-day-using-mysql.html)
[150M người dùng hoạt động, 300K QPS, "firehose" 22 MB/S](http://highscalability.com/blog/2013/7/8/the-architecture-twitter-uses-to-deal-with-150m-active-users.html)
[Timelines at scale](https://www.infoq.com/presentations/Twitter-Timeline-Scalability)
[Big and small data at Twitter](https://www.youtube.com/watch?v=5cKTP36HVgI)
[Operations at Twitter: scaling beyond 100 million users](https://www.youtube.com/watch?v=z8LU0Cj6BOU)
[How Twitter Handles 3,000 Images Per Second](http://highscalability.com/blog/2016/4/20/how-twitter-handles-3000-images-per-second.html) | +| Uber | [Cách Uber mở rộng nền tảng thị trường thời gian thực](http://highscalability.com/blog/2015/9/14/how-uber-scales-their-real-time-market-platform.html)
[Bài học khi mở rộng Uber tới 2000 kỹ sư, 1000 dịch vụ, 8000 repo Git](http://highscalability.com/blog/2016/10/12/lessons-learned-from-scaling-uber-to-2000-engineers-1000-ser.html) | +| WhatsApp | [Kiến trúc WhatsApp Facebook mua với 19 tỷ USD](http://highscalability.com/blog/2014/2/26/the-whatsapp-architecture-facebook-bought-for-19-billion.html) | +| YouTube | [Khả năng mở rộng của YouTube](https://www.youtube.com/watch?v=w5WVu624fY8)
[YouTube architecture](http://highscalability.com/youtube-architecture) | + +### Blog kỹ thuật của công ty + +> Kiến trúc của các công ty bạn đang phỏng vấn. +> +> Các câu hỏi bạn gặp có thể thuộc cùng miền này. + +* [Airbnb Engineering](http://nerds.airbnb.com/) +* [Atlassian Developers](https://developer.atlassian.com/blog/) +* [AWS Blog](https://aws.amazon.com/blogs/aws/) +* [Bitly Engineering Blog](http://word.bitly.com/) +* [Box Blogs](https://blog.box.com/blog/category/engineering) +* [Cloudera Developer Blog](http://blog.cloudera.com/) +* [Dropbox Tech Blog](https://tech.dropbox.com/) +* [Engineering at Quora](https://www.quora.com/q/quoraengineering) +* [Ebay Tech Blog](http://www.ebaytechblog.com/) +* [Evernote Tech Blog](https://blog.evernote.com/tech/) +* [Etsy Code as Craft](http://codeascraft.com/) +* [Facebook Engineering](https://www.facebook.com/Engineering) +* [Flickr Code](http://code.flickr.net/) +* [Foursquare Engineering Blog](http://engineering.foursquare.com/) +* [GitHub Engineering Blog](https://github.blog/category/engineering) +* [Google Research Blog](http://googleresearch.blogspot.com/) +* [Groupon Engineering Blog](https://engineering.groupon.com/) +* [Heroku Engineering Blog](https://engineering.heroku.com/) +* [Hubspot Engineering Blog](http://product.hubspot.com/blog/topic/engineering) +* [High Scalability](http://highscalability.com/) +* [Instagram Engineering](http://instagram-engineering.tumblr.com/) +* [Intel Software Blog](https://software.intel.com/en-us/blogs/) +* [Jane Street Tech Blog](https://blogs.janestreet.com/category/ocaml/) +* [LinkedIn Engineering](http://engineering.linkedin.com/blog) +* [Microsoft Engineering](https://engineering.microsoft.com/) +* [Microsoft Python Engineering](https://blogs.msdn.microsoft.com/pythonengineering/) +* [Netflix Tech Blog](http://techblog.netflix.com/) +* [Paypal Developer Blog](https://developer.paypal.com/community/blog/) +* [Pinterest Engineering Blog](https://medium.com/@Pinterest_Engineering) +* [Reddit Blog](http://www.redditblog.com/) +* [Salesforce Engineering Blog](https://developer.salesforce.com/blogs/engineering/) +* [Slack Engineering Blog](https://slack.engineering/) +* [Spotify Labs](https://labs.spotify.com/) +* [Stripe Engineering Blog](https://stripe.com/blog/engineering) +* [Twilio Engineering Blog](http://www.twilio.com/engineering) +* [Twitter Engineering](https://blog.twitter.com/engineering/) +* [Uber Engineering Blog](http://eng.uber.com/) +* [Yahoo Engineering Blog](http://yahooeng.tumblr.com/) +* [Yelp Engineering Blog](http://engineeringblog.yelp.com/) +* [Zynga Engineering Blog](https://www.zynga.com/blogs/engineering) + +#### Nguồn và đọc thêm + +Muốn thêm blog? Để tránh làm trùng, hãy cân nhắc thêm blog công ty bạn vào repo sau: + +* [kilimchoi/engineering-blogs](https://github.com/kilimchoi/engineering-blogs) + +## Đang phát triển + +Bạn muốn thêm một phần hoặc giúp hoàn thành phần đang làm? [Đóng góp](#đóng-góp)! + +* Điện toán phân tán với MapReduce +* Consistent hashing +* Scatter gather +* [Đóng góp](#đóng-góp) + +## Ghi công + +Các nguồn và ghi công được nêu xuyên suốt repo. + +Đặc biệt cảm ơn: + +* [Hired in tech](http://www.hiredintech.com/system-design/the-system-design-process/) +* [Cracking the coding interview](https://www.amazon.com/dp/0984782850/) +* [High scalability](http://highscalability.com/) +* [checkcheckzz/system-design-interview](https://github.com/checkcheckzz/system-design-interview) +* [shashank88/system_design](https://github.com/shashank88/system_design) +* [mmcgrana/services-engineering](https://github.com/mmcgrana/services-engineering) +* [System design cheat sheet](https://gist.github.com/vasanthk/485d1c25737e8e72759f) +* [A distributed systems reading list](http://dancres.github.io/Pages/) +* [Cracking the system design interview](http://www.puncsky.com/blog/2016-02-13-crack-the-system-design-interview) + +## Thông tin liên hệ + +Hãy liên hệ tôi để thảo luận về các vấn đề, câu hỏi hoặc góp ý. + +Thông tin liên hệ của tôi có trên [trang GitHub](https://github.com/donnemartin). + +## Giấy phép + +*Tôi cung cấp mã và tài nguyên trong repo này cho bạn theo giấy phép mã nguồn mở. Vì đây là repo cá nhân, giấy phép bạn nhận được cho mã và tài nguyên là từ tôi chứ không phải từ công ty tôi (Facebook).* + + Copyright 2017 Donne Martin + + Creative Commons Attribution 4.0 International License (CC BY 4.0) + + http://creativecommons.org/licenses/by/4.0/ diff --git a/README-zh-Hans.md b/README-zh-Hans.md index 474fb4251a..b866f1a715 100644 --- a/README-zh-Hans.md +++ b/README-zh-Hans.md @@ -3,7 +3,7 @@ > * 译者:[XatMassacrE](https://github.com/XatMassacrE)、[L9m](https://github.com/L9m)、[Airmacho](https://github.com/Airmacho)、[xiaoyusilen](https://github.com/xiaoyusilen)、[jifaxu](https://github.com/jifaxu)、[根号三](https://github.com/sqrthree) > * 这个 [链接](https://github.com/xitu/system-design-primer/compare/master...donnemartin:master) 用来查看本翻译与英文版是否有差别(如果你没有看到 README.md 发生变化,那就意味着这份翻译文档是最新的)。 -*[English](README.md) ∙ [日本語](README-ja.md) ∙ [简体中文](README-zh-Hans.md) ∙ [繁體中文](README-zh-TW.md) | [العَرَبِيَّة‎](https://github.com/donnemartin/system-design-primer/issues/170) ∙ [বাংলা](https://github.com/donnemartin/system-design-primer/issues/220) ∙ [Português do Brasil](https://github.com/donnemartin/system-design-primer/issues/40) ∙ [Deutsch](https://github.com/donnemartin/system-design-primer/issues/186) ∙ [ελληνικά](https://github.com/donnemartin/system-design-primer/issues/130) ∙ [עברית](https://github.com/donnemartin/system-design-primer/issues/272) ∙ [Italiano](https://github.com/donnemartin/system-design-primer/issues/104) ∙ [한국어](https://github.com/donnemartin/system-design-primer/issues/102) ∙ [فارسی](https://github.com/donnemartin/system-design-primer/issues/110) ∙ [Polski](https://github.com/donnemartin/system-design-primer/issues/68) ∙ [русский язык](https://github.com/donnemartin/system-design-primer/issues/87) ∙ [Español](https://github.com/donnemartin/system-design-primer/issues/136) ∙ [ภาษาไทย](https://github.com/donnemartin/system-design-primer/issues/187) ∙ [Türkçe](https://github.com/donnemartin/system-design-primer/issues/39) ∙ [tiếng Việt](https://github.com/donnemartin/system-design-primer/issues/127) ∙ [Français](https://github.com/donnemartin/system-design-primer/issues/250) | [Add Translation](https://github.com/donnemartin/system-design-primer/issues/28)* +*[English](README.md) ∙ [日本語](README-ja.md) ∙ [简体中文](README-zh-Hans.md) ∙ [繁體中文](README-zh-TW.md) | [العَرَبِيَّة‎](https://github.com/donnemartin/system-design-primer/issues/170) ∙ [বাংলা](https://github.com/donnemartin/system-design-primer/issues/220) ∙ [Português do Brasil](https://github.com/donnemartin/system-design-primer/issues/40) ∙ [Deutsch](https://github.com/donnemartin/system-design-primer/issues/186) ∙ [ελληνικά](https://github.com/donnemartin/system-design-primer/issues/130) ∙ [עברית](https://github.com/donnemartin/system-design-primer/issues/272) ∙ [Italiano](https://github.com/donnemartin/system-design-primer/issues/104) ∙ [한국어](https://github.com/donnemartin/system-design-primer/issues/102) ∙ [فارسی](https://github.com/donnemartin/system-design-primer/issues/110) ∙ [Polski](https://github.com/donnemartin/system-design-primer/issues/68) ∙ [русский язык](https://github.com/donnemartin/system-design-primer/issues/87) ∙ [Español](https://github.com/donnemartin/system-design-primer/issues/136) ∙ [ภาษาไทย](https://github.com/donnemartin/system-design-primer/issues/187) ∙ [Türkçe](https://github.com/donnemartin/system-design-primer/issues/39) ∙ [tiếng Việt](README-vi.md) ∙ [Français](https://github.com/donnemartin/system-design-primer/issues/250) | [Add Translation](https://github.com/donnemartin/system-design-primer/issues/28)* # 系统设计入门 diff --git a/README-zh-TW.md b/README-zh-TW.md index b51b0e7be7..cf4784523e 100644 --- a/README-zh-TW.md +++ b/README-zh-TW.md @@ -1,4 +1,4 @@ -*[English](README.md) ∙ [日本語](README-ja.md) ∙ [简体中文](README-zh-Hans.md) ∙ [繁體中文](README-zh-TW.md) | [العَرَبِيَّة‎](https://github.com/donnemartin/system-design-primer/issues/170) ∙ [বাংলা](https://github.com/donnemartin/system-design-primer/issues/220) ∙ [Português do Brasil](https://github.com/donnemartin/system-design-primer/issues/40) ∙ [Deutsch](https://github.com/donnemartin/system-design-primer/issues/186) ∙ [ελληνικά](https://github.com/donnemartin/system-design-primer/issues/130) ∙ [עברית](https://github.com/donnemartin/system-design-primer/issues/272) ∙ [Italiano](https://github.com/donnemartin/system-design-primer/issues/104) ∙ [한국어](https://github.com/donnemartin/system-design-primer/issues/102) ∙ [فارسی](https://github.com/donnemartin/system-design-primer/issues/110) ∙ [Polski](https://github.com/donnemartin/system-design-primer/issues/68) ∙ [русский язык](https://github.com/donnemartin/system-design-primer/issues/87) ∙ [Español](https://github.com/donnemartin/system-design-primer/issues/136) ∙ [ภาษาไทย](https://github.com/donnemartin/system-design-primer/issues/187) ∙ [Türkçe](https://github.com/donnemartin/system-design-primer/issues/39) ∙ [tiếng Việt](https://github.com/donnemartin/system-design-primer/issues/127) ∙ [Français](https://github.com/donnemartin/system-design-primer/issues/250) | [Add Translation](https://github.com/donnemartin/system-design-primer/issues/28)* +*[English](README.md) ∙ [日本語](README-ja.md) ∙ [简体中文](README-zh-Hans.md) ∙ [繁體中文](README-zh-TW.md) | [العَرَبِيَّة‎](https://github.com/donnemartin/system-design-primer/issues/170) ∙ [বাংলা](https://github.com/donnemartin/system-design-primer/issues/220) ∙ [Português do Brasil](https://github.com/donnemartin/system-design-primer/issues/40) ∙ [Deutsch](https://github.com/donnemartin/system-design-primer/issues/186) ∙ [ελληνικά](https://github.com/donnemartin/system-design-primer/issues/130) ∙ [עברית](https://github.com/donnemartin/system-design-primer/issues/272) ∙ [Italiano](https://github.com/donnemartin/system-design-primer/issues/104) ∙ [한국어](https://github.com/donnemartin/system-design-primer/issues/102) ∙ [فارسی](https://github.com/donnemartin/system-design-primer/issues/110) ∙ [Polski](https://github.com/donnemartin/system-design-primer/issues/68) ∙ [русский язык](https://github.com/donnemartin/system-design-primer/issues/87) ∙ [Español](https://github.com/donnemartin/system-design-primer/issues/136) ∙ [ภาษาไทย](https://github.com/donnemartin/system-design-primer/issues/187) ∙ [Türkçe](https://github.com/donnemartin/system-design-primer/issues/39) ∙ [tiếng Việt](README-vi.md) ∙ [Français](https://github.com/donnemartin/system-design-primer/issues/250) | [Add Translation](https://github.com/donnemartin/system-design-primer/issues/28)* # 系統設計入門 diff --git a/README.md b/README.md index 9e2cdb88de..f9a6344326 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -*[English](README.md) ∙ [日本語](README-ja.md) ∙ [简体中文](README-zh-Hans.md) ∙ [繁體中文](README-zh-TW.md) | [العَرَبِيَّة‎](https://github.com/donnemartin/system-design-primer/issues/170) ∙ [বাংলা](https://github.com/donnemartin/system-design-primer/issues/220) ∙ [Português do Brasil](https://github.com/donnemartin/system-design-primer/issues/40) ∙ [Deutsch](https://github.com/donnemartin/system-design-primer/issues/186) ∙ [ελληνικά](https://github.com/donnemartin/system-design-primer/issues/130) ∙ [עברית](https://github.com/donnemartin/system-design-primer/issues/272) ∙ [Italiano](https://github.com/donnemartin/system-design-primer/issues/104) ∙ [한국어](https://github.com/donnemartin/system-design-primer/issues/102) ∙ [فارسی](https://github.com/donnemartin/system-design-primer/issues/110) ∙ [Polski](https://github.com/donnemartin/system-design-primer/issues/68) ∙ [русский язык](https://github.com/donnemartin/system-design-primer/issues/87) ∙ [Español](https://github.com/donnemartin/system-design-primer/issues/136) ∙ [ภาษาไทย](https://github.com/donnemartin/system-design-primer/issues/187) ∙ [Türkçe](https://github.com/donnemartin/system-design-primer/issues/39) ∙ [tiếng Việt](https://github.com/donnemartin/system-design-primer/issues/127) ∙ [Français](https://github.com/donnemartin/system-design-primer/issues/250) | [Add Translation](https://github.com/donnemartin/system-design-primer/issues/28)* +*[English](README.md) ∙ [日本語](README-ja.md) ∙ [简体中文](README-zh-Hans.md) ∙ [繁體中文](README-zh-TW.md) | [العَرَبِيَّة‎](https://github.com/donnemartin/system-design-primer/issues/170) ∙ [বাংলা](https://github.com/donnemartin/system-design-primer/issues/220) ∙ [Português do Brasil](https://github.com/donnemartin/system-design-primer/issues/40) ∙ [Deutsch](https://github.com/donnemartin/system-design-primer/issues/186) ∙ [ελληνικά](https://github.com/donnemartin/system-design-primer/issues/130) ∙ [עברית](https://github.com/donnemartin/system-design-primer/issues/272) ∙ [Italiano](https://github.com/donnemartin/system-design-primer/issues/104) ∙ [한국어](https://github.com/donnemartin/system-design-primer/issues/102) ∙ [فارسی](https://github.com/donnemartin/system-design-primer/issues/110) ∙ [Polski](https://github.com/donnemartin/system-design-primer/issues/68) ∙ [русский язык](https://github.com/donnemartin/system-design-primer/issues/87) ∙ [Español](https://github.com/donnemartin/system-design-primer/issues/136) ∙ [ภาษาไทย](https://github.com/donnemartin/system-design-primer/issues/187) ∙ [Türkçe](https://github.com/donnemartin/system-design-primer/issues/39) ∙ [tiếng Việt](README-vi.md) ∙ [Français](https://github.com/donnemartin/system-design-primer/issues/250) | [Add Translation](https://github.com/donnemartin/system-design-primer/issues/28)* **Help [translate](TRANSLATIONS.md) this guide!** diff --git a/TRANSLATIONS.md b/TRANSLATIONS.md index 584c3e2eba..6611d2f194 100644 --- a/TRANSLATIONS.md +++ b/TRANSLATIONS.md @@ -151,12 +151,12 @@ Languages are grouped by status and are listed in alphabetical order. * Discussion Thread: https://github.com/donnemartin/system-design-primer/issues/248 * Translation Fork: https://github.com/Acarus/system-design-primer -### ❗ Vietnamese +### ❗ Tiếng Việt -* Maintainer(s): **Help Wanted** ✋ - * Previous Maintainer(s): [@tranlyvu](https://github.com/tranlyvu), [@duynguyenhoang](https://github.com/duynguyenhoang) -* Discussion Thread: https://github.com/donnemartin/system-design-primer/issues/127 -* Translation Fork: https://github.com/donnemartin/system-design-primer/pull/241, https://github.com/donnemartin/system-design-primer/pull/327 +* Người duy trì: **Cần người** ✋ + * Người duy trì trước đây: [@tranlyvu](https://github.com/tranlyvu), [@duynguyenhoang](https://github.com/duynguyenhoang) +* Luồng thảo luận: https://github.com/donnemartin/system-design-primer/issues/127 +* Fork bản dịch: https://github.com/donnemartin/system-design-primer/pull/241, https://github.com/donnemartin/system-design-primer/pull/327 ## Not Started