التخزين المؤقت في TypeScript: Redis وMemcached والحلول المدمجة — دليل شامل

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

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

ابدأ الدورة

مقدمة: لماذا نحتاج إلى التخزين المؤقت في TypeScript؟



تتطلب تطبيقات الويب الحديثة سرعة استجابة عالية وأقل حمل ممكن على قواعد البيانات. يُعد التخزين المؤقت أحد أكثر الطرق فعالية لتحقيق ذلك. في بيئة TypeScript (و Node.js)، يتوفر للمطور ثلاثة أساليب رئيسية: الأنظمة الموزعة (Redis, Memcached) والحلول المدمجة (in-memory cache). في هذه المقالة، سنشرح كل منها، ونقدم أمثلة عملية بلغة TypeScript، ونساعدك في اختيار الخيار الأمثل لمشروعك.



يسمح التخزين المؤقت بتخزين البيانات المطلوبة بشكل متكرر في مخزن سريع، مما يتجنب العمليات المكلفة المتكررة (استعلامات قاعدة البيانات، الحسابات، استدعاءات واجهات برمجة التطبيقات الخارجية). يمكن لاستراتيجية التخزين المؤقت الصحيحة تقليل وقت استجابة الخادم بمقدار 10-100 مرة.



1. التخزين المؤقت المدمج في TypeScript (In-Memory)



أبسط طريقة هي تخزين البيانات مباشرة في ذاكرة عملية Node.js. لا يتطلب ذلك خدمات خارجية، وهو مثالي للتطبيقات الصغيرة أو النماذج الأولية.



1.1. استخدام Map و WeakMap



المجموعات المدمجة في JavaScript هي أساس ممتاز لذاكرة تخزين مؤقت بسيطة. مثال على التنفيذ مع TTL (وقت البقاء):



type CacheEntry<T> = {  value: T;  expiresAt: number;};

class SimpleCache<T> { private store = new Map<string, CacheEntry<T>>();

set(key: string, value: T, ttlMs: number = 60000): void { this.store.set(key, { value, expiresAt: Date.now() + ttlMs, }); }

get(key: string): T | undefined { const entry = this.store.get(key); if (!entry) return undefined; if (Date.now() > entry.expiresAt) { this.store.delete(key); return undefined; } return entry.value; }

delete(key: string): boolean { return this.store.delete(key); }

clear(): void { this.store.clear(); }}

// الاستخدامconst userCache = new SimpleCache<object>();userCache.set('user:1', { name: 'أليكسي' }, 30000); // TTL 30 ثانيةconsole.log(userCache.get('user:1'));


1.2. مكتبة node-cache



بالنسبة للحلول الإنتاجية، من الأفضل استخدام مكتبة موثوقة node-cache. توفر إمكانيات متقدمة: التنظيف التلقائي، الإحصائيات، والأحداث.



import NodeCache from 'node-cache';

const myCache = new NodeCache({ stdTTL: 100, checkperiod: 120 });

// حفظ كائنconst success = myCache.set('myKey', { data: 'value' });if (success) console.log('تم حفظ التخزين المؤقت');

// قراءةconst value = myCache.get('myKey');console.log(value); // { data: 'value' }

// الحصول على الإحصائياتconst stats = myCache.getStats();console.log(`الإصابات: ${stats.hits}, الأخطاء: ${stats.misses}`);


المزايا: البساطة، عدم وجود تأخير في الشبكة، لا يتطلب تثبيت خدمات.
العيوب: فقدان التخزين المؤقت عند إعادة تشغيل التطبيق، غير مناسب للأنظمة الموزعة.



2. التخزين المؤقت باستخدام Redis في TypeScript



Redis هو الحل الأكثر شيوعًا للتخزين المؤقت في بيئات الإنتاج. يعمل كخادم منفصل، ويدعم هياكل البيانات المعقدة، ومقاوم لإعادة تشغيل التطبيق.



2.1. توصيل ioredis



مكتبة ioredis هي المعيار الفعلي للعمل مع Redis من TypeScript. تدعم التجميع (clustering)، والنشر/الاشتراك (Pub/Sub)، وخطوط الأنابيب (Pipeline).



import Redis from 'ioredis';

const redis = new Redis({ host: 'localhost', port: 6379, retryStrategy: (times) => Math.min(times * 50, 2000),});

// التحقق من الاتصالredis.on('connect', () => console.log('تم الاتصال بـ Redis'));redis.on('error', (err) => console.error('خطأ Redis:', err));


2.2. مثال على التخزين المؤقت مع TTL



async function getCachedData(key: string): Promise<string | null> {  const cached = await redis.get(key);  if (cached) {    console.log('البيانات من                

المدونات

توصيات الكتب