التخزين المؤقت في C#: Redis وMemcached والحلول المضمنة — دليل شامل
في تطوير الويب الحديث، يُعد أداء التطبيق أحد العوامل الرئيسية للنجاح. يسمح التخزين المؤقت بتقليل الحمل على قاعدة البيانات بشكل كبير وتسريع استجابة النظام. في نظام C# (.NET)، تتوفر للمطور ثلاثة أساليب رئيسية: التخزين المؤقت المضمن في الذاكرة (IMemoryCache)، والحلول الموزعة (IDistributedCache)، وخوادم التخزين المؤقت الخارجية مثل Redis وMemcached. في هذه المقالة، سنقوم بتحليل كل منها من الناحية النظرية إلى الأمثلة العملية للكود.
1. التخزين المؤقت المضمن في .NET: IMemoryCache
التخزين المؤقت المضمن هو أبسط وأسرع طريقة للتخزين المؤقت للبيانات. في ASP.NET Core، يتم تنفيذه من خلال الواجهة IMemoryCache. يتم تخزين البيانات في الذاكرة العشوائية لعملية واحدة، مما يضمن أقل تأخير.
متى يتم الاستخدام:
- البيانات لا تحتاج إلى المزامنة بين عدة خوادم.
- حجم البيانات المخزنة مؤقتًا صغير.
- مطلوب أقصى أداء دون إعداد خدمات خارجية.
مثال على التنفيذ:
using Microsoft.Extensions.Caching.Memory;
public class WeatherService{ private readonly IMemoryCache _cache;
public WeatherService(IMemoryCache cache) { _cache = cache; }
public async Task<WeatherData> GetWeatherAsync(string city) { string cacheKey = $"weather_{city}";
if (!_cache.TryGetValue(cacheKey, out WeatherData data)) { // البيانات غير موجودة في الذاكرة المؤقتة — نقوم بتحميلها من مصدر خارجي data = await FetchWeatherFromApi(city);
// إعدادات الذاكرة المؤقتة: مدة الصلاحية 5 دقائق var cacheOptions = new MemoryCacheEntryOptions() .SetAbsoluteExpiration(TimeSpan.FromMinutes(5));
_cache.Set(cacheKey, data, cacheOptions); }
return data; }
private async Task<WeatherData> FetchWeatherFromApi(string city) { // محاكاة استدعاء API خارجي await Task.Delay(1000); return new WeatherData { City = city, Temperature = 22.5 }; }}
public class WeatherData{ public string City { get; set; } public double Temperature { get; set; }}الطرق الرئيسية: TryGetValue وSet وRemove. من المهم تذكر أن IMemoryCache غير مناسب للهندسة المعمارية القائمة على الخدمات المصغرة.
2. التخزين المؤقت الموزع: IDistributedCache وموفروه
للتطبيقات التي تعمل على عدة خوادم، يلزم التخزين المؤقت الموزع. في .NET، يتم تجريده من خلال الواجهة IDistributedCache. وهذا يسمح بتغيير الموفّر (Redis، SQL Server، NCache) بسهولة دون تغيير منطق الأعمال.
الطرق الرئيسية:
GetAsync / SetAsync— للعمل مع البايتات.GetStringAsync / SetStringAsync— للبيانات النصية.RefreshAsync— إعادة تعيين مؤقت مدة الصلاحية المنزلقة.RemoveAsync— حذف السجل.
مثال مع Redis:
// في Program.cs نقوم بتسجيل الموفّرbuilder.Services.AddStackExchangeRedisCache(options =>{ options.Configuration = "localhost:6379"; options.InstanceName = "SampleApp";});
// الاستخدام في الخدمةpublic class ProductService{ private readonly IDistributedCache _cache;
public ProductService(IDistributedCache cache) { _cache = cache; }
public async Task<Product> GetProductAsync(int id) { string cacheKey = $"product_{id}"; string cachedData = await _cache.GetStringAsync(cacheKey);
if