التخزين المؤقت المتقدم في C#: Redis وMemcached والحلول المضمنة

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة: لماذا يغير التخزين المؤقت المتقدم كل شيء

\n

في البنية الحديثة عالية التحميل، تعد سرعة الاستجابة وتقليل الحمل على قاعدة البيانات من المهام الرئيسية. لم يعد التخزين المؤقت في C# (.NET) مجرد حفظ للنتيجة: بل أصبح نظامًا معقدًا لإدارة الحالة ووقت الحياة واتساق البيانات. على المستوى المتقدم، يجب على المطور الاختيار بين Redis وMemcached والحلول المضمنة اعتمادًا على السيناريو.

\n

في هذه المقالة، سنقوم بتحليل ثلاثة أساليب رئيسية للتخزين المؤقت في النظام البيئي .NET، ومقارنة أدائها، وتعقيد التنفيذ، والأخطاء الشائعة. ستتعلم كيفية إعداد التخزين المؤقت الموزع باستخدام Redis، وتحسين Memcached للأحمال العالية، ومتى يكون التخزين المؤقت المضمن IMemoryCache هو الحل الأفضل.

\n\n

التخزين المؤقت المضمن في .NET: IMemoryCache وIDistributedCache

\n

IMemoryCache — تخزين مؤقت محلي سريع

\n

التخزين المؤقت المضمن IMemoryCache من مساحة الأسماء Microsoft.Extensions.Caching.Memory هو الحل الأمثل لتطبيق واحد. يقوم بتخزين البيانات في ذاكرة الوصول العشوائي (RAM) للعملية، مما يوفر أقل زمن وصول.

\n
// التسجيل في 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\n

IDistributedCache — تجريد للتخزين المؤقت الموزع

\n

تتيح الواجهة IDistributedCache التبديل بسهولة بين Redis أو SQL Server أو NCache دون تغيير منطق الأعمال. التطبيق الافتراضي هو MemoryDistributedCache (محلي)، ولكن عادةً ما يتم اختيار Redis للإنتاج.

\n
// تسجيل تطبيق 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\n

Redis في 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

المدونات

توصيات الكتب