Giter VIP home page Giter VIP logo

system-design-beginner's Introduction

Tìm hiểu về thiết kế hệ thống

Nguồn tham khảo chính


Động lực (Motivation)

  • Học cách để thiết kế một hệ thống lớn có khả năng mở rộng
  • Làm đầu ra cho đợt thực tập hè 2017

Mục lục

Khởi động

Bước 1: Bài giảng về khả năng mở rộng

CS75 (Summer 2012) Lecture 9 Scalability Harvard Web Development David Malan

  • Các chủ đề được đề cập:
    • Mở rộng theo chiều dọc (Vertical scaling)
    • Mở rộng theo chiều ngang (Horizontal scaling)
    • Caching
    • Cân bằng tải (Load balancing)
    • Nhân bản cơ sở dữ liệu (Database replication)
    • Phân mảnh cơ sở dữ liệu (Database partitioning)

Bước 2: Bài báo về khả năng mở rộng

Scalability for Dummies

Bước tiếp theo

Tiếp theo là một số khái niệm ở mức cao hơn

  • Hiệu năng (Performance)Khả năng mở rộng (Scalability)
  • Độ trễ (Latency)Thông lượng (Throughput)
  • Tính sẵn sàng (Availability)Tính nhất quán (Consistency)

Hiệu năng và Khả năng mở rộng

Một dịch vụ được coi là có tính mở rộng (scalable) nếu nó mang lại kết quả hoạt động tăng theo tỉ lệ thuận với các tài nguyên (resource) được thêm vào. Tăng hiệu năng có thể được hiểu là một lúc làm được nhiều việc hơn hay làm được một việc lớn hơn.1

Một cách nhìn khác 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 sẽ chậm khi phục vụ một người dùng đơn nhất.
  • Nếu bạn có vấn đề về khả năng mở rộng, hệ thống của bạn sẽ nhanh khi phục vụ người dùng đơn và sẽ chậm nếu phải chịu tải lớn.

Nguồn và tài liệu đọc thêm

Độ trễ và Thông lượng

Độ trễ là thời gian để thực hiện một số hành động hoặc để tạo ra một số kết quả. Thông lượng là số hành động được thực hiện hay số kết quả được đưa ra trong một đơn vị thời gian

Thông thường, mục đích sẽ là cực đại thông lượng với độ trễ chấp nhận được.

Nguồn và tài liệu đọc thêm

Tính sẵn sàng và Tính nhất quán

Định lý CAP


Source: CAP theorem revisited

Ở một hệ thống tính toán phân tán (distributed) (bạn nên tìm hiểu thêm về decentralized), Bạn chỉ có thể cung cấp hai trong số các tính đúng đắn dưới đây:

  • Tính nhất quán (Consistency) - Mọi sự kiện đọc (read) đều nhận được phiên bản mới nhất của sự kiện ghi (write) gần nhất hoặc lỗi.
  • Tính sẵn sàng (Availability) - Mọi request đều nhận một response, không cần đảm bảo dữ liệu nhận được là phiên bản mới nhất.
  • Tính chịu đựng phân mảnh (Partition Tolerance) - Hệ thống vẫn tiếp tục hoạt động mặc cho sự phân mảnh tùy ý (arbitrary partitioning) bị gây ra do lỗi mạng.

Môi trường mạng là không đáng tin cậy, vì vậy bạn sẽ cần tính chịu đựng phân mảnh. Bạn sẽ cần cân nhắc giữa tính nhất quán và tính sẵn sàng.

CP - consistency and partition tolerance

Đợi một response từ node được phân mảnh có thể gây ra timeout error. CP là một lựa chọn tốt nếu bạn cần một ứng dụng đọc ghi nguyên tử.

AP - availability and partition tolerance

Responses trả về phiên bẻn gần nhất của dữ liệu có trên node đó, có thể không phải là mới nhất. Việc ghi có thể tốn một lượng thời gian cho việc lan truyền.

AP sẽ tốt đối với các ứng dụng cần eventual consistency hoặc các ứng dụng yêu cầu vẫn hoạt động mặc cho có lỗi từ bên ngoài.

Các mẫu nhất quán (Consistency patterns)

Với nhiều bản sao của cùng một dữ kiệu, Chúng ta phải đối mặt với các lựa chọn về cách đồng bộ chúng để client có một cái nhìn nhất quán về dữ liệu.

Nhất quán yếu (Weak consistency)

Sau khi ghi, việc đọc có thể nhìn thấy hoặc không. Nhất quán yếu sẽ hoạt động tốt với ứng dụng VoIP, video chat, game online (Các ứng dụng cần phản hồi nhanh và có thể chấp nhận mất mát thông tin).

Eventual consistency (Nhất quán đến cuối cùng)

Sau khi ghi, việc đọc cuối cùng sẽ thấy nó (có thể sau một thời gian). Dữ liệu được nhân bản một cách bất đồng bộ. Loại này được recommmend cho các ứng dụng cần tính sẵn sàng cao (Mô hình BASE).

Nhất quán mạnh (Strong consistency)

Sau việc ghi, việc đọc sẽ thấy nó. Dữ liệu được nhân bản một cách đồng bộ. Nó có thể được thấy ở các hệ thống file hay hệ cơ sở dữ liệu quan hệ. Nó sẽ hữu ích với các ứng dụng dùng giao tác (Mô hình ACID).

Nguồn và tài liệu đọc thêm

Availability patterns

Có hai mẫu chính để hỗ trợ tính sẵn sàng cao: fail-overnhân bản (replication).

Failover

Active-passive

Với active-passive fail-over, heartbeats được gửi giữa các mấy chủ chủ động (active server) và mấy chủ bị động (passive server) sẽ ở trạng thái chờ (standby). Nếu heartbeat bị ngắt quãng, Máy chủ thụ động lấy địa chỉ ip của máy chủ chủ động và tiếp tục dịch vụ, việc đổi ip này có nhiều cách giải quyết, bạn có thể xem Zookeeper.

Active-active

Trong mô hình active-active, tất cả server đều quản lý trafic, chia sẽ tải cho nhau.

Nếu các server đều ở trạng thái public-facing, DNS sẽ cần biết các địa chỉ IP công khai của các server này. Nếu các server ở trạng thái internal-facing, nghiệp vụ của chương trình sẽ phải biết về tất cả các server này.

Active-active failover có thể được gọi với cái tên khác là master-master failover.

Nhược điểm: failover

  • Fail-over cần thêm phần cứng và phức tạp hơn.
  • Vẫn có khả năng mất mát dữ liệu nếu server active sập trước khi dữ liệu mới được ghi chưa được nhân bản ở server passive.

Nhân bản

Master-slave and master-master

Chủ đề này sẽ được bàn luận sâu hơn ở phần Database:

Domain name system


Source: DNS security presentation

Một Domain Name System (DNS) dịch một tên miền như www.example.com thành địa chỉ IP (ngoài ra nó có thể sử dụng để cân bàng tải).

DNS có tính thứ bậc (hierarchical), với một vài server chính chủ (authoritative server) ở mức cao nhất. Router hoặc ISP cung cấp thông tin về DNS server nào sẽ được liên lạc khi có việc tra cứu. Các server DNS ở mức thấp hơn được dùng cho cache mappings, chúng có thể không được cập nhật mới nhất do độ trễ từ việc lan truyền. kết quả DNS 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 sống time to live (TTL).

  • NS record (name server) - chỉ định DNS servers cho tên miền/tên miền con.
  • MX record (mail exchange) - chỉ định mail servers cho việc chấp nhận các tin nhắn.
  • A record (address) - ánh xạ một tên đến một địa chỉ IP.
  • CNAME (canonical) - ánh xạ một tên đến một tên khác hoặc CNAME (example.com to www.example.com) hoặc đến một bản ghi A.

Dịch vụ như CloudFlareRoute 53 cung cấp các dịch vụ DNS được quản lý. Một vài DNS service có thể định tuyến trafic với rất nhiều phương pháp:

  • Weighted round robin
    • chặn các traffic đến server đang bảo trì
    • Cân bằng giữa các size cluster khác nhau
    • A/B testing
  • (Dựa vào độ trễ) Latency-based
  • (Dựa vào vị trí địa lý) Geolocation-based

Nhược điểm: DNS

  • Truy cập DNS sẽ tạo ra một độ trễ nhỏ, mặc dù đã được giảm bớt từ việc cache.
  • quản lý DNS server có thể phức tạp, mặc dù chúng đã được quản lý bởi governments, ISPs, and large companies.
  • DNS services có thể bị tấn công DDoS attack, làm cho người dùng không thể truy cập đúng địa chỉ IP.

Nguồn và tài liệu đọc thêm

Content delivery network (CDN)


Source: Why use a CDN

Một content delivery network (CDN) là một mạng phân tán toàn cầu các proxy server, phục vụ các nội dung từ các địa điểm gần hơn cho người dùng. Thông thường, các nội dung tĩnh như HTML/CSS/JS, ảnh, và video được phục vụ bởi CDN, mặc dù một vài CDN như Amazon's CloudFront cung cấp các nội dung động. Một DNS resolution sẽ nói cho client biết lấy nội dung từ CDN nào.

Việc cung cấp nội dung từ CDN có thể được tối ưu hiệu năng đáng kể nhờ hai yếu tố:

  • Người dùng nhận nội dung tại trung tâm dữ liệu gần họ
  • Server sẽ không phải phục vụ các request mà CDN đã xử lý

Push CDN


Source: cdn.net

Push CDNs nhận nội dung mới bất cứ khi nào có sự thay đổi từ server. Bạn chịu hoàn toàn trách nhiệm cho việc cung cấp nội dung, upload 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ội dung hết hạn và khi nào được cập nhật. Nội dung chỉ được cập nhật khi nó là mới hoặc được cập nhật lại, tối thiểu hóa traffic, nhưng tối đa hóa storage.

Site với một lượng traffic nhỏ hoặc site với nội dung ít phải cập nhật sẽ hoạt động tốt nhất với CDN này. Nội dung được đặt ở CDN một lần, thay vì được pull lại sau một khoảng thời gian nhất định.

Pull CDN


Source: cdn.net

Pull CDN lấy nội dung mới từ server khi người dùng đầu tiên yêu cầu nội dung. Bạn để nội dung ở server của bạn và viết lại URL để trỏ đến CDN. Kết quả là các request sẽ được phục vụ chậm hơn khi nội dung chưa kịp cache lại.

Khoảng thời gian sống time-to-live (TTL) xác định khoảng thời gian nội dung được cache. Pull CDNs tối thiểu hóa lượng dữ liệu phải lưu trữ trên CDN, nhưng nó có thể tạo ra các traffic thừa nếu nội dung hết hạn và được pull lại trước khi nó thực sự được thay đổi.

Các site với lượng traffic lớn sẽ hoạt động tốt với pull CDNs, vì traffic được phân đều ra do chỉ có các nội dung được yêu cầu gần đây được lưu ơ CDN.

Một số tài nguyên CDN miễn phí

Nhược điểm: CDN

  • Chi phí cho CDN có thể đáng kể dựa vào lượng truy cập. Nhưng vẫn cần cân nhắc với những chi phí bạn phải gánh chịu nếu không sử dụng CDN.
  • Nội dung có thể cũ nếu nó vẫn trong thời gian sống tại CDN mà lại được cập nhật ở server.
  • CDN yêu cầu việc viết lại URL để trỏ tới nó.

Nguồn và tài liệu đọc thêm

Bộ cân bằng tải (Load Balancer)


Source: Scalable system design patterns

Load balancers phân tán các request đến các tài nguyên tính toán ví dụ như các server và database. Ở mỗi trường hợp, load balancer trả về một response từ tài nguyên tính toán đến một client thích hợp. Load balancers hiệu quả trong:

  • Ngăn các request đến các server đang có vấn đề
  • Ngăn chặn việc một tài nguyên bị quá tải
  • Giúp loại bỏ điểm chết (single points of failure)

Load balancers có thể được cài đặt với phần cứng (đắt đỏ) hoặc bằng phần mềm như HAProxy.

Một vài lợi ích khác:

  • SSL termination - Giải mã các request đến và mã hóa các response trả về vì vậy backend không phải lo việc này nữa
  • Session persistence - cung cấp các cookie và định tuyến các request cụ thể đến cùng một instance nếu ứng dụng web không theo dõi session.

Để bảo vệ trước lỗi, thường phải cài đặt nhiều load balancer, cả active-passive và active-active.

Load balancer có thể định tuyến trafic dựa trên nhiều độ đo, bao gồm:

Layer 4 load balancing

Layer 4 load balancer nhìn vào thông tin ở lớp transport để quyết định phân tán request. Thông thường, nó bao gồm các địa chỉ IP của nguồn đích và port ở phần header, nhưng không có nội dung của package. Layer 4 load balancer chuyển tiếp các gói tin đến và từ các upstream server, biểu diễn Network Address Translation (NAT).

Layer 7 load balancing

Layer 7 load balancer xem thông tin tại lớp [application layer] để phân tán request. Nó có thể bao gồm thông tin của header, message, và cookies. Layer 7 load balancer ngắt network traffic, đọc nội dung tin, đưa ra quyết định, sau đó mở một kết nối đến server được lựa chọn. Ví dụ, một layer 7 load balancer có thể chỉ đường video traffic tới các server chứa video trong khi chỉ đường cho các traffic nhạy cảm hơn tới những server có tính bảo mật cao (security-hardened server).

Nói về chi phí cho sự linh hoạt, layer 4 load balancing yêu cầu ít thời gian và tài nguyên tính toán hơn Layer 7, mặc dù tác động của hiệu năng có thể là tối thiểu ở các hệ thống được trang bị hiện đại.

Mở rộng theo chiều ngang (Horizontal scaling)

Load balancer có thể cũng giúp ích cho horizontal scaling, nâng cao hiệu năng và khả năng mở rộng. Mở rộng sử dụng thêm các bộ máy là hiệu quả hơn và kết quả là tính sẵn sàng cao hơn là mở rộng bằng cách nâng cấp một server bằng các phần cứng đắt hơn, gọi là Mở rộng theo chiều dọc (Vertical Scaling). Cũng dễ dàng hơn để thuê các tài năng làm việc trên các hệ thống thương mại so với các hệ thống doanh nghiệp đặc biệt.

Nhược điểm: horizontal scaling

  • Mở rộng ngang yêu cầu phức tạp hơn và cần có clone server
    • Server nên để stateless: chúng không nên lưu trữ bất kỳ dữ liệu nào liên quan đến người dùng như sessions hay ảnh cá nhân
    • Sessions có thể lưu ở một trung tâm dữ liệu như một database (SQL, NoSQL) hoặc cache bằng Redis hay Memcached
  • Downstream server ví dụ như cache hay database cần xử lý nhiều kết nối đồng thời bởi vì upstream server được mở rộng

Nhược điểm: load balancer

  • The load balancer có thể trở thành thắt cổ chai nếu không có đủ tài nguyên hoặc không được cấu ình tốt.
  • Có thể tăng sự phức tạp.
  • Một load balancer đơn lẻ là một điểm lỗi, nếu dùng nhiều load balancer thì việc cấu hình lại phức tạp hơn.

Nguồn và tài liệu đọc thêm

Reverse proxy (web server)


Source: Wikipedia

Một reverse proxy là một web server tập trung các dịch vụ bên trong (internal services) và cung cấp giao diện được chuẩn hóa ra bên ngoài. Requests từ clients được chuyển tiếp đến server có khả năng hoàn thành nó trước khi reverse proxy trả về response của server cho client.

Các lợi ích kèm theo bao gồm:

  • Tăng tính bảo mật - Che dấu các thông tin về backend servers, blacklist IPs, số kết nối tối đa được cấp cho mỗi client
  • Tăng khả năng mở rộng và linh hoạt - Client chỉ nhìn thấy địa chỉ IP của reverse proxy, cho phép mở rộng thêm server hoặc thay đổi cấu hình của những server này.
  • Chấm dứt SSL (SSL termination) - đã nói ở phần cân bằng tải
  • Nén (Compression) - nén server response
  • Caching - trả về các response đã được cache
  • Các nội dung tĩnh (Static content) - Nếu client yêu cầu các nội dung tĩnh không cần đến server xử lý, reverse proxy có thể trả về trực tiếp các nội dung này.
    • HTML/CSS/JS
    • Photos
    • Videos
    • Etc

Load balancer vs reverse proxy

  • Triển khai một load balancer là có lợi nếu bạn có nhiều server. Một cách thường xuyên, load balancer định tuyến traffic đến một tạp các server phục vụ cùng một chức năng.
  • Reverse proxy có thể hữu dụng ngay cả với chỉ một web server, với các lợi tích đã nêu trên.
  • Giải pháp ví dụ như NGINX và HAProxy có thể hỗ trợ cả layer 7 reverse proxying và load balancing.

Nhược điểm: reverse proxy

  • Tăng thêm tính 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ụ một failover) thì lại thêm tính phức tạp.

Nguồn và tài liệu đọc thêm

Application layer


Source: Intro to architecting systems for scale

Chia ra web layer từ the application layer (còn được biết đến như platform layer) cho phép bạn mở rộng và cấu hình cả hai một cách độc lập. Thêm một API mới kết quả chỉ là thêm một application server mà không cần thêm một web server.

Single responsibility principle ủng hộ cho việc có các service nhỏ và tự trị làm việc cùng với nhau. Các team nhỏ với các dịch vụ nhỏ có thể trù hoạch mạnh mẽ hơn cho sự phát triển nhanh chóng.

Worker ở application layer có thể cho phép bất đồng bộ (asynchronism).

Microservices

Vấn đề bàn đến là microservices, có thể được miêu tả như một bộ các service được triển khai độc lập, nhỏ và hướng module. Mỗi service chạy ở một tiến trình riêng biệt và giao tiếp thông qua một cơ chế gọn nhẹ, được xác định rõ hàng để thực hiện một nghiệp vụ. 1

Pinterest, như là một ví dụ, có thể có các microservice sau đây: user profile, follower, feed, search, photo upload, ...

Service Discovery

Các hệ thống như Consul, Etcd, and Zookeeper có thể giúp các service tìm được các service khác bằng việc theo dõi các tên, địa chỉ, và cổng đã được đăng ký. Health checks giúp kiểm chứng sự toàn vẹn của các service thường được thực hiện bằng cách sử dụng HTTP endpoint. Cả Consul và Etcd được xây dựng trên key-value store rất hữu dụng cho việc lưu trữ các giá trị cấu hình và các dữ liệu được chia sẻ khác.

Nhược điểm: application layer

  • Thêm một application layer với các dịch vụ kết đôi lỏng lẻo yêu cầu cách tiếp cận khác về kiến trúc, vận hành, và các quan điểm quá trình (process viewpoint) (so với một monolithic system).
  • Microservices có thể thêm độ phức tạp trông việc triển khai và vận hành.

Nguồn và tài liệu đọc thêm

Cơ sở dữ liệu (Database)


Source: Scaling up to your first 10 million users

Relational database management system (RDBMS)

Một CSDL quan hệ như SQL là một bộ sưu tập các data được tổ chức dưới dạng bảng.

ACID là một tập các thuộc tính của RDBMS transactions.


  • Atomicity - Mỗi transaction hoặc là tất cả các thao tác thành công hoặc tất cả thất bại
  • Consistency - Bất kỳ transaction nào cũng đưa CSDL từ một trạng thái hợp lệ này sang một trạng thái hợp lệ khác
  • Isolation - Các giao dịch phải tách biệt nhau
  • Durability - Các dữ liệu đã commit là bền vững

Có rất nhiều kỹ thuật để mở rộng RDBMS: master-slave replication, master-master replication, federation, sharding, denormalization, và SQL tuning.

Master-slave replication

Server master phục vụ đọc và ghi, nhân bản các dữ liệu được ghi ra slave, nơi mà dữ liệu chỉ được đọc. Các slave có thể nhân bản ra các slave khác (dạng cây). Nếu master sập, hệ thống sẽ ở trạng thái chỉ đọc cho đến khi một slave được thăng lên làm master hoặc master được khôi phục.


Source: Scalability, availability, stability, patterns

Nhược điểm: master-slave replication
  • Cần thêm các logic để xác định cơ chế chuyển một slave nên master.

Master-master replication

Tất cả đều hỗ trợ đọc ghi, các server là ngang hàng về việc ghi. Nếu một master sập, hệ thống vẫn tiếp tục đọc ghi.


Source: Scalability, availability, stability, patterns

Nhược điểm: master-master replication
  • Bạn sẽ cần một load balancer hoặc sẽ cần thay đổi logic của application để quết định ghi ở đâu.
  • Hầu hết hệ thống master-master là nhất quán lỏng lẻo (xâm phạm ACID) hoặc sẽ trễ trong việc ghi để đồng bộ.
  • Giải quyết xung đột sẽ càng phức tạp nếu thêm server ghi.
Nhược điểm: replication
  • Có khả năng mất mát dữ liệu nếu master chết trước khi nhân bản được hoàn thành.
  • Mỗi lần ghi sẽ sinh ra các lần nhân bản. Nếu có rất nhiều ghi, việc nhân bản có thể bị sa lầy và không thể làm như các hệ thống nhiều đọc.
  • Càng nhiều read slave, bạn càng cần nhân bản nhiều, độ trễ càn lớn.
  • Ở một vài hệ thống, viết lên master có thể sinh nhiều luồng ghi song song, khi nhân bản chỉ cung cấp viết tuần tự với một luồng đơn.
  • Nhân bản cần thêm phần cứng và độ phức tạp.
Nguồn và tài liệu đọc thêm: replication

Federation


Source: Scaling up to your first 10 million users

Federation (or hoặc phân chia theo hàm) chia database bằng hàm. Ví dụ, thay vì dùng một database đơn, bạn có thể có ba database: forums, users, và products, kết quả là sẽ ít traffic đọc ghi cho mỗi database và cuối cùng ít lag cho nhân bản. Database nhỏ hơn kết quả là nhiều dữ liệu có thể được vừa cho memory, có thể tạo nên nhiều cache hit hơn và cải thiện cache một cách cục bộ. Do có nhiều database bạn có thể ghi song song, cải thiện thông lượng.

Nhược điểm: federation
  • Federation không hiệu quả nếu schema yêu cầu hàm hoặc bảng lớn.
  • Bạn sẽ cần cập nhật application logic để xác định ghi và đọc trên database nào.
  • Join bảng sẽ rất phức tạp với một server link.
  • Federation cần thêm phần cứng và độ phức tạp.
Nguồn và tài liệu đọc thêm: federation

Sharding


Source: Scalability, availability, stability, patterns

Sharding phân tán dữ liệu xuyên suốt các database khác nhau như mỗi database giữ một phần của dữ liệu. Lấy user database làm ví dụ, Nếu càng nhiều user, càng nhiều shard sẽ được thêm vào cluster.

Tương tự như ưu điểm của federation, sharding. kích cỡ index được giảm đi, cải thiện hiệu năng và truy vấn nhanh hơn. Nếu một shard sập các shard khác vẫn họat động, mặc dù bạn vẫn cần nhân bản để tránh mất mát dữ liệu. Như federation, bạn có thể ghi một cách song song.

Bạn có thể dùng họ hoặc vị trí địa lý để shard một bảng có nhiều người dùng.

Nhược điểm: sharding
  • Cần cập nhật lại logic.
  • Dữ liệu có thể bị lõm ở shard. Ví dụ, Sẽ có nhiều request vào một shard trong khi các shard khác rảnh rỗi.
    • Cân bằng lại yêu cầu thêm độ phức tạp. Một hàm cho sharding dựa trên consistent hashing có thể giảm hiểu lượng dữ liệu phải di chuyển qua lại khi có thay đổi.
  • Join từ nhiều shard có thể phức tạp.
  • Sharding yêu cầu thêm phần cứng và độ phức tạp.
Nguồn và tài liệu đọc thêm: sharding

Denormalization

Denormalization mục tiêu là tối ưu hóa đọc bằng một vài chi phí cho việc ghi. Các bản copy thừa của dữ liệu được thêm vào các bảng để hạn chế nhiều lệnh join. Một vài RDBMS như PostgreSQL và Oracle cung cấp materialized views để xử lý công việc lưu trữ dư thừa và giũ chúng nhất quán.

Một khi dữ liệu phân tán từ các kỹ thuật như federationsharding, việc join sẽ rất phức tạp. Denormalization sẽ giảm thiểu việc phải join một cách phức tạp.

Ở hầu hết các hệ thống, việc đọc thường gấp 100 thậm chí 1000:1 việc ghi. việc đọc lại yêu cầu các phép join tốn kém, tốn một khoảng thời gian lớn cho việc truy xuất.

Nhược điểm: denormalization
  • Dữ liệu bị trùng lặp.
  • Phải đồng bộ hóa dư thừa, thiết kế database phức tạp hơn.
  • Không sử dụng cho các ứng dụng có lượng ghi lớn.
Nguồn và tài liệu đọc thêm: denormalization

SQL tuning

SQL tuning là một chủ đề lớn của rất nhiều sách đã được viết như một nguồn tham khảo.

Nó rất quan trọng để benchmarkprofile để mô phỏng và phát hiện các nút thắt cổ chai.

  • Benchmark - Mô phỏng trường hợp tải cao với công cụ như ab.
  • Profile - Công cụ kiểm định như slow query log để theo dõi các vấn đề về hiệu năng.

Benchmarking và profiling có thể giúp cho bạn cải thiện hiệu năng theo những cách sau.

Làm chặt hơn schema
  • MySQL dumps vào đĩa bằng các block liên tiếp cho việc truy cập nhanh.
  • Sử dụng CHAR thay vì VARCHAR cho các trường có độ dài cố định.
    • CHAR cho phép random access một cách hiệu quả, trong khi với VARCHAR, bạn phải tìm đến hết string trước khi chuyển sang cái tiếp theo.
  • Sử dụng TEXT cho một lượng lớn ký tự như một bài đăng của blog. TEXT còn cho phép boolean seach. Sử dụng TEXT lưu một con trỏ tới đĩa để lưu trũ text block.
  • Sử dụng INT cho các số từ 2^32 hoặc 4 tỉ.
  • Sử dụng DECIMAL cho đơn vị tiền tệ.
  • Tránh sử dụng BLOBS lớn, thay vào đó lưu địa chỉ của tài nguyên.
  • VARCHAR(255) là số ký tự lớn nhất có thể đếm được bằng số 8-bit, thường tối đa hóa việc sử dụng byte trong một số RDBMS.
  • Set NOT NULL ở các trường có thể dùng để tăng hiệu năng improve search performance.
Sử dụng việc đánh chỉ số tốt
  • Cột mà bạn truy vấn (SELECT, GROUP BY, ORDER BY, JOIN) có thể nhanh hơn nhờ index.
  • Index thường được biểu diễn dưới dạng cây cân bằng B-tree giữa cho dữ liệu được sắp xếp để tìm kiếm, truy cập tuần tự, thêm, và xóa đọ phức tạp logarit.
  • Việc index yêu cầu thêm không gian lưu trữ.
  • Việc viết có thể chậm hơn nếu dùng index.
  • Khi loading một lượng lớn dữ liệu, có thể nhanh hơn nếu vô hiệu hóa index, load dữ liệu, sau đó xây dựng lại index.
Tránh join
  • Denormalize, khi hiệu năng yêu cầu đến nó.
Phân mảnh bảng
  • Chia bảng bằng cách đặt các điểm nóng trong một bảng riêng biệt để giúp giữ nó trong memory.
Điều chỉnh query cache
Nguồn và tài liệu đọc thêm: SQL tuning

Cơ sở dữ liệu NoSQL

NoSQL is là một tập các dữ liệu được biểu hiện theo cách key-value store, document-store, wide column store, hoặc là một graph database. Dữ liệu là không chuẩn hóa, và phép join được sử dụng ở mức code. Hầu hết chúng không dùng ACID mà dùng eventual consistency.

BASE thường được dùng trong NoSQL. Theo CAP Theorem, BASE chọn tính sẵn sàng cao hơn 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 có thể thay đổi theo thời gian, kể cả không có input.
  • Eventual consistency - Hệ thống sẽ nhất quán sau một khoảng thời gian nhất định.

Thêm vào đó chọn SQL hay NoSQL, rất hữu ích để hiểu được NoSQL phù hợp với ca sử dụng nào nhất. Chúng tôi sẽ review key-value stores, document-stores, wide column stores, và graph databases ở phần tiếp theo.

Key-value store

Abstraction: Bảng băm(hash table)

Một CSDL key-value thông thường cho độ phức tạp O(1) cho việc đọc ghi và thường được sử dụng trên RAM hoặc SSD để tối ưu hóa tốc độ. CSDL có thể duy trì khóa theo thứ tự từ điển (lexicographical order), cho phép truy xuất hiệu quả các vùng khóa (key range). Nó có thể cho phép lưu giá trị (value) dưới dạng siêu dữ liệu (metadata).

CSDL cung cấp hiệu năng cao và thường được sử dụng cho mô hình dữ liệu đơn giản hoặc các dữ liệu thay đổi nhanh, ví dụ như các dữ liệu được lưu ở lớp in-memory cache. Bởi vì chúng chỉ cung cấp một tập hữu hạn các toán tử, các toán tử phức tạp sẽ được chuyển đến lớp application.

CSDL key-value là nền tảng cho các hệ thống phức tạp hơn như CSDL dạng document, và trong một số trường hợp là graph database.

Nguồn và tài liệu đọc thêm: key-value store

Document store

Abstraction: key-value store với documents được lưu như một giá trị

Một document store lấy văn bản (document) làm trung tâm (XML, JSON, binary, ...), một document có thể lưu mọi thông tin của một đối tượng. Document stores cung cấp các API hoặc một ngôn ngữ truy vấn để truy vấn dựa trên cấu trúc nội tại của văn bản. Ghi chú, nhiều key-value store có bao gồm các tính năng để làm việc với siêu dữ liệu, làm mờ ranh giới giữa 2 loại CSDL.

Dựa trên phần cài đặt phía dưới, văn bản được tổ chức dưới dạng các collection, tag, metadata, hoặc directorie. Mặc dù các văn bản có thể được tổ chức hoặc nhóm lại với nhau, Văn bản có thể chứa các trường khác hoàn toàn với phần còn lại.

Một vài CSDL nổi tiếng như MongoDBCouchDB cung cấp ngôn ngữ truy vấn giống SQL. DynamoDB cung cấp cả dạng key-value và document.

Document stores cung cấp độ linh hoạt cao và thường được dùng với những loại dữ liệu phải thay đổi đột ngột.

Nguồn và tài liệu đọc thêm: document store

Wide column store


Source: SQL & NoSQL, a brief history

Abstraction: nested map ColumnFamily<RowKey, Columns<ColKey, Value, Timestamp>>

Đơn vị dữ liệu cơ bản của wide column store là một cột (cặp name/value). Một cột có thể được nhóm vào một họ các cột (column family) (tương tự như một bảng bên SQL). Super column family là sự nhóm lại của các column family. Bạn có thể truy cập mỗi cột một cách độc lập với một row key, và các cột với cùng một row key tạo thành một dòng. Mỗi giá trị bao gồm một timestamp cho việc tạo phiên bản (versioning) và để giải quyết các sung đột.

Google giới thiệu Bigtable như là wide column store đầu tiên, nó tác động tới dự án open-source HBase thường được sử dụng trong hệ sinh thái Hadoop, và Cassandra từ Facebook. Các CSDL ví dụ như BigTable, HBase, và Cassandra duy trì khóa theo thứ tự bảng chữ cái.

Wide column stores cung cấp tính sẵn sàng và mở rộng cao. Chúng thường được sử dụng để giải quyết lượng dữ liệu rất lớn.

Nguồn và tài liệu đọc thêm: wide column store

Graph database


Source: Graph database

Abstraction: graph

Trong CSDL đồ thị (graph database), mỗi nút(node) là một bản ghi và mỗi cạnh là một quan hệ (relationship) giữa hai nút. Graph databases được tối ưu cho việc biểu diễn dữ liệu với các quan hệ phức tạp với rất nhiều khóa ngoại hay quan hệ nhiều nhiều.

Graphs databases cung cấp hiệu năng cao cho mô hình dữ liệu với các quan hệ phức tạp, ví dụ mạng xã hội. Chúng tương đối mới và chưa được sử dụng rộng rãi; Sẽ khó hơn cho bạn trong việc tìm tài nguyên hay công cụ phát triển. Nhiều CSDL dạng này chỉ có thê truy cập qua REST APIs.

Nguồn và tài liệu đọc thêm: graph

Nguồn và tài liệu đọc thêm: NoSQL

SQL hay NoSQL


Source: Transitioning from RDBMS to NoSQL

Lý do cho SQL:

  • Dữ liệu có cấu trúc
  • schema chặt chẽ
  • Dữ liệu có tính quan hệ cao
  • Cần các phép nối phức tạp
  • Cần đến Transaction (đảm bảo ACID)
  • Các mẫu rõ ràng cho việc mở rộng
  • Được hỗ trợ nhiều hơn từ: developers, community, code, tools, ...
  • Tra cứu trên index rất nhanh

Lý do cho NoSQL:

  • Dữ liệu có tính bán cấu trúc
  • schema động và linh hoạt
  • Dữ liệu ít có tính quan hệ
  • Không cần các phép nối phức tạp
  • Lưu dữ liệu nhiều đên mữ TB, PB
  • Cần chịu tải rất lớn
  • Cần thông lượng cao cho IOPS

Các dữ liệu mẫu thích hợp cho NoSQL:

  • Rapid ingest of clickstream and log data
  • Leaderboard or scoring data
  • Temporary data, such as a shopping cart
  • Frequently accessed ('hot') tables
  • Metadata/lookup tables
Nguồn và tài liệu đọc thêm: SQL or NoSQL

Cache


Source: Scalable system design patterns

Caching cải thiện thời gian tải trang và giảm thiểu việc phải tương tác với database của server. Ở mô hình này, Bộ điểu phối (Dispatcher) trước tiên sẽ tra cứu nếu request đã được thực hiện trước đó và cố gắng tìm kết qủa trước đó để trả lại, để tiết kiệm thời gian thực thi.

Cơ sở dữ liệu thường hoạt động tốt nhờ việc phân phối đồng đều các lần đọc ghi trên các phân vùng của nó. Các item phổ biến sẽ làm mất cân bằng phân phối, gây nghẽn cổ trai. Đưa một bộ nhơ đệm (cache) ở phía trước cơ sở dữ liệu có thể giải quyết vấn đề tải không đều và sự tăng đột biến lượng truy cập.

Client caching

Caches có thể được đặt bên phía client (Hệ điều hành hoặc trình duyệt), server side, hoặc ở một lớp bộ nhớ đệm khác.

CDN caching

CDNs được coi là một loại bộ nhớ cache.

Web server caching

Reverse proxies và cache ví dụ như Varnish có thể phục vụ trực tiếp các nội dung tĩnh và động. Web servers còn có thể cache lại request, trả về responses mà không cần giao tiếp với application server.

Database caching

Cơ sở dữ liệu thường bao gồm một vài mức cache ở cấu hình mặc định, tối ưu hóa cho việc sử dụng chung nhất. Tinh chỉnh các cấu hình này cho các trường hợp sử dụng đặc thù có thể làm tăng thêm hiệu suất.

Application caching

In-memory caches ví dụ như Memcached và Redis là các giá trị key-value giữa ứng dụng và your data storage. Bởi vì dữ liệu được giữ trên RAM, nó sẽ nhanh hơn rất nhiều so với dữ liệu được lấy từ database (lưu trên đĩa). Dung lượng RAM hạn chế hơn dung lượng đĩa, vì vậy thuật toán cache invalidation ví dụ least recently used (LRU) có thể bỏ các dữ liệu ít dùng và giữ lại các dữ liệu thường xuyên được sử dụng trên RAM.

Redis có các tính năng bổ sung dưới đây:

  • Tùy chọn lưu trữ lâu dài (Persistence option)
  • Cấu trúc dữ liệu dựng sẵn ví dụ như sorted sets và list

Có nhiều mức cache được xếp vào hai loại chính: database queriesobjects:

  • Row level
  • Query-level
  • Fully-formed serializable objects
  • Fully-rendered HTML

Thông thường bạn nên cố tránh cache trên tệp, ví nó làm cho việc nhân bản và tự động mở rộng trở nên khó khăn hơn.

Caching at the database query level

Bất kì khi nào bạn truy vấn, băm truy vấn thành một khóa và lưu kết quả vào cache.

Cách tiếp cận này có những vấn đề sau:

  • Khó để xóa các dữ liệu đã cache với truy vấn phức tạp
  • Nếu một mảnh dữ liệu thay đổi ví dụ như một ô trên bảng, bạn phải xóa toàn bộ các truy vấn đã cache có chứa ô bị thay đổi đó.

Caching at the object level

Coi dữ liệu như các đối tượng, tương tự với việc bạn làm với mã nguồn. Have your application assemble the dataset from the database into a class instance or a data structure(s):

  • Xóa đối tượng nếu dữ liệu ở mức dưới có sự thay đổi.
  • Cho phép xử lý bất đồng bộ: workers tập hợp các đối tượng bằng cách tiêu thụ các đối tượng được cache gần nhất.

Gợi ý các thành phần nên cache:

  • User sessions
  • Fully rendered web pages
  • Activity streams
  • User graph data

Khi nào nên cập nhật cache

Bởi vì bạn chỉ có thể lưu một lượng giới hạn dữ liệu trong cache, bạn cần chọn chiến lược cập nhật phù hợp với trường hợp của mình.

Cache-aside


Source: From cache to in-memory data grid

Hệ thống chịu trách nhiệm đọc và ghi từ bộ nhớ. Bộ nhớ đệm không trực tiếp tương tác với cơ sở dữ liệu. Hệ thống sẽ làm những việc sau:

  • Tra cứu entry trong cache, nếu cache-miss
  • Tải entry lên từ đĩa
  • Thêm entry vào cache
  • Trả về entry
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 thường được dùng trong trường hợp này.

Đọc tuần tự dữ liệu được thêm vào cache thì nhanh. Cache-aside cũng được gọi là lazy loading. Chỉ những dữ liệu yêu cầu mới được cache, tránh đưa vào cache những dữ liệu không được yêu cầu.

Write-through


Source: Scalability, availability, stability, patterns

Hệ thống sử dụng cache như một nơi lưu trữ chính, đọc và ghi dữ liệu lên nó, trong khi cache đóng vai trò đọc và ghi dữ liệu trên database:

  • Hệ thống thêm, sửa entry trên cache
  • Cache ghi một cách đồng bộ lên
  • Trả về kết quả

Application code:

set_user(12345, {"foo":"bar"})

Cache code:

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à chậm trên tổng thể do thao tác ghi, nhưng đọc tuần tự trên các dữ liệu vừa được ghi là nhanh. Người dùng thường dễ chấp nhận độ trễ cho cập nhật dữ liệu hơn là khi đọc dữ liệu. Dữ liệu trong cache không bị cũ.

Write-behind (write-back)


Source: Scalability, availability, stability, patterns

Trong write-behind, Ứng dụng sẽ làm các bước sau:

  • Thêm, cập nhật vào cache
  • Ghi bất đồng bộ ra database, cải thiện hiệu năng ghi
Nhược điểm: write-behind
  • Có thể mất mát dữ liệu nếu dữ liệu mới chỉ được ghi vào cache mà chưa được ghi vào data.
  • Cài đặt có thể khó hơn write-through hoặc cache aside.

Refresh-ahead


Source: From cache to in-memory data grid

Bạn có thể cấu hình cache làm mới tự động các entry được truy cập gần đây trước thời gian nó hết hạn.

Refresh-ahead có thể giảm độ trễ với read-through nếu cache có thể dự đoán chính xác item nào có thể được truy cập trong tương lai.

Bất lợi: refresh-ahead
  • Việc tiên đoán có thể làm ảnh hưởng đến hiệu năng.

Nhược điểm: cache

  • Cần đảm bảo thông tin là đúng và nhất quán giũa cache và database, Các giải thuật về cache.
  • Cần thay đổi ứng dụng nếu thêm Redis hay Memcache.
  • Chiến lược cập nhật cache là tương đối khó và có sự đặc thù cho các ứng dụng khác nhau.

Nguồn và tài liệu đọc thêm

Bất đồng bộ (Asynchronism)


Source: Intro to architecting systems for scale

Các luồng làm việc bất đồng bộ (Asynchronous workflow) giúp giảm thiểu thời gian yêu cầu cho những tác vụ tốn tài nguyên mà bình thường chứng được xử lý đồng bộ. Chúng cũng giúp đỡ bằng cách làm những việc tốn thời gian trước, ví dụ như tập hợp dữ liệu một cách định kỳ.

Message queues

Message queues nhận, giữ, và vận chuyển các tin nhắn. Nếu một tác vụ mất nhiều thời gian để xử lý một các đồng bộ, bạn có thể dùng một message queue với luồng công việc dưới đây:

  • Một ứng dụng công bố (publish) một công việc đến hàng đợi, sau đó thông báo cho người dùng trạng thái của coong việc
  • Một worker lấy (pick up) công việc từ hang đợi, xử lý nó, sau đó thông báo là công việc đã hoàn thành

Người dùng không đợi cho đến khi công việc xử lý xong và công việc được xử lý dưới nền. Trong suốt thời gian này, phía client có thể làm một chút xử lý nhó để làm như công việc đã xửu lý xong. Ví dụ, Nếu đăng lên tweet, tweet sẽ ngay lập tức được đưa lên timeline, nhưng có thể phải mất một chút thời gian để tweet của bạn thực sự được đưa đến những người theo dõi.

Redis là hữu dụng nư một message broker đơn giản nhưng tin nhắn có thể bị mất.

RabbitMQ phổ biến nhưng yêu cầu bạn làm cho hệ thống tương thích với giao thức 'AMQP' và quản lý các node của bạn.

Amazon SQS, được tổ chức (hosted) nhưng có độ trễ cao và có thể tin nhắn sẽ được gửi đi đến hai lần (lặp).

Task queues

Các Tasks queue nhận các task và những dữ liệu liên quan, chạy chúng, sau đó chuyển đi các kết quả của chúng. Task queue hỗ trợ lập lịch cà có thể chạy các công việc đòi hỏi tính toán nhiều ở trong nền.

Celery hỗ trợ lạp lịch và chủ yếu hỗ trợ python.

Back pressure

Nếu các hàng đợi lớn lên đáng kể, kích cỡ hàng đợi có thể lớn hơn bộ nhớ, dẫn đến cache mis, đọc từ đĩa, và hiệu năng chậm đi đáng kể. Back pressure có thể giới hạn kích cỡ hàng đợi, qua đó duy trì một tỉ lệ băng thông cao và thời gian phản hồi tốt cho các công việc có trong hàng đợi. Khi mà hàng đợi đầy, client sẽ nhận phản hồi bận từ server hoặc mã trạng thái HTTP 503 để thử lại lần nữa. Client có thể thử request sau đó, có thể với exponential backoff.

Nhược điểm: asynchronism

  • Các ca sử dụng như các tính toán nhẹ và các luồng xử lý thời gian thực có thể sẽ thích hợp hơn nếu dùng xử lý đồng bộ, trong khi xử lý bất đồng bộ có thể chậm và phức tạp.

Nguồn và tài liệu đọc thêm

Communication


Source: OSI 7 layer model

Hypertext transfer protocol (HTTP)

Transmission control protocol (TCP)

User datagram protocol (UDP)

Remote procedure call (RPC)


Source: Crack the system design interview

Trong RPC, một client tạo nên một thủ tục có thể được thực thi ở một địa chỉ khác, thường là server từ xa. Thủ tục được mã hóa như thể nó là một cuộc gọi cục bộ, trừu tượng hóa các công đoạn cụ thể làm thế nào để server liên lạc với client. Gọi từ xa thường chậm hơn và ít phụ thuộc hơn so với gọi cụ bộ nên nó rất hữu dụng để để phân biệc một RPC call hay cuộc gọi cục bộ. RPC frameworks phổ biến bao gồm Protobuf, Thrift, và Avro.

RPC là một giao thức request-response:

  • Client program - gọi stub procedure bên client. Tham số được thêm vào ngăn xếp như là gọi thủ tục cục bộ.
  • Client stub procedure - Marshals (gói) id và các tham số của thủ tục vào một request mesage.
  • Client communication module - Hệ điều hành gửi mesage từ client lên server.
  • Server communication module - hệ điều hành chuyển message đến stub procedure bên server.
  • Server stub procedure - Unmarshalls (giải nén) kết quả, gọi các thủ tục phía server phù hợp với id của thủ tục được gửi đến và truyền vào các tham số nhận được.
  • server phàn hồi bằng cách lặp lại các bước trên ở thứ tự ngược lại.

gọi RPC mẫu:

GET /someoperation?data=anId

POST /anotheroperation
{
  "data":"anId";
  "anotherdata": "another value"
}

RPC tập trung vào các hành vi. RPC thường được sử dụng cho vấn đề về hiệu năng với những giao tiếp nội tại, vì bạn có thể gọi bản địa (native call) một cách thủ công để phù hợp hơn với ca sử dụng (khác REST).

Chọn một native library (aka SDK) khi:

  • Bạn biết nền tảng nhắm tới.
  • Bạn muốn kiểm soát "logic được truy cập như thế nào".
  • Bạn muốn kiểm soát cơ chế kiểm soát lỗi xảy ra như thế nào trong thư viện của bạn.
  • Hiệu năng và trải nghiệm người dùng cuối là điều lo lắng chính của bạn.

HTTP API dưới đây REST có xu hướng được sử dụng nhiều hơn cho public API.

Nhược điểm: RPC

  • RPC client có liên kết chặt chẽ với việc cài đặt phía server.
  • Một API mới sẽ phải định nghĩa lại cho tất cả tác vụ hoặc ca sử dụng.
  • Khó để có thể debug RPC.
  • You có thể không có khả năng nâng cấp các công nghệ đang có. Ví dụ, có thể yêu cầu thêm nỗ lực để chắc chắn RPC call đã được cache ở server cache như Squid.

Representational state transfer (REST)

REST is là một kiểu kiến trúc thi hành một mô hình client/server mà client thực hiện hành vi trên một tập các tài nguyên được quản lý bới server. Server cung cấp một đại diện cho tài nguyên và hành vi mà có thể được vận dụng cũng như lấy một đại diện mới của các tài nguyên. Tất cả giao tiếp phải là stateless và có thể cache được.

Có 4 tiêu chí chất lượng cho một giao diện RESTful:

  • (Xác định tài nguyên) (URI trong HTTP) - sử dụng cùng một URI cho bất kỳ tác vụ nào.
  • Thay đổi với representations (Verbs trong HTTP) - sử dụng verb, header, and body.
  • Self-descriptive error message (status response trong HTTP) - Sử dụng status code, "đừng phát minh lại chiếc bánh xe".
  • HATEOAS (HTML interface for HTTP) - web service của bạn nên được truy cập đầy đủ trong một trình duyệt.

Mẫu cho việc sử dụng REST:

GET /someresources/anId

PUT /someresources/anId
{"anotherdata": "another value"}

REST lại tập trung vào việc phơi bày (expose) dữ liệu. tối hiểu hóa sự liên kết giữ client/server và thường được sử dụng trong các public HTTP API. REST sử dụng method một cách chuẩn mực và chung chung hơn thông qua API, đại diện thông qua header, và các hành vi thông qua verbs như GET, POST, PUT, DELETE, và PATCH. Là stateless, REST là rất tuyệt cho việc mở rộng theo chiều ngang và phân mảnh.

Nhược điểm: REST

  • Với việc REST tập trung vào dữ liệu được phơi bày (exposing data), nó có thể không hoàn toàn tương thích nếu tài nguyên không được tổ chức theo nguyên tắc hoặc được truy cập dưới dạng phân cấp đơn giản. Ví dụ, trả về tất cả các bản ghi đã được cập nhật từ giờ trước match với một tập các sự kiện không dễ để thể hiện với một đường dẫn. Với REST, Nó như là một sự cài đặt với sự kết hợp của đường dẫn URI, query parameter, và có thể còn request body nữa.
  • REST thông thường phụ thuộc vào một vài verbs (GET, POST, PUT, DELETE, và PATCH) đôi khi không phù hợp với ca sử dụng của bạn. Ví dụ, chuyển một tài liệu đã hết hạn đến một thư mục có thể không hoàn toàn phù hợp với những verb này.
  • Việc nạp các tài nguyên phức tạp với phân cấp lồng nhau yêu cầu nhiều lần kết nối giũa client và server để render một giao diện, ví dụ. nạp nội dung cho một blog và bình luận cho blog đó. Đối với các thiết bị di động hoạt động trên mỗi trường mạng bất ổn, việc này sẽ có vấn đề.
  • Theo thời gian, nhiều trường được thêm vào API response và các client cũ phải nhận thêm các trường dữ liệu mới này, mặc cho chúng không hề cần các trường đó, như một hệ quả, nó làm tăng kích thước của payload và dẫn đến độ trễ gia tăng.

So sánh RPC and REST

Operation RPC REST
Signup POST /signup POST /persons
Resign POST /resign
{
"personid": "1234"
}
DELETE /persons/1234
Read a person GET /readPerson?personid=1234 GET /persons/1234
Read a person’s items list GET /readUsersItemsList?personid=1234 GET /persons/1234/items
Add an item to a person’s items POST /addItemToUsersItemsList
{
"personid": "1234";
"itemid": "456"
}
POST /persons/1234/items
{
"itemid": "456"
}
Update an item POST /modifyItem
{
"itemid": "456";
"key": "value"
}
PUT /items/456
{
"key": "value"
}
Delete an item POST /removeItem
{
"itemid": "456"
}
DELETE /items/456

Source: Do you really know why you prefer REST over RPC

Nguồn và tài liệu đọc thêm: REST and RPC

Bảo mật (Security)

Phần này sẽ cần cập nhật thêm.

Bảo mật là một chủ đề rất rộng. Nên ở đây chỉ nêu một vài vấn đề cơ bản

  • Mã hóa trong chuyển tiếp cũng như trong lưu trữ.
  • Khử độc(Sanitize) tất cả đầu vào của người dùng để tránh tấn công XSSSQL injection.
  • Sử dụng các truy vấn có thể truyền tham số để tránh SQL Injection (Các thư viện đều hỗ trợ, tốt hơn là nên dùng ORM).
  • Sử dụng định lý least privilege. Nên dùng các quy luật chặt chẽ để phân quyền trên các tiến trình và tài nguyên.

Nguồn và tài liệu đọc thêm : Security

Sử dụng JWT cho việc định danh (authentication)


Source: auth0

  • Lợi thế của JWT hay token-based authentication nói chung

    • phi trạng thái (stateless), khả năng mở rộng (scalable) và tách biệt (decoupled): có lẽ lợi thế lớn nhất của jwt so với dùng session là phi trạng thái. Server không phải lưu lại bản ghi của token mà chỉ cần xác nhận token đấy có hợp lệ hay không, bản thân token nó đã mang các thông tin cần thiết rồi.
    • Cross Domain và CORS: Session sẽ gặp khó khăn khi phải quản lý ở nhiều domain khác nhau, jwt có thể xử lý vấn đề này
    • Store Data in the JWT: jwt có thể lưu lại bất kỳ dữ liệu nào, nếu nó là một JSON hợp lệ. Bạn có thể lưu lại các thông tin cần thiết cho hệ thống của bạn.
    • Hiệu năng: Từ những lợi thế trên, ta sẽ có lợi thế về hiệu năng. Khi dùng session thông thường, server phải mở một hoặc nhiều kết nối để tìm kiếm trong CSDL trong khi dùng token thì bạn chỉ cần mở kết nối khi cần lấy dữ liệu mà thôi, tất cả thông tin về authentication cũng như authorization đều được lưu trong jwt.
    • Mobile Ready: Không phải thiết bị nào cũng hỗ trợ tốt cho cookie, jwt là một sự thay thế không tồi.
  • Làm cách nào để vô hiệu hóa một jwt (cho việc đăng xuất cũng như hủy đăng nhập từ các thiết bị khác)

    • Xây dựng một danh sách đen (blacklist) các jwt bị vô hiệu hóa.
    • Set thời gian sống cho mỗi jwt thật ngắn, sau đó refresh lại token vào mốc thời gian cần thiết.

Nguồn và tài liệu đọc thêm: JWT

Các kiểu tấn công web phổ biến

Tường lửa ứng dụng web

  • Ruled base (Blacklist)
  • Anormaly Detection (Whitelist)

TODO

  1. Centralized vs Decentralized vs Distributed
  2. Apache vs Nginx
  3. Redis Architecture
  4. Zoo Keeper, ETCD

system-design-beginner's People

Contributors

nesso99 avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.