بنية التخزين المؤقت والمراسلة

تشغيل Redis: الأساسيات

18 دقيقة الدرس 1 من 30

تشغيل Redis: الأساسيات

Redis هو خادم بنى بيانات يعمل في الذاكرة بخيط تنفيذ وحيد. تحمل هذه الجملة ثلاث كلمات جوهرية تشكّل كل قرار تشغيلي ستتخذه. خيط وحيد يعني أن إشباع نواة معالج واحدة يكفي لتجميد الخادم بالكامل — لا يمكنك معالجة اختناق Redis بإضافة المزيد من الأنوية كما تفعل مع الخدمات عديمة الحالة. في الذاكرة يعني أن مجموعة البيانات العاملة يجب أن تتسع في RAM؛ حين لا تتسع، إما أن يطرد Redis البيانات أو يتعطل بالكامل وفق السياسة المضبوطة. خادم بنى بيانات يعني أنه ليس مجرد مخزن مفتاح-قيمة — فهو يدعم نصوصاً وقواميس وقوائم ومجموعات مرتبة وتدفقات ومصفوفات بتية وHyperLogLog، كل منها له بصمة ذاكرة مختلفة وتعقيد زمني يؤثر جوهرياً على الأداء عند الحجم الكبير.

قبل ضبط أي إعداد، عليك تحديد ما يلي: هل هذه النسخة ذاكرة تخزين مؤقت أم مخزن بيانات؟ الإجابة تحدد كل خيار لاحق — الاستمرارية وسياسة الذاكرة وطبولوجيا النسخ الاحتياطي وعتبات التنبيه.

ذاكرة التخزين المؤقت مقابل المخزن: الفارق التشغيلي

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

  • يمكن تعطيل الاستمرارية كلياً، مما يوفر CPU وعمليات I/O.
  • سياسة طرد صارمة كـallkeys-lru هي الخيار الصحيح — يجب أن يحرر Redis الذاكرة دون تعطيل التطبيق.
  • RTO يقترب من الصفر: عند إعادة التشغيل تكون ذاكرة التخزين فارغة وتمتلئ تلقائياً.
  • النسخ يُعدّ اعتباراً أدائياً لا اعتباراً للمتانة.

المخزن (يُسمى أحياناً المخزن الأولي أو Redis الدائم) يحتفظ بحالة موثوقة: رموز الجلسات وعدادات تحديد المعدل والأقفال الموزعة والمهام المُدرجة في الطابور ولوحات الصدارة والتحليلات الآنية. فقدان البيانات هنا خطأ وليس مجرد إخفاق بحث. هذا يعني:

  • الاستمرارية إلزامية — بحد أدنى AOF مع appendfsync everysec، ومثالياً AOF + RDB معاً لاسترداد سريع ولقطات زمنية.
  • سياسة الطرد يجب أن تكون noeviction — ليتلقى التطبيق خطأ OOM command not allowed ويتعامل معه صراحةً بدلاً من فقدان بيانات بصمت.
  • النسخ اعتبار متانة؛ دائماً شغّل نسخة واحدة على الأقل مع min-replicas-to-write 1.
فخ إنتاجي — النسخة متعددة الأغراض: كثيراً ما تبدأ الفرق بنسخة Redis واحدة لكل من التخزين المؤقت وتخزين الجلسات خفضاً للتكلفة. هذا فخ موثوقية. حين يضغط الذاكرة ويُفعّل الطرد، لا يستطيع Redis التمييز بين إدخال كاشي بلا قيمة وجلسة مستخدم — كلاهما يُطرد وفق LRU. شغّل نسخاً منفصلة (أو قواعد بيانات منطقية منفصلة كحد أدنى) بسياسات مختلفة. على نطاق المؤسسات الكبرى، تعزل النسخ المنفصلة أيضاً تأثيرات الجار المزعج: عاصفة إبطال الكاش الجماعي لن تُسبب تأخيراً في قراءة الجلسات.

الاستمرارية: لقطات RDB

تكتب استمرارية RDB (قاعدة بيانات Redis) لقطة ثنائية مضغوطة للمجموعة الكاملة على القرص بفترات زمنية محددة. تُنشأ اللقطة عبر fork() — يستمر الوالد في خدمة الطلبات بينما يكتب العملية الابن ملف .rdb باستخدام نسخ عند الكتابة (CoW). على نسخة بحجم 50 جيجابايت مع أحمال عمل كثيفة الكتابة، يمكن لـCoW مضاعفة RSS مؤقتاً؛ تأكد من ضبط إعداد الإفراط في الالتزام في النظام (vm.overcommit_memory=1) ومن وجود مساحة كافية.

# redis.conf — جدول لقطات RDB # save <ثوانٍ> <تغييرات> save 3600 1 # لقطة إذا تغير مفتاح واحد على الأقل في ساعة save 300 100 # لقطة إذا تغير 100 مفتاح على الأقل في 5 دقائق save 60 10000 # لقطة إذا تغير 10,000 مفتاح على الأقل في دقيقة dir /var/lib/redis dbfilename dump.rdb # إيقاف الكتابات إذا فشلت العملية الابن — يمنع فقدان البيانات بصمت stop-writes-on-bgsave-error yes # ضغط LZF (مقايضة CPU؛ يستحق على مجموعات البيانات الكبيرة) rdbcompression yes rdbchecksum yes # فحص سلامة CRC64 عند التحميل

RDB مثالي لنسخ التخزين المؤقت فقط وأرشيفات الاسترداد من الكوارث — تنتج BGSAVE ملفاً واحداً محمولاً يمكن نسخه خارجياً بـrsync أو رفعه إلى التخزين الكائني. المقايضة هي الدقة الزمنية: إذا تعطل Redis بين اللقطات، تفقد كل ما كُتب في تلك الفترة. على كاش خالص هذا مقبول؛ على مخزن بيانات فلا.

الاستمرارية: ملف الإلحاق AOF

يكتب AOF كل أمر كتابة إلى سجل إلحاقي. عند إعادة التشغيل، يُعيد Redis تشغيل السجل لإعادة بناء الحالة. المفتاح الحاسم هو appendfsync الذي يتحكم في مقايضة المتانة مقابل الكمون على مستوى نظام التشغيل:

  • alwaysfsync() بعد كل كتابة. متانة على مستوى أمر واحد، لكنه يضيف ~1–2 مللي ثانية لكل كتابة. نادراً ما يكون مبرراً؛ استخدم قاعدة بيانات علائقية إذا احتجت هذا.
  • everysecfsync() مرة في الثانية في خيط خلفي. الافتراضي الإنتاجي للمخازن. أقصى فقدان للبيانات: ~ثانية واحدة من الكتابات.
  • no — نظام التشغيل يقرر متى يُفرّغ. أعلى معدل نقل، أسوأ متانة. مكافئ عملياً لـRDB.
# redis.conf — إعداد AOF appendonly yes appendfilename "appendonly.aof" appendfsync everysec # منع fsync أثناء حفظ RDB الثقيل (يتجنب تأخيرات 30 ثانية) no-appendfsync-on-rewrite yes # إعادة كتابة تلقائية عند نمو ملف AOF 100% فوق حجم آخر إعادة كتابة auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb # مقدمة بتنسيق RDB + AOF تزايدي = إعادة تشغيل أسرع بكثير aof-use-rdb-preamble yes
RDB + AOF معاً (الإعداد الموصى به للمخازن): AOF يوفر متانة عالية التردد؛ RDB يوفر خط أساس استرداد مضغوط ويُمكّن من إعادة تشغيل أسرع عبر aof-use-rdb-preamble yes. على نسخة بحجم 100 جيجابايت، يمكن أن يستغرق إعادة تشغيل AOF الخالص من البداية أكثر من 20 دقيقة؛ مقدمة RDB تختصر ذلك إلى أقل من 60 ثانية.

سياسات الذاكرة

حين يصل Redis إلى maxmemory، يجب أن يقرر ما يفعل. يُضبط ذلك عبر maxmemory-policy. اختيار السياسة الخاطئة هو أحد أكثر أسباب تلف البيانات الصامت شيوعاً في الإنتاج.

Redis maxmemory-policy decision tree maxmemory reached Cache or Store? Cache allkeys-lru Evict any key by LRU order Store noeviction Return OOM error to client Other cache variants allkeys-lfu — evict by frequency volatile-lru — evict only keys with TTL allkeys-random — uniform random eviction Alert on used_memory Alert at 75% maxmemory; page at 90%. Scale before OOM, not after.
اختيار maxmemory-policy المناسب بناءً على استخدام Redis كذاكرة تخزين مؤقت أو مخزن بيانات موثوق.

مصفوفة السياسات الكاملة:

  • noeviction — لا تُحذف أي مفاتيح؛ أوامر الكتابة تُعيد خطأً. الخيار الصحيح للمخازن.
  • allkeys-lru — طرد المفتاح الأقل استخداماً حديثاً عبر كامل الفضاء. الخيار الصحيح للكاش الخالص.
  • allkeys-lfu — طرد المفتاح الأقل استخداماً تكراراً (Redis 4+). أفضل من LRU لأنماط الوصول المنحازة (أحمال المفاتيح الساخنة).
  • volatile-lru / volatile-lfu / volatile-ttl — طرد المفاتيح التي لها وقت انتهاء صلاحية فقط. استخدمها حين يحمل Redis مفاتيح دائمة وأخرى عابرة وتريد حماية الدائمة. هشة: إذا كانت كل المفاتيح لها TTL، يتصرف كـallkeys-*؛ وإذا لم يكن لأي منها TTL، يتراجع إلى noeviction.
  • allkeys-random — طرد مفتاح عشوائي. نادراً ما يكون صحيحاً؛ فقط لأنماط الوصول الموحدة.
# redis.conf — إعداد الذاكرة maxmemory 12gb maxmemory-policy allkeys-lru # غيّر إلى noeviction للمخازن # دقة أخذ عينات LRU/LFU (أعلى = CPU أكثر، دقة أكبر) maxmemory-samples 10 # الافتراضي 5؛ 10 قيمة جيدة للإنتاج # فترة تضاؤل LFU (دقائق). يتحكم في سرعة تقادم عدادات التكرار. lfu-decay-time 1

الأوامر التشغيلية الأساسية

على كل مشغّل Redis معرفة هذه الأوامر عن ظهر قلب:

  • INFO memoryused_memory_rss مقابل used_memory؛ الفرق (نسبة التجزؤ) يرتفع بعد الحذف الجماعي.
  • INFO stats — عداد evicted_keys؛ أي قيمة غير صفرية على مخزن بيانات تستوجب تنبيهاً فورياً.
  • INFO persistencerdb_last_bgsave_status وaof_last_write_status؛ الإخفاقات هنا كثيراً ما تمر بصمت.
  • MEMORY USAGE <key> — ذاكرة المفتاح بالبايت بما فيها الحمل الزائد للبيانات الوصفية.
  • OBJECT FREQ <key> — عداد LFU (يتطلب maxmemory-policy allkeys-lfu).
  • DEBUG SLEEP 0 — التحقق من عدم انسداد حلقة الأحداث (يعود فوراً إذا كانت سليمة).
  • SLOWLOG GET 20 — آخر 20 أمراً تجاوزت slowlog-log-slower-than (الافتراضي 10 مللي ثانية)؛ ظهور KEYS * هنا يعني أن أحدهم ينفّذ مسحاً O(N) في الإنتاج.
لا تنفّذ KEYS * على نسخة إنتاجية أبداً. هو O(N) ويعطّل حلقة الأحداث طوال فترة المسح. على نسخة بعشرة ملايين مفتاح يمكن أن يتسبب في توقفات لعدة ثوانٍ. استخدم دائماً SCAN مع مؤشر وتلميح COUNT مناسب (مثلاً SCAN 0 MATCH session:* COUNT 200). كذلك SMEMBERS على مجموعة كبيرة وHGETALL على قاموس كبير يعطّلان الحلقة — استخدم SSCAN وHSCAN بدلاً منهما.

قاعدة تحديد حجم maxmemory

خطأ شائع هو ضبط maxmemory مساوياً لإجمالي RAM النسخة. Redis نفسه يستخدم ذاكرة إضافية فوق بياناتك: مخازن الإخراج لكل عميل متصل يمكن أن تبلغ عشرات الميغابايتات تحت الحمل، ومخزن النسخة الاحتياطية (repl-backlog-size، الافتراضي 1 MB) يكبر أثناء تأخر النسخة، ومخازن إعادة كتابة AOF ترتفع أثناء BGREWRITEAOF. القاعدة العملية في المؤسسات الكبرى: اضبط maxmemory على 75% من RAM المتاحة ونبّه عند 75% من ذلك. هذا يترك هامشاً لـCoW الخاص بـfork ومخازن النسخ وذاكرة التخزين المؤقت للصفحات في نظام التشغيل اللازمة لكتابات AOF.

أنت الآن تمتلك النموذج الذهني ومفاتيح الإعداد لتشغيل Redis بصورة صحيحة في الإنتاج. الدرس التالي يتناول التوافر العالي — Sentinel والمجموعة — والذي يُبنى مباشرةً على هذه الأسس للاستمرارية والطرد.