مقدمة: لماذا نحتاج التخزين المؤقت في C++ وكيف يسرع التطبيقات
\n\nفي التطوير الحديث بلغة C++، يعتبر الأداء عاملاً حاسماً. كل طلب إضافي لقاعدة البيانات، كل إعادة حساب لدالة معقدة أو قراءة من القرص هي خسارة للميلي ثوانٍ، والتي على نطاق خدمة عالية التحميل تتحول إلى ثوانٍ من التوقف. يحل التخزين المؤقت هذه المشكلة عن طريق حفظ نتائج العمليات المكلفة في ذاكرة سريعة الوصول.
\n\nفي هذه المقالة، سنستعرض ثلاثة أساليب رئيسية للتخزين المؤقت في C++: الأنظمة الخارجية (Redis, Memcached) والحلول المدمجة (std::unordered_map, LRU-cache). ستتعرف على متى تختار أي أداة، وكيفية ضبط التخزين المؤقت بشكل صحيح، وما هي المخاطر التي تنتظرك.
\n\n1. أنظمة التخزين المؤقت الخارجية: Redis وMemcached
\n\n1.1 Redis: مخزن قوي في الذاكرة مع دعم هياكل البيانات
\n\nRedis ليس مجرد تخزين مؤقت، بل هو خادم كامل لهياكل البيانات يعمل في الذاكرة العشوائية. يدعم السلاسل النصية، القوائم، المجموعات، جداول التجزئة وحتى قوائم الانتظار. بالنسبة لـ C++، توجد عدة مكتبات عميلة، أشهرها hiredis (بلغة C) و redis-plus-plus (بلغة C++).
مثال على الاتصال واستخدام Redis عبر redis-plus-plus:
#include <sw/redis++/redis++.h>\n#include <iostream>\n\nint main() {\n // الاتصال بـ Redis على المضيف المحلي\n sw::redis::Redis redis("tcp://127.0.0.1:6379");\n\n // كتابة قيمة في التخزين المؤقت\n redis.set("user:1001", "{\\"name\\":\\"Alice\\",\\"age\\":30}");\n\n // قراءة القيمة\n auto val = redis.get("user:1001");\n if (val) {\n std::cout << "البيانات المخزنة مؤقتاً: " << *val << std::endl;\n }\n\n // تعيين TTL (وقت الحياة) — 60 ثانية\n redis.expire("user:1001", 60);\n\n return 0;\n}\n\n\nمزايا Redis:
\n- \n
- دعم هياكل البيانات المعقدة (القوائم، التجزئة، المجموعات) \n
- آليات مدمجة للنسخ المتماثل والثبات \n
- دعم المعاملات ونصوص Lua \n
- إمكانية الاستخدام كوسيط رسائل pub/sub \n
عيوب Redis:
\n- \n
- يتطلب خادماً منفصلاً (بنية تحتية إضافية) \n
- يستهلك ذاكرة أكثر من Memcached بسبب البيانات الوصفية للهياكل \n
- غير مناسب لكميات كبيرة جداً من البيانات (محدودية الذاكرة العشوائية) \n
1.2 Memcached: تخزين مؤقت موزع خفيف وسريع
\n\nMemcached هو نظام أبسط، مصمم حصرياً للتخزين المؤقت لأزواج المفتاح-القيمة. إنه مثالي لتخزين الكائنات الصغيرة (حتى 1 ميجابايت). بالنسبة لـ C++، تُستخدم مكتبة libmemcached.
مثال على العمل مع Memcached بلغة C++:
\n\n#include <libmemcached/memcached.h>\n#include <iostream>\n#include <cstring>\n\nint main() {\n memcached_server_st *servers;\n memcached_st *memc;\n memcached_return rc;\n\n memc = memcached_create(nullptr);\n servers = memcached_server_list_append(nullptr, "127.0.0.1", 11211, &rc);\n rc = memcached_server_push(memc, servers);\n\n // كتابة في التخزين المؤقت مع TTL 300 ثانية\n const char *key = "session_token_abc123";\n const char *value = "valid";\n rc = memcached_set(memc, key, strlen(key), value, strlen(value), 300, 0);\n\n // قراءة من التخزين المؤقت\n size_t value_length;\n uint32_t flags;\n char *result = memcached_get(memc, key, strlen(key), &value_length, &flags, &rc);\n if (result) {\n std::cout << "القيمة المخزنة مؤقتاً: " << result << std::endl;\n free(result);\n }\n\n memcached_free(memc);\n return 0;\n}\n\n\nمزايا Memcached:
\n- \n
- أقصى أداء في العمليات البسيطة get/set \n
- استهلاك ضئيل للذاكرة على البيانات الوصفية \n <