مقدمة: لماذا يغير التخزين المؤقت المتقدم كل شيء
\nفي البنية الحديثة عالية التحميل، تعد سرعة الاستجابة وتقليل الحمل على قاعدة البيانات من المهام الرئيسية. لم يعد التخزين المؤقت في C# (.NET) مجرد حفظ للنتيجة: بل أصبح نظامًا معقدًا لإدارة الحالة ووقت الحياة واتساق البيانات. على المستوى المتقدم، يجب على المطور الاختيار بين Redis وMemcached والحلول المضمنة اعتمادًا على السيناريو.
\nفي هذه المقالة، سنقوم بتحليل ثلاثة أساليب رئيسية للتخزين المؤقت في النظام البيئي .NET، ومقارنة أدائها، وتعقيد التنفيذ، والأخطاء الشائعة. ستتعلم كيفية إعداد التخزين المؤقت الموزع باستخدام Redis، وتحسين Memcached للأحمال العالية، ومتى يكون التخزين المؤقت المضمن IMemoryCache هو الحل الأفضل.
التخزين المؤقت المضمن في .NET: IMemoryCache وIDistributedCache
\nIMemoryCache — تخزين مؤقت محلي سريع
\nالتخزين المؤقت المضمن IMemoryCache من مساحة الأسماء Microsoft.Extensions.Caching.Memory هو الحل الأمثل لتطبيق واحد. يقوم بتخزين البيانات في ذاكرة الوصول العشوائي (RAM) للعملية، مما يوفر أقل زمن وصول.
// التسجيل في Startup.cs أو Program.cs\nbuilder.Services.AddMemoryCache();\n\n// الاستخدام في الخدمة\npublic class ProductService\n{\n private readonly IMemoryCache _cache;\n\n public ProductService(IMemoryCache cache)\n {\n _cache = cache;\n }\n\n public async Task<Product> GetProductAsync(int id)\n {\n string cacheKey = $"product_{id}";\n if (!_cache.TryGetValue(cacheKey, out Product product))\n {\n product = await _repository.GetProductByIdAsync(id);\n var cacheEntryOptions = new MemoryCacheEntryOptions()\n .SetAbsoluteExpiration(TimeSpan.FromMinutes(5))\n .SetSlidingExpiration(TimeSpan.FromMinutes(1))\n .SetPriority(CacheItemPriority.High);\n\n _cache.Set(cacheKey, product, cacheEntryOptions);\n }\n return product;\n }\n}\n\nالإيجابيات: زمن وصول شبكي صفري، سهولة الإعداد، دعم انتهاء الصلاحية المنزلق والمطلق.
\nالسلبيات: لا يعمل عند التوسع إلى عدة خوادم؛ محدود بحجم ذاكرة الوصول العشوائي (RAM) للعملية.
\n\nIDistributedCache — تجريد للتخزين المؤقت الموزع
\nتتيح الواجهة IDistributedCache التبديل بسهولة بين Redis أو SQL Server أو NCache دون تغيير منطق الأعمال. التطبيق الافتراضي هو MemoryDistributedCache (محلي)، ولكن عادةً ما يتم اختيار Redis للإنتاج.
// تسجيل تطبيق Redis\nbuilder.Services.AddStackExchangeRedisCache(options =>\n{\n options.Configuration = "localhost:6379";\n options.InstanceName = "SampleInstance";\n});\n\n// الاستخدام\npublic async Task SetCacheAsync(string key, byte[] data)\n{\n var cache = context.RequestServices.GetRequiredService<IDistributedCache>();\n await cache.SetAsync(key, data, new DistributedCacheEntryOptions\n {\n AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1)\n });\n}\n\nالميزة الرئيسية هي التوحيد: تكتب الكود مرة واحدة، ويتغير مزود التخزين المؤقت من خلال التكوين.
\n\nRedis في C#: تقنيات وأنماط متقدمة
\nالاتصال وتجميع الاتصالات
\nللعمل مع Redis في .NET، يتم استخدام مكتبة StackExchange.Redis. بدلاً من إنشاء اتصال جديد في كل مرة، استخدم تعدد الإرسال (multiplexing) — اتصال واحد للتطبيق بأكمله.
\n// مفردة عالمية\npublic static ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost:6379,abortConnect=false");\n\n// الحصول على قاعدة البيانات\nIDatabase db = redis.GetDatabase(0);\n\n// العمليات الأساسية\nawait db.StringSetAsync("user:1", "John Doe", TimeSpan.FromMinutes(30));\nstring name = await db.StringGetAsync("user:1");\n\n
المدونات
توصيات الكتب
اقرأ أيضًا