الكاش والإخلاء: عندما يمتلئ الصندوق السحري – دليل شامل لخوارزميات التخزين المؤقت

استمع للبودكاست حوار شيق بين لمى وأبو عمر
0:00 / 0:00

الكاش والإخلاء: عندما يمتلئ الصندوق السحري

بتذكر مرة، كنت شغال على تطبيق لبيع التذاكر. كل شي كان تمام، بس فجأة، صار التطبيق بطيء بشكل فضيع وقت الذروة. المستخدمين صاروا يشتكوا، والضغط زاد عليّ. قعدت أدور وين المشكلة، واكتشفت إنه قاعدة البيانات كانت تحت ضغط كبير. الحل؟ الكاش! بس الكاش مساحته محدودة، وهون بلشت قصة خوارزميات الإخلاء. كيف بدي اختار البيانات اللي لازم تضل بالكاش، والبيانات اللي لازم تنحذف؟ هذا المقال رح يجاوب على هذا السؤال، ونستكشف سوا أشهر الخوارزميات المستخدمة.

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

لكن الصندوق السحري مش كبير، ولازم نفضي مكان للأشياء الجديدة. هون بيجي دور “سياسات الإخلاء” (Eviction Policies): لما يمتلئ الكاش، أي البيانات لازم نحذفها عشان نفتح مجال لبيانات جديدة؟

خوارزميات الإخلاء الأساسية

في كتير خوارزميات، بس رح نركز على الأساسية والأكثر استخداماً:

LRU (Least Recently Used) – الأقل استخداماً مؤخراً

هاي الخوارزمية بسيطة ومنطقية. بتفترض إنه البيانات اللي استخدمناها مؤخراً، رح نستخدمها مرة تانية قريباً. يعني، بتحافظ على البيانات “الطازة” وبترمي القديمة.

الآلية:

  • بتحتفظ بقائمة مرتبة بالعناصر.
  • لما نوصل لعنصر، بننقله لبداية القائمة (يعني بنخليه “الأحدث”).
  • لما يمتلئ الكاش، بنحذف العنصر الموجود في نهاية القائمة (الأقدم).

# مثال بسيط لـ LRU في Python
from collections import OrderedDict

class LRUCache:
    def __init__(self, capacity: int):
        self.capacity = capacity
        self.cache = OrderedDict()

    def get(self, key: int) -> int:
        if key not in self.cache:
            return -1
        else:
            self.cache.move_to_end(key) # تحديث آخر استخدام
            return self.cache[key]

    def put(self, key: int, value: int) -> None:
        if key in self.cache:
            self.cache[key] = value
            self.cache.move_to_end(key)
        else:
            self.cache[key] = value
            if len(self.cache) > self.capacity:
                self.cache.popitem(last=False) # حذف الأقدم

نقاط الضعف:

بتعاني بشدة في حالات “المسح الشامل” (Full Scans). تخيل إنك بتعمل تقرير بيقرا قاعدة البيانات كلها مرة وحدة. الـ LRU رح تطرد كل البيانات المهمة والمتكررة من الكاش، وتحط بدالها بيانات التقرير اللي ما رح تستخدمها مرة تانية. هيك التطبيق رح يصير أبطأ (Cache Pollution).

نصيحة من أبو عمر: قبل ما تستخدم LRU، فكر منيح بطبيعة البيانات اللي بتتعامل معها. لو عندك عمليات مسح شاملة، يمكن مش الخيار الأفضل.

LFU (Least Frequently Used) – الأقل استخداماً

هاي الخوارزمية بتركز على “تكرار” الاستخدام بدل ما تركز على حداثته. بتحتفظ بعداد لكل عنصر، وكل ما استخدمنا العنصر، بنزيد العداد. لما يمتلئ الكاش، بنطرد العنصر اللي عنده أقل عداد.

المزايا:

  • مقاومة لعمليات المسح الشامل، لأنه البيانات الجديدة اللي بنستخدمها مرة وحدة بس، العداد تبعها رح يكون قليل (1)، فما رح تطرد البيانات المهمة اللي العداد تبعها عالي.

العيوب:

  • معقدة التنفيذ، وبتستهلك ذاكرة إضافية عشان نحفظ العدادات لكل عنصر.
  • بتعاني من “التقادم” (Staleness): عنصر كان مشهور جداً الأسبوع الماضي، رح يضل بالكاش حتى لو ما عدنا بحاجته اليوم، لأنه العداد تبعه عالي.

نصيحة من أبو عمر: الـ LFU بتنفع لما يكون عندك بيانات بتتكرر كتير، بس بدك تنتبه لمشكلة التقادم. ممكن تستخدم طريقة عشان تقلل قيمة العدادات مع مرور الوقت (Aging) عشان تحل هاي المشكلة.

W-TinyLFU: أحدث التقنيات في عالم الكاش

الـ W-TinyLFU (Window TinyLFU) هي أحدث ما توصلت إليه هندسة الكاش، وهي مستخدمة في مكتبات قوية زي Caffeine (Java) و Ristretto (Go).

فلسفة القبول (Admission Policy):

بدل ما نقبل أي عنصر جديد بالكاش، الـ TinyLFU بتسأل: “هل هذا العنصر الجديد بستاهل نخزنه أكثر من العنصر اللي رح نطرده؟”. بتستخدم مخطط Count-Min Sketch (هيكل احتمالي) عشان تقدر التكرار بذاكرة قليلة جداً.

تصميم النافذة (Window Design):

الـ W-TinyLFU بتتكون من قسمين:

  • نافذة صغيرة (LRU): بتستقبل العناصر الجديدة وبتعطيها فرصة تثبت شعبيتها (بتحل مشكلة LFU مع العناصر الجديدة).
  • الكاش الرئيسي (SLRU): بيتم ترقية العناصر إليه بناءً على التكرار المقدر بواسطة TinyLFU.

النتيجة:

معدل إصابة (Hit Rate) بيقارب المثالية، مع حماية ضد التلوث ومقاومة للمسح الشامل.

نصيحة من أبو عمر: لو بتدور على حل كاش قوي وحديث، الـ W-TinyLFU خيار ممتاز. صحيح إنه تنفيذه معقد، بس المكتبات الجاهزة بتسهل الموضوع.

الخلاصة

اختيار خوارزمية الإخلاء المناسبة بيعتمد على طبيعة التطبيق والبيانات اللي بتتعامل معها. الـ LRU بسيطة وسريعة، بس بتعاني من المسح الشامل. الـ LFU أفضل في حالات التكرار، بس بدها ذاكرة إضافية. الـ W-TinyLFU هي الأحدث والأكثر تطوراً، بس تنفيذها معقد. 💡

نصيحة أخيرة: قبل ما تختار أي خوارزمية، حلل طبيعة البيانات اللي بتتعامل معها، وجرب الخوارزميات المختلفة وشوف أي وحدة بتعطي أفضل أداء لتطبيقك. ولا تنسى تراقب أداء الكاش باستمرار عشان تتأكد إنه بيشتغل بالشكل المطلوب. بالتوفيق! 👍

أبو عمر

سجل دخولك لعمل نقاش تفاعلي

كافة المحادثات خاصة ولا يتم عرضها على الموقع نهائياً

آراء من النقاشات

لا توجد آراء منشورة بعد. كن أول من يشارك رأيه!

آخر المدونات

التوسع والأداء العالي والأحمال

تطبيقنا كان ينهار في أوقات الذروة: كيف أنقذتنا ‘موازنة الأحمال’ (Load Balancing) من جحيم فشل السيرفر الواحد؟

أشارككم قصة حقيقية من الميدان، يوم كاد تطبيقنا أن ينهار تحت ضغط المستخدمين في وقت الذروة. سأروي لكم كيف تحولنا من الفوضى إلى النظام بفضل...

17 أبريل، 2026 قراءة المزيد
التكنلوجيا المالية Fintech

رحلة التحقق من الهوية: كيف أنقذنا الذكاء الاصطناعي من جحيم التسجيل اليدوي في عالم الـFintech

بصفتي مطور برمجيات، عانيت شخصيًا من كوابيس التحقق من الهوية اليدوية (KYC). في هذه المقالة، أسرد لكم كيف حولنا هذه العملية البيروقراطية المعقدة إلى تجربة...

17 أبريل، 2026 قراءة المزيد
ادارة الفرق والتنمية البشرية

مقابلاتنا الفردية كانت استجوابًا: كيف أنقذتنا ‘الأجندة التعاونية’ من جحيم اللقاءات عديمة الجدوى؟

أشارككم تجربتي كقائد فريق تقني، وكيف حولت الاجتماعات الفردية (One-on-Ones) من جلسات استجواب مملة إلى محادثات مثمرة وبناءة باستخدام أداة بسيطة وفعالة: الأجندة التعاونية. اكتشف...

17 أبريل، 2026 قراءة المزيد
اختبارات الاداء والجودة

اختباراتنا كانت خضراء والكود مليء بالثغرات: كيف أنقذنا ‘الالاختبار الطفري’ من جحيم الثقة الزائفة؟

أشارككم قصة حقيقية حول كيف خدعتنا نسبة تغطية الاختبارات (Test Coverage) التي بلغت 100%، وكيف كان "الاختبار الطفري" (Mutation Testing) هو البطل الذي كشف ضعف...

17 أبريل، 2026 قراءة المزيد
نصائح برمجية

مدخلاتنا كانت قنابل موقوتة: كيف أنقذتنا “حراسة الشروط” (Guard Clauses) من جحيم الشروط المتداخلة؟

كود يتسبب بكارثة في نظام حيوي، والمشكلة؟ شروط متداخلة معقدة. في هذه المقالة، أشارككم قصة كيف أنقذنا أسلوب "حراسة الشروط" (Guard Clauses) من هذا الجحيم،...

17 أبريل، 2026 قراءة المزيد
​معمارية البرمجيات

تطبيقنا المونوليث كان وحشًا: كيف أنقذنا ‘نمط التين الخانق’ من جحيم التحديث المستحيل؟

أتذكر جيدًا ذلك الوحش البرمجي الضخم الذي عملنا عليه، تطبيق "مونوليث" أصبح تحديثه كابوسًا. في هذه المقالة، أسرد لكم تجربتي وكيف أنقذنا نمط "التين الخانق"...

17 أبريل، 2026 قراءة المزيد
البودكاست