Trong nhiều năm, tôi luôn được dạy rằng caching là một công cụ để tăng tốc phần mềm. Với việc cân nhắc kỹ lưỡng về tính nhất quán, caching giúp bạn không phải truy cập vào cơ sở dữ liệu backend, máy chủ API hay ổ SSD mỗi khi cần đọc dữ liệu, thay vào đó có thể lấy từ bộ nhớ – nơi nhanh hơn nhiều. Như vậy, caching được xem là một giải pháp tối ưu hiệu suất.
Mục lục
Một góc nhìn khác về caching
Tuy nhiên, sau thời gian làm việc với các hệ thống liên quan đến di chuyển dữ liệu giữa bộ nhớ đối tượng, ổ đĩa và RAM, tôi nhận ra rằng cách hiểu trên về caching là chưa đầy đủ. Thực chất, caching không chỉ là công cụ tăng tốc mà còn là phương pháp giúp phần mềm trở nên đơn giản hơn.
Điều khiến tôi luôn băn khoăn là tại sao chúng ta lại sử dụng các thuật toán caching có sẵn như LRU, LFU… Trên thực tế, mỗi ứng dụng có đặc thù riêng và cần chiến lược caching phù hợp. Tại sao phải phụ thuộc vào các “chính sách” chung chung thay vì tự kiểm soát việc lưu trữ dữ liệu? Khi truy xuất dữ liệu, chúng ta hoàn toàn có thể xác định liệu nó có cần thiết trong tương lai gần hay không, từ đó quyết định thời gian lưu trữ phù hợp.
Caching như một lớp trừu tượng
Khi tiếp cận caching với tư duy “Tôi sẽ tự quản lý việc lưu trữ dữ liệu vào bộ nhớ nhanh” thay vì “Tôi sẽ truy cập ổ đĩa mỗi lần cần dữ liệu”, bạn sẽ nhận ra caching thực chất là một lớp trừu tượng hơn là công cụ tối ưu.
Hai chương trình có thể có hành vi tương tự nhưng cấu trúc khác biệt hoàn toàn, trong đó một bên sử dụng caching như lớp trừu tượng, còn bên kia xử lý rõ ràng các tầng lưu trữ.
Hãy xem xét các hệ thống cơ sở dữ liệu – nơi phải quản lý chặt chẽ việc di chuyển dữ liệu giữa bộ nhớ và ổ đĩa. Chúng hoạt động theo nguyên tắc: mọi dữ liệu được đều được đưa vào bộ nhớ trước khi xử lý. Tương tự, hệ điều hành cũng đưa dữ liệu vào page cache trước khi truy cập (trừ khi sử dụng direct IO).
(Dù vậy, với sự phát triển của SSD siêu nhanh và các API tối ưu, cách tiếp cận này có thể thay đổi trong tương lai.)
Lợi ích của caching như lớp trừu tượng
Quan điểm này nhắc nhở chúng ta rằng hoàn toàn có thể thiết kế hệ thống đáp ứng yêu cầu “truy cập nhanh đến dữ liệu cần thiết” một cách gọn gàng, với các thành phần được tách biệt rõ ràng.
Tất nhiên, lớp trừu tượng này cũng có nhược điểm, điển hình là các vấn đề với OS page cache và fsync do sử dụng sai cách. Điều này đặt ra câu hỏi: “Liệu các mối quan tâm này có thực sự tách biệt?”
Hiểu đúng về thuật toán caching
Khi nghe ai đó nói về việc nghiên cứu sâu các thuật toán caching, tôi thường nghĩ đó là sự lãng phí thời gian. Vấn đề cốt lõi không phải là “làm thế nào để đánh bại hệ thống caching”, mà là “làm sao để dữ liệu luôn ở bộ nhớ nhanh khi cần”.
Nhưng có hai sự thật khiến quan điểm này không chính xác:
- Trong thực tế, việc truy cập dữ liệu khó dự đoán đến mức buộc phải dựa vào heuristic. Ý tưởng về một chiến lược di chuyển dữ liệu tùy chỉnh thông minh hơn chỉ là ảo tưởng.
- Caching thực sự là một lớp trừu tượng tuyệt vời, xứng đáng được nghiên cứu kỹ lưỡng để hoạt động hiệu quả hơn. Bản thân caching không thất bại, mà chỉ có cách triển khai không phù hợp.
Có lẽ đây là “lời nguyền” của những lớp trừu tượng thành công: chúng trở nên vô hình cho đến khi gây ra vấn đề, khiến chúng ta dễ đánh giá thấp giá trị thực sự, thậm chí không nhận ra chúng là lớp trừu tượng.