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

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

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

ابدأ الدورة

التخزين المؤقت في JavaScript: Redis وMemcached والحلول المدمجة: من الألف إلى الياء



في تطوير الويب الحديث باستخدام Node.js، يعتمد أداء التطبيق بشكل مباشر على سرعة الوصول إلى البيانات. كل طلب إلى قاعدة البيانات أو API خارجي أو نظام ملفات يُحدث تأخيراً يتراكم مع زيادة الحمل. التخزين المؤقت هو استراتيجية تخزين مؤقت للبيانات المطلوبة بشكل متكرر في مخزن سريع، مما يسمح بتقليل وقت الاستجابة بمقدار 10 إلى 100 مرة. في هذه المقالة، سنناقش ثلاثة أساليب للتخزين المؤقت في JavaScript: الحلول المدمجة (Map وWeakMap ووحدة node-cache)، والأنظمة الموزعة Redis وMemcached، بالإضافة إلى توليفاتها.



لماذا نحتاج التخزين المؤقت في Node.js؟

الهدف الرئيسي للتخزين المؤقت هو تقليل الحمل على الموارد البطيئة (قواعد البيانات، الأقراص، الخدمات الخارجية) وتسريع إرسال البيانات للمستخدم. في تطبيق ويب نموذجي على Node.js، يمكن للكاش تخزين:

  • نتائج الاستعلامات المعقدة لقاعدة البيانات (التجميعات، JOIN).
  • الردود من APIs الخارجية (الطقس، أسعار العملات، البيانات الجغرافية).
  • جلسات المستخدم ورموز المصادقة.
  • أجزاء HTML أو صفحات كاملة (تخزين مؤقت SSR).
  • ملفات التكوين والقوالب.

بدون التخزين المؤقت، كل طلب متكرر لنفس البيانات يؤدي إلى تكرار العمل. مع الكاش، يتم استرجاع البيانات من الذاكرة العشوائية في ميكروثانية.



الحلول المدمجة للتخزين المؤقت في JavaScript

للسيناريوهات البسيطة أو التطبيقات أحادية الخيط، يمكن استخدام هياكل البيانات الأصلية في JavaScript. لا تتطلب تثبيت حزم خارجية، ولكن لها قيود على الحجم وعمر البيانات.



1. Map وWeakMap

كائن Map هو مجموعة من أزواج المفتاح-القيمة، مثالية للكاش ضمن عملية واحدة. مثال على كاش بسيط مع TTL (وقت الحياة):

class SimpleCache {  constructor(ttl = 60000) {    this.cache = new Map();    this.ttl = ttl;  }

set(key, value) { this.cache.set(key, { value, expiry: Date.now() + this.ttl }); }

get(key) { const item = this.cache.get(key); if (!item) return null; if (Date.now() > item.expiry) { this.cache.delete(key); return null; } return item.value; }

has(key) { return this.get(key) !== null; }}

// الاستخدامconst cache = new SimpleCache(5000); // TTL 5 ثوانٍcache.set('user:123', { name: 'إيفان' });console.log(cache.get('user:123')); // { name: 'إيفان' }

يختلف WeakMap بأن مفاتيحه هي كائنات فقط، ويمكن لمجمع القمامة حذف الإدخالات إذا لم يعد هناك مراجع للكائن المفتاح. هذا مناسب لتخزين عناصر DOM أو الكائنات المؤقتة.



2. وحدة node-cache

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

const NodeCache = require('node-cache');const myCache = new NodeCache({ stdTTL: 100, checkperiod: 120 });

// كتابةmyCache.set('key', { data: 'value' });

// قراءةconst value = myCache.get('key');if (value === undefined) { // خطأ في الكاش - يجب الحصول على البيانات من قاعدة البيانات}

// حذفmyCache.del('key');

الحلول المدمجة مناسبة للتطبيقات المتجانسة أو الخدمات المصغرة ذات النسخة الواحدة. ومع ذلك، عند التوسع إلى عدة عمليات أو خوادم، تصبح البيانات غير متسقة - وهنا نحتاج إلى كاشات موزعة.



Redis: مخزن بيانات قوي في الذاكرة

Redis هو مخزن بيانات عالي الأداء في الذاكرة العشوائية، يدعم السلاسل، التجزئات، القوائم، المجموعات وهياكل بيانات أخرى. بالنسبة لـ Node.js، يتم استخدام حزمة redis أو ioredis. Redis مثالي للتخزين المؤقت بفضل:

  • دعم TTL على مستوى المفتاح (أمر EXPIRE).
  • العمليات الذرية (INC

المدونات

توصيات الكتب