Xin chào mọi người!
Hôm nay mình sẽ giới thiệu cơ bản về memory cache trong lập trình nói chung và C#(.net) nói riêng. Bài viết chỉ mang tính chất giới thiệu các khái niệm căn bản.
Hy vọng sẽ được thảo luận cùng anh em. Không để chờ lâu bắt đầu luôn nào.
1. Memory cache là gì:
In-memory cache sử dụng bộ nhớ của máy server để lưu trữ data. Những data nào thường được lưu cache thỏa mãn 2 yếu tố: data được truy cập thường xuyên và ít thay đổi. Mục đích của sử dụng memory cache hay bất kỳ loại cache nào là đều muốn cải thiện hiệu suất chương trình.
Ví dụ: lấy ra danh sách 100 sản phẩm bán chạy mỗi tháng. (dữ liệu này thỏa mãn tiêu chí ít thay đổi (1 tháng thay đổi 1 lần) + truy cập thường xuyên khi người dùng filter danh sách sản phẩm bán chạy). Ta có thể lưu cache cho data này để giảm thời gian truy cập xuống database để lấy dữ liệu.
Lưu ý: In-memory cache phù hợp cho 1 server duy nhất hoặc nhiều server có sử dụng sticky sessions.
2. Sticky sessions
Chỗ này mình sẽ giải thích sơ qua sticky session là gì? (Phần này liên quan đến kiến thức về load balancing)
Sticky session là một trong những tính năng cơ bản của load balancing cho phép định tuyến một máy chủ đơn lẻ cho một người dùng cụ thể, dựa trên HTTP session hoặc IP của họ.
Tại sao mình phải lưu ý vấn đề ở trên:
- Nếu chỉ có 1 máy server thì khi ta lưu cache chỉ lưu trên bộ nhớ của máy server duy nhất đó => không xảy ra vấn đề gì.
- Trong trường hợp có nhiều máy server (thông thường các hệ thống lớn đều xài multiple servers). Server A, B, C, D… Khi ta lưu cache thì ta sẽ chỉ lưu ở một máy server A. Vậy khi lấy cache ra làm sao biết được ta sẽ lấy ở máy server nào trong nhiều servers. Sticky session sẽ giúp ta làm việc đó.
Thêm 1 lưu ý khi sử dụng nếu ta lưu quá nhiều memory cache thì sẽ tốn dung lượng lưu trữ dẫn đến server bị chậm.
3. Types of cache memory
-
Level 1: Mức đầu tiền hay còn gọi là primary cache. Với loại cache này sẽ được lưu vào chính bản thân cpu nên có tốc độ tưởng đương tốc độ cpu. Ví dụ như cpu có 4 core thì mỗi core sẽ có 1 bộ đệm riêng. Kích thước bộ nhớ nằm khoảng 2KB đến 64KB
-
Level 2: mức thứ hai hay còn gọi là Secondary Cache. Bộ nhớ cấp 2 này có thể nằm bên trong cpu hoặc ngoài cpu. Tất cả các core của cpu có thể có bộ nhớ đệm cấp 2 riêng biệt hoặc chia sẻ bộ nhớ đệm cấp 2 với nhau. Trong trường hợp nằm ngoài cpu thì nó được kết nối với cpu qua 1 bus có tốc độ rất cao. Kích thước bộ nhớ đệm này khoảng 256KB đến 512KB. Về tốc độ chúng chậm hơn bộ nhớ đệm L1
-
Level 3: main cache. Không phải tất cả bộ xử lý đều có bộ nhớ đệm này. Một số high processor có thể có loại này để năng cao hiệu suất bộ nhớ đệm cấp 1 và cấp 2. Nằm ngoài cpu và chia sẻ giữa các core của cpu. Dung lượng từ 1MB tới 8MB. Mặc dù chậm hơn L1 và L2 nhưng nó nhanh hơn bộ nhớ RAM
4. Cách CPU tìm dữ liệu trong cache
Khi CPU cần dữ liệu, trước hết, nó tìm bên trong bộ đệm L1. Nếu nó không tìm thấy gì trong L1, nó sẽ tìm bên trong bộ đệm L2.
Nếu một lần nữa, nó không tìm thấy dữ liệu trong bộ đệm L2, nó sẽ tìm trong bộ đệm L3.
Nếu dữ liệu được tìm thấy trong bộ nhớ đệm, thì nó được gọi là lần truy cập bộ nhớ cache.
Ngược lại, nếu dữ liệu không được tìm thấy bên trong bộ nhớ cache, nó được gọi là lỗi bộ nhớ cache. Nếu dữ liệu không có sẵn trong bất kỳ bộ nhớ đệm nào, nó sẽ nằm trong Bộ nhớ truy cập ngẫu nhiên (RAM).
Nếu RAM cũng không có dữ liệu, thì nó sẽ lấy dữ liệu đó từ Ổ đĩa cứng.
5. Sử dụng memory cache trong .net core
Trong .net core có hỗ trợ sẵn memory cache(IMemoryCache) vậy nên ta không cần phải xài third party.
• Cấu hình service memory cache để sử dụng:
• Sử dụng dependence injection để inject IMemoryCache
• Set data cho cache bao gồm key và value(value có thể là kiểu int, string, double, object…)
Tham số đầu tiền là key, tham số thứ 2 là value.
• Lấy dữ liệu từ cache ta dùng phương thức get
• Sử dụng GetOrCreate để tạo 1 cache mới nếu chưa tồn tại
GetOrCreate giúp lấy ra dữ liệu của cache, nếu cache đó Không tồn tại thì thêm mới vào. Code rất ngắn gọn và tiện lợi.
• Sử dụng tryGet để kiểm tra sự tồn tại của key
Sử dụng hàm tryGet để lấy ra giá trị của cache item sẽ trả về Boolean. True nghĩa là key đã tồn tại, ngược lại trả về failse. Đồng thời nếu trả về true thì sẽ có một tham số out để lấy value ra sử dụng.
• Xóa cache
• AbsoluteExpiration và SlidingExpiration
Ngoài cách dùng phương thức Remove để xóa cache ta có thể thiết lập thời gian hết hạn của cache.
MemoryCacheEntryOptions cho phép thiết lập các lựa chọn của cache.
AbsoluteExpiration: Cache sẽ được gỡ bỏ tại một thời điểm xác định.
SlidingExpiration: cache sẽ hết hạn sau 1 khoảng thời gian không truy cập, kể cả nó còn thời hạn AbsoluteExpiration
• Độ ưu tiên của các item trong cache MemoryCacheEntryOptions cho phép thiết lập độ ưu tiền của các item trong cache: có 4 độ ưu tiên:
Đối với trường hợp bộ nhớ lưu trữ bị đầy thì sẽ ưu tiền xóa cache có độ ưu tiền từ thấp đến cao. Riêng NeverRemove sẽ không bao giờ bị xóa.
• Calback khi item trong cache bị gỡ bỏ
Ta có thể gỡ bỏ cache bằng phương thức remove, thiết lập option SlidingExpiration hoặc AbsoluteExpiration. Trong trường hợp item bị gỡ bỏ và bạn muốn thông báo thông tin về item trong cache bị gỡ bỏ ta dùng RegisterPostEvictionCallback để đăng ký callback function
2 tham số đầu tiền là key và value, thêm số thứ 2 là lý do bị gỡ bỏ.
EvictionReason là 1 enum bao gồm các lý do:
Demo:
Source demo: https://github.com/TechMarDay/Cache
Tham khảo: https://docs.microsoft.com/en-us/aspnet/core/performance/caching/memory?view=aspnetcore-5.0 https://fullstack.edu.vn/blog/co-ban-memory-cache-la-gi.html