Scalability for Dummies

Sau khi làm theo Phần 2 của loạt bài này, bạn đã có một giải pháp cơ sở dữ liệu có thể mở rộng. Bạn không còn lo lắng về việc lưu trữ hàng terabyte dữ liệu nữa và mọi thứ có vẻ ổn thỏa. Nhưng đó chỉ là với bạn. Người dùng của bạn vẫn phải chịu cảnh truy xuất trang chậm chạp khi hệ thống phải lấy quá nhiều dữ liệu từ cơ sở dữ liệu. Giải pháp nằm ở việc triển khai một hệ thống cache (bộ nhớ đệm).

Khi tôi nói “cache”, tôi luôn muốn nói đến các hệ thống cache trong bộ nhớ như Memcached hoặc Redis. Xin đừng bao giờ sử dụng cache dựa trên file – nó khiến việc nhân bản và tự động mở rộng các máy chủ của bạn trở nên vô cùng rắc rối.

Quay lại với cache trong bộ nhớ. Một cache là một kho lưu trữ đơn giản theo dạng khóa-giá trị (key-value), và nên được đặt như một lớp trung gian giữa ứng dụng của bạn và kho dữ liệu. Mỗi khi ứng dụng cần đọc dữ liệu, trước tiên nó nên cố gắng lấy từ cache. Chỉ khi không tìm thấy trong cache, ứng dụng mới truy vấn đến nguồn dữ liệu chính. Tại sao phải làm như vậy? Bởi vì cache cực kỳ nhanh. Nó lưu mọi dữ liệu trong RAM và xử lý truy vấn nhanh nhất có thể về mặt kỹ thuật. Ví dụ, Redis có thể thực hiện hàng trăm nghìn lượt đọc mỗi giây trên một máy chủ tiêu chuẩn. Ghi dữ liệu – đặc biệt là các thao tác tăng số (increment) – cũng rất nhanh. Hãy thử làm điều đó với cơ sở dữ liệu xem!

Có hai mô hình cache dữ liệu phổ biến: một kiểu cũ và một kiểu mới:


#1 – Cache kết quả truy vấn cơ sở dữ liệu

Đây vẫn là kiểu cache phổ biến nhất. Mỗi khi bạn truy vấn đến cơ sở dữ liệu, bạn lưu kết quả trả về vào cache. Khóa cache là một phiên bản được băm (hash) của câu truy vấn. Lần sau khi chạy truy vấn, bạn kiểm tra cache trước xem đã có kết quả chưa. Tuy nhiên, mô hình này có một số vấn đề, đặc biệt là vấn đề hết hạn (expiration). Việc xóa một kết quả cache là rất khó nếu bạn đang cache các truy vấn phức tạp (mà ai lại không từng làm vậy?). Khi chỉ một phần dữ liệu thay đổi (ví dụ một ô trong bảng), bạn sẽ phải xóa tất cả các truy vấn đã được cache có thể chứa dữ liệu đó. Bạn hiểu vấn đề rồi chứ?


#2 – Cache đối tượng

Đây là cách tôi khuyến nghị mạnh mẽ và luôn ưu tiên sử dụng. Về cơ bản, hãy xem dữ liệu như các đối tượng – giống như bạn đã làm trong mã của mình (class, instance, v.v.). Hãy để lớp (class) của bạn tự kết hợp dữ liệu từ cơ sở dữ liệu và sau đó lưu toàn bộ instance hoặc dữ liệu đã được tổ hợp vào cache. Nghe có vẻ lý thuyết, nhưng hãy xem cách bạn thường viết code. Ví dụ, bạn có một class tên là “Product” với thuộc tính “data” – là một mảng chứa giá, mô tả, hình ảnh và đánh giá của người dùng. Thuộc tính “data” này được tạo ra từ nhiều phương thức trong class thực hiện nhiều truy vấn tới cơ sở dữ liệu – rất khó để cache vì mọi thứ liên quan đến nhau. Bây giờ hãy làm điều này: khi class đã hoàn tất việc tổ hợp mảng “data”, hãy lưu trực tiếp mảng này – hoặc tốt hơn là toàn bộ instance của class – vào cache! Cách này giúp bạn dễ dàng xóa đối tượng bất cứ khi nào có sự thay đổi, đồng thời giúp mã của bạn chạy nhanh và hợp lý hơn.

Và điểm tuyệt vời nhất: cách này giúp bạn xử lý bất đồng bộ! Hãy tưởng tượng một đội quân các máy chủ worker thực hiện việc tổ hợp dữ liệu giùm bạn! Ứng dụng của bạn chỉ cần lấy dữ liệu đã cache sẵn – hầu như không cần truy cập cơ sở dữ liệu nữa!


Một vài ví dụ về đối tượng nên cache:

  • Phiên người dùng (đừng bao giờ lưu trong cơ sở dữ liệu!)
  • Bài viết blog đã render hoàn chỉnh
  • Dòng hoạt động (activity streams)
  • Mối quan hệ người dùng <-> bạn bè

Như bạn có thể thấy, tôi là một fan hâm mộ lớn của cache. Nó dễ hiểu, rất dễ triển khai, và kết quả luôn khiến bạn phải kinh ngạc. Về cơ bản, tôi thích Redis hơn Memcached vì tôi yêu các tính năng bổ sung của Redis như khả năng lưu trữ bền vững và các cấu trúc dữ liệu tích hợp như danh sách (list) và tập hợp (set). Với Redis và cách đặt tên khóa hợp lý, bạn thậm chí có thể không cần đến cơ sở dữ liệu nữa. Nhưng nếu bạn chỉ cần cache, hãy dùng Memcached – vì nó có khả năng mở rộng cực kỳ tốt.

Chúc bạn cache vui vẻ!

nguồn: https://www.lecloud.net/post/9246290032/scalability-for-dummies-part-3-cache

Code Toàn Bug

Code nhiều bug nhưng biết cách giấu!

Leave a Reply

Your email address will not be published. Required fields are marked *