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

استمع للبودكاست حوار شيق بين لمى وأبو عمر
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 هي الأحدث والأكثر تطوراً، بس تنفيذها معقد. 💡

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

أبو عمر

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

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

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

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

آخر المدونات

​معمارية البرمجيات

كل خدمة تنادي الأخرى مباشرة… حتى انهار كل شيء: كيف أنقذتني المعمارية الموجهة بالأحداث (EDA) من كابوس الاقتران المحكم؟

أشارككم قصة حقيقية عن ليلة كاد فيها نظامنا أن ينهار بالكامل بسبب الاقتران المحكم بين الخدمات. سأشرح لكم كيف كانت المعمارية الموجهة بالأحداث (EDA) هي...

9 مارس، 2026 قراءة المزيد
الحوسبة السحابية

وضعت كل بيضي في سلة AWS… ثم تعطلت المنطقة بأكملها: كيف أنقذتني استراتيجية السحابة المتعددة (Multi-Cloud) من التوقف التام؟

في لحظة توقف فيها كل شيء، تعلمت الدرس الأصعب: الاعتماد على مزود سحابي واحد هو وصفة لكارثة محققة. أشارككم قصتي وكيف كانت استراتيجية السحابة المتعددة...

8 مارس، 2026 قراءة المزيد
التوظيف وبناء الهوية التقنية

تجمدت في مقابلة الترميز المباشر: كيف تعلمت ‘التفكير بصوت عالٍ’ وأنقذت فرصتي الوظيفية؟

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

8 مارس، 2026 قراءة المزيد
التوسع والأداء العالي والأحمال

جدول المستخدمين وصل إلى مليار صف… وقاعدة بياناتي استسلمت: كيف أنقذني تقسيم البيانات (Sharding) من انهيار كامل؟

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

7 مارس، 2026 قراءة المزيد
التكنلوجيا المالية Fintech

نقرة واحدة، خصم مزدوج: كيف أنقذني مفتاح ‘عدم التكرار’ (Idempotency Key) من غضب العملاء وكوابيس التسويات المالية؟

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

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