Caching là một kỹ thuật được sử dụng rộng rãi nhằm giảm latency, tăng performance cho hệ thống. Caching xuất hiện ở khắp nơi, từ CPU, OS đến CDN, DNS, web browser. Ở trong chuỗi bài này, tôi chỉ đề cập đến caching trong web application.

Mục lúc nội dung của series này dựa trên sườn của bài blog “A Crash Course in Caching - Part 1” - ByteByteGo [1]. Tôi dư tính sẽ viết 3 bài cho series này, với nội dung như bên dưới.

Caching phần 1. (bài này)

  1. Caching là gì?
    • in memory storage
    • cache hit & miss. cache hit ratio
  2. Cache được dùng ở đâu?
    • memcached, redis
  3. In-process and remote cache

Caching phần 2

  1. Distribted cache
    • modulus sharding
    • range-based sharding
    • consistent hashing
  2. cache replacement and invalidation
    • Cache replacement: LRU, LFU
    • Cache invalidation: TTL,invalidation event

Caching phần 3

  1. cache strategies
    • cache aside
    • read through
    • write around
    • write through
    • write back
    • which strategies do people prefer? Pros and Cons của mỗi loại
  2. caching challenges
    • thundering herd/cache breakdown
    • cache penetration
    • cache avalanche
    • big key
    • hot key
    • data consistency
  3. monitoring and alerts

Nào, cùng bắt đầu bài đầu tiên trong series.

1. What is caching? Caching là gì? [1]

Caching là 1 thành phần sẽ lưu trữ data để phục vụ các request trong tương lai. Thay vì phải truy cập database hoặc một loại các phép tính để có dữ liệu, khi dùng cache, dữ liệu được trả lại ngay lập tức. Điều này giúp giảm latency và cải thiện hiệu năng của hệ thống.

Khi dùng cache, request sẽ tìm kiếm trên cache trước, nếu có thì trả về. Nếu không có, sẽ gọi database.

Vậy cache và storage khác nhau như thế nào? Cache sẽ lưu trữ trong thời gian ngắn và thường chỉ lưu một phần dữ liệu hay được truy cập mà thôi. Cache thường sẽ được lưu trên RAM để đảm bảo tốc độ. Storage sẽ lưu trên đĩa cứng, lưu toàn bộ dữ liệu và được thế kế để lưu trữ dài hạn.

Nếu dữ liệu cần truy cập tồn tại trên cache, ta gọi đó là cache hit. Nếu dữ liệu không có trên cache, ta gọi là cache miss. Hiệu quả của cache thường được đo bằng tỉ lệ cache hit ratio = cache hit / (cache hit + cache miss). Tỉ lệ càng lớn, cache càng hiệu quả. Nếu tỉ lệ này nhỏ, theo tôi là nhỏ hơn 20% thì cache không hiệu quả, bởi nó phải gọi storage liên tục. Cache không có ý nghĩa. Lúc này, cần xem lại việc chọn key hoặc business logic có cho phép cache hay không.

2. Cache được dùng ở đâu? [1]

Với CPU, ta có cache Layer L1, L2, L3. Với OS, ta có page cache, rồi disk cache. Với browswer, ta có browser cache. Ngoài ra còn có cache những static file trên CDN, caching trong database, …

Với web application, có 2 cache system hay dùng là Memcached và Redis. Chúng đều là open-source và có hiệu năng cao.

Caching đem lai hiệu quả trong điều kiện dữ liệu không thay đổi thường xuyên, 1 record được truy cập nhiều lần hay cache kết quả của các phép tính toán. Khi dùng cache, hãy chú trọng tỉ lệ cache hit ratio.

3. In-process and remote cache [2]

In-process cache nghĩa là cache là 1 thành phần của web application. Được deploy chung với web. Mỗi 1 web instance sẽ có 1 cache riêng biệt. Remote cache là cache được lưu trữ ở 1 remote server như Redis hoặc Memcached. Web service thường phải call tới remote server này

In-memory cache sẽ nhanh hơn Remote cache, do không phải gọi network call. Nó cũng tránh được tình trạng bottlenek khi tải cao hoặc khi mạng bị nghẽn, nhất là khi object cần cache lớn trong các task xử lý video, audio, … Tuy nhiên, In-memory cache sẽ gây duplicate dữ liệu khi deploy web application trên nhiều instance. Cũng gây gánh nặng cho việc invalidate cache cùng lúc trên nhiều instance. Ví dụ: nếu ta cache userProfile với id = 1. UserProfile này có thể nằm trên nhiều instance. Nếu ta update thông tin của profile, ta cần invalide cache trên nhiều instance cùng lúc, để đảm bảo dữ liệu được cập nhật mới nhất. Thêm nữa, bởi vì loại cache này dùng RAM của từng server, nên có 1 giới hạn nhất định và thường sẽ nhỏ hơn remote cache.

Remote cache thích hợp cho microservice hơn là In-memory cache. Nhiều web application instance sẽ truy cập cùng 1 chỗ để lấy data từ cache. Lượng thông tin cache được cũng lớn hơn. Hơn nữa, ta cũng có thể thiết kế loại distributed cache, dùng nhiều Redis hoặc Memcached server dể tạo thành 1 cụm cached, có thể cache hằng trăm GB. Vấn đề này sẽ nói ở phần sau. Bởi vì cached data đều nằm 1 chỗ, nên không có nhiều gánh nặng cho việc invalidate cache.

Referene:

  1. https://blog.bytebytego.com/p/a-crash-course-in-caching-part-1
  2. Avoid Using Cache in Your Application or Do It Right