Cache cho web ở server
Cache
5
White

Ngoc Dao viết ngày 20/03/2016

Cache là thượng sách để tăng tốc độ truy cập cho web. Thường nó giúp tốc độ trang web tăng lên ngay lập tức vài chục lần. Trước khi nghĩ đến hạ sách load balance, thread pool, DB connection pool, vertical scaling, horizontal scaling và những thuật ngữ rất kêu khác, hãy nghĩ đến cache. Wikipedia định nghĩa cache như sau:

a cache (pronounced /kæʃ/, like "cash") is a collection of data duplicating original values stored elsewhere or computed earlier, where the original data is expensive to fetch (owing to longer access time) or to compute, compared to the cost of reading the cache. In other words, a cache is a temporary storage area where frequently accessed data can be stored for rapid access. Once the data is stored in the cache, future use can be made by accessing the cached copy rather than re-fetching or recomputing the original data, so that the average access time is shorter.

Ý tưởng về cache cho web rất đơn giản: nội dung web tuy động nhưng không thay đổi quá nhanh, khi 100 người truy cập cùng URL thì trong đa số trường hợp 100 người này đều nhìn thấy cùng chuỗi kí tự HTML, do đó chỉ cần tính toán chuỗi kí tự HTML đó ở lần truy cập đầu tiên rồi cache kết quả lại, 99 lần tiếp theo chỉ cần hiện nguyên xi kết quả lấy từ cache.

Bài viết này trình bày chung về cache ở server, có thể áp dụng cho nhiều ngôn ngữ và framework khác nhau. Về cache ở client, xin hẹn bài khác.

Cơ chế và phân loại cache

Web thì đầu vào là URL và tham số, đầu ra là HTML. Chương trình chạy trên web server, quan sát dòng chảy dữ liệu từ đầu vào cho đến đầu ra:

Request -(1)-> [Controller/Action -(2)-> [[Model -(3)-> DB -(4)]-> View -(5)]] -> Response

ta thấy ở mỗi bước đều có thể nhảy cóc sang bước cách nó hoặc nhảy thẳng đến đầu ra nếu đã có kết quả lưu sẵn trong cache. Sơ đồ trên cho thấy có thể phân cache làm 5 loại:

  • (1) Page: Nguyên cả trang HTML ứng với URL nhất định được lưu vào cache, các truy cập tiếp theo đến cùng URL này nhận được ngay kết quả từ web server. Chương trình không phải tính toán gì, thậm chí không biết là đã có request vì web server không báo.
  • (2) Action: Chương trình biết là có request, nhưng trả về ngay kết quả mà không cần động vào Model hay View.
  • (5) Fragment: Chỉ một phần HTML của trang được lưu.
  • (4) Object: Object nào đó (có thể không phải là chuỗi kí tự HTML) được lưu.
  • (3) SQL: Khi cùng câu lệnh SQL được gọi đi gọi lại, thì chỉ lệnh đầu tiên được gửi đến DB server. Tính năng này thường được thực hiện tự động bởi framework, khi viết chương trình không cần quan tâm.

Nói chung, nút cổ chai thường nằm ở kết nối đến DB server, cache làm sao để giảm thiểu truy vấn đến DB server càng nhiều càng tốt.

Yếu tố ảnh hưởng đến chọn loại cache

Có 2 yếu tố:

  • Người dùng. Ví dụ người đã đăng nhập nhìn thấy kết quả HTML khác với người chưa đăng nhập. Ví dụ cùng URL nhưng trang web hiện tiếng Việt cho người đến từ Việt Nam, tiếng Mỹ cho người Mỹ.
  • Thời gian. Ví dụ bài vừa được đăng sẽ hiện "Động đất ở Trung Quốc - Cập nhật vài phút trước", nhưng cũng bài nay sau vài ngày sẽ hiện "Động đất ở Trung Quốc - Cập nhật vài ngày trước".

Mẹo vặt

  • Tiêu chí: Khi DB không có gì thay đổi, thì refresh trang web cũng không làm web server phải truy cập vào DB server.
  • Page cache: Chỉ dùng được khi hiện như nhau cho tất cả người dùng, rất hiếm vì 99.9% các trang đều chứa nội dung động. Hệ quả: nên tắt luôn session để tốc độ xử lí nhanh thêm gấp rưỡi đến gấp đôi.
  • Hầu như chỉ có thể dùng fragment và object cache (thường các framework đều tự động có sẵn tính năng SQL cache). Object cache dễ dùng hơn vì cùng thông tin nhưng có thể thoải mái hiện theo nhiều kiểu khác nhau.
  • Khi viết chương trình, nhìn debug log hiện ở console để biết cần cache chỗ nào, có truy vấn nào đến DB server nữa không để sau khi thêm cache sẽ giảm thiểu được truy vấn đến DB server.
  • Cache lưu theo key. Ứng với một cache key, nên chứa càng nhiều dữ liệu càng tốt, thay vì chỉ một record đơn lẻ, như vậy mới có tác dụng tăng tốc nhiều.
  • Nên ghi chú (1) tên cache key, (2) những chỗ set và (3) những chỗ expire cache thành tài liệu để tránh sai sót và tiện bảo trì sau này.
  • Nếu framework cung cấp sweeper (như Rails) thì quá tiện: (3) thay vì là controller, sẽ là sweeper. Tuy nhiên vì sweeper cũng chỉ là một loại callback, nên nếu framework không có tính năng sweeper, thì có thể để thủ công (3) ở after callback của model.
  • (2) có thể để ở after_find/after_materialize của model.
  • Cache ở cấp cao nhất có thể. Lần mò từ thấp lên cao (DB object -> fragment -> action -> page), nếu cache được ở cấp cao hơn thì cache ở đó. Nếu các khối HTML lồng nhau, thì cache khối càng ở ngoài càng tốt.
  • Đặt tên key kèm tiền tố, ví dụ fragments/xxx/yyy.
  • Cache lưu trong memory (memcached thì OK) thích hợp khi chạy trong chế độ development vì tự mất khi tắt web server, nhưng không thích hợp khi chạy trong chế độ production vì thường phải chạy nhiều process, mà các process sẽ chứa cache khác nhau khi một process nào đó expire.
  • Object gì cũng lưu được trong memory. Nhưng để lưu được xuống tập tin hay vào DB, nó phải có thể serialize (dump, marshal) được thành chuỗi kí tự. Do đó nếu không cẩn thận thì chương trình chạy được trong chế độ developement nhưng lại lỗi khi chạy trong chế độ production.

Tham khảo

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Ngoc Dao

102 bài viết.
252 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
56 6
Làm thế nào để nâng cấp trang web mà không làm gián đoạn dịch vụ? Đây là câu hỏi phỏng vấn các công ty lớn thường hỏi khi bạn xin vào vị trí làm lậ...
Ngoc Dao viết gần 2 năm trước
56 6
White
32 0
Bài viết này giải thích sự khác khác nhau giữa hai ngành khoa học máy tính (computer science) và kĩ thuật phần mềm (software engineering), hi vọng ...
Ngoc Dao viết gần 2 năm trước
32 0
White
28 1
Nếu là team leader, giám đốc công ty hay tướng chỉ huy quân đội, vấn đề cơ bản bạn gặp phải là “hướng mọi người đi theo con đường bạn chỉ ra”. Thử...
Ngoc Dao viết gần 2 năm trước
28 1
Bài viết liên quan
Male avatar
22 2
Đây là hai khái niệm không mới nhưng lại rất dễ gây nhầm lẫn. Khi thực hiện free m, hẳn bạn đã từng thấy các tham số buffer và cache này. total...
manhdung viết gần 2 năm trước
22 2
White
2 0
(Ảnh) Memcached là ban đầu là một ứng dụng Linux, nhưng vì Memcached là mã nguồn mở nên đã được các nhà lập trình phát triển cho nền tảng Windows ...
Võ Nhật Nam viết 1 năm trước
2 0
White
48 8
Memoize là một kĩ thuật cache lại giá trị trả về của các hàm dựa trên tham số truyền vào nó. Kĩ thuật này có thể áp dụng trên mọi ngôn ngữ lập trì...
Huy Trần viết 11 tháng trước
48 8
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
102 bài viết.
252 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!