أساسيات قاعدة بيانات Redis: كيف تعمل واجهة Redis CLI وأهم الأوامر ومشاريع تطبيقية

دقائق القراءة: 8

مقدمة إلى Redis ولماذا تحظى بهذه الشعبية

Redis هي قاعدة بيانات سريعة للغاية تعمل داخل الذاكرة، وتُستخدم في سيناريوهات متعددة مثل التخزين المؤقت caching، وتحديد معدل الطلبات rate limiting، ومشاركة البيانات بين الخدمات والتطبيقات. ما يميزها فعلاً هو قدرتها على القراءة والكتابة بزمن استجابة منخفض جداً، وهو ما يجعلها خياراً ممتازاً عندما تكون السرعة عاملاً حاسماً.

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

شرح أساسيات قاعدة بيانات Redis واستخدامها في التخزين المؤقت وتحسين أداء التطبيقات

ما المقصود بقاعدة بيانات تعمل داخل الذاكرة؟

قواعد البيانات التقليدية تحتفظ عادةً بجزء من البيانات في الذاكرة لتسريع الوصول، بينما يبقى الجزء الأكبر على وحدات التخزين مثل SSD أو HDD. أما Redis فتعتمد بشكل أساسي على RAM، وهذا ما يمنحها سرعة استثنائية في تنفيذ العمليات.

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

ورغم أن Redis تُصنَّف غالباً كقاعدة بيانات من نوع key-value، فإنها ليست بدائية كما قد يبدو من الوصف. فهي توفر أساليب متعددة للتعامل مع البيانات، إلى جانب دعم هياكل متنوعة وخصائص قوية تناسب تطبيقات حديثة ومعقدة.

لماذا قد تحتاج إلى Redis في مشروعك؟

1. بناء تطبيقات قابلة للتوسع الأفقي

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

2. مشاركة البيانات بين خدمات متعددة

في كثير من البنى البرمجية الحديثة، توجد عدة خدمات منفصلة تحتاج إلى مشاركة معلومات معينة بسرعة. على سبيل المثال، إذا اكتشفت خدمة ما محاولة هجوم أو إساءة استخدام على نطاق فرعي مثل payments.codedamn.com، فقد ترغب في أن تستفيد خدمة أخرى مثل login.codedamn.com من هذه المعلومة فوراً. هنا تؤدي Redis دور الذاكرة المشتركة بين هذه الخدمات.

أساسيات Redis التي يجب أن تعرفها

من الجوانب الإيجابية في Redis أنها سهلة التعلم نسبياً. فعدد الأوامر الأساسية التي تحتاج إليها في البداية محدود، ويمكنك خلال وقت قصير أن تبدأ بتجربتها في بيئة حقيقية.

كيف تعمل واجهة Redis CLI؟

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

واجهة Redis CLI وتجربة الأوامر التفاعلية داخل قاعدة بيانات Redis

على سبيل المثال، يمكنك اختبار الاتصال بقاعدة البيانات عبر أمر بسيط مثل PING، وستتلقى استجابة تؤكد أن الخادم يعمل كما ينبغي.

أشهر أوامر Redis الأساسية

تنفيذ الأوامر الشائعة في Redis CLI لفهم طريقة عمل Redis عملياً

الأمر SET

يُستخدم الأمر SET لتخزين قيمة داخل مفتاح معيّن.

SET mehul "developer from india"

في هذا المثال، تم تخزين القيمة developer from india داخل المفتاح mehul.

الأمر GET

يُستخدم GET لاسترجاع القيمة المرتبطة بمفتاح موجود.

GET mehul

سيعيد هذا الأمر القيمة المخزنة سابقاً، وهي developer from india.

الأمر SETNX

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

SET key1 value1
SETNX key1 value2
SETNX key2 value2

بعد تنفيذ الأوامر السابقة، سيبقى key1 بقيمة value1، بينما سيُضبط key2 على value2. السبب هو أن SETNX لا يغيّر المفتاح إذا كان موجوداً مسبقاً.

الأمر MSET

إذا كنت تريد تخزين عدة مفاتيح دفعة واحدة، فاستخدم MSET.

MSET key1 "value1" key2 "value2" key3 "value3"

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

الأمر MGET

يشبه GET، لكنه يسترجع قيم عدة مفاتيح في أمر واحد.

MGET key1 key2 key3 key4

إذا لم يكن المفتاح موجوداً، فستكون النتيجة المقابلة له null. وهذا مفيد عند التعامل مع مجموعات مفاتيح في وقت واحد.

الأمر DEL

يُستخدم لحذف مفتاح من قاعدة البيانات.

SET key value
GET key
DEL key
GET key

بعد الحذف، سيعيد GET القيمة null لأن المفتاح لم يعد موجوداً.

الأمران INCR وDECR

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

SET favNum 10
INCR favNum
INCR favNum
DECR favNum

ستتغير القيمة من 10 إلى 11 ثم 12 ثم تعود إلى 11.

الأمر EXPIRE

يُستخدم هذا الأمر لتحديد مدة صلاحية مفتاح. وبعد انتهاء المدة، يصبح المفتاح غير متاح وكأنه حُذف.

SET bitcoin 100
EXPIRE bitcoin 10
GET bitcoin
# after 10 seconds
GET bitcoin

هذه الخاصية أساسية جداً في أنظمة التخزين المؤقت، لأنها تمنع بقاء البيانات القديمة إلى الأبد.

الأمر TTL

إذا أردت معرفة الزمن المتبقي قبل انتهاء صلاحية مفتاح، فاستخدم TTL.

SET bitcoin 100
TTL bitcoin
TTL somethingelse
EXPIRE bitcoin 5
# wait 2 seconds
TTL bitcoin
# after expiration
GET bitcoin
TTL bitcoin

سلوك هذا الأمر مهم:

  • يعيد -1 إذا كان المفتاح موجوداً ولكن بلا مدة انتهاء.
  • يعيد -2 إذا كان المفتاح غير موجود.
  • يعيد عدداً صحيحاً يمثل الثواني المتبقية إذا كان المفتاح سينتهي لاحقاً.

الأمر SETEX

يجمع SETEX بين التخزين وتحديد مدة الانتهاء في أمر واحد.

SETEX key 10 value

في هذا المثال، سيتم تخزين القيمة value داخل المفتاح key لمدة 10 ثوانٍ فقط.

مشروع عملي 1: بناء نظام تخزين مؤقت لواجهة API باستخدام Redis

أحد أشهر استخدامات Redis هو تخزين نتائج طلبات API الخارجية مؤقتاً. هذه الفكرة تقلل عدد الطلبات المرسلة إلى الخدمة الخارجية، وتسرّع الاستجابة للمستخدم، كما تساعد على تجنب تجاوز حدود الاستخدام rate limits التي تفرضها بعض المنصات.

مشروع عملي لتخزين نتائج API مؤقتاً باستخدام Redis لتحسين الأداء

في المثال التالي باستخدام Node.js، نحاول أولاً قراءة البيانات من Redis. إذا كانت موجودة، نعيدها مباشرة. وإذا لم تكن موجودة، نستدعي GitHub API ثم نخزن النتيجة لمدة قصيرة.

app.post('/data', async (req, res) => {
  const repo = req.body.repo
  const value = await redis.get(repo)

  if (value) {
    res.json({ status: 'ok', stars: value })
    return
  }

  const response = await fetch(`https://api.github.com/repos/${repo}`).then((t) => t.json())

  if (response.stargazers_count != undefined) {
    await redis.setex(repo, 60, response.stargazers_count)
  }

  res.json({ status: 'ok', stars: response.stargazers_count })
})

ما الذي يحدث في هذا الكود؟

  • نأخذ اسم المستودع من الطلب، مثل facebook/react.
  • نبحث عنه أولاً في Redis باستخدام get.
  • إذا وجدنا القيمة، فهذا يعني حدوث cache hit، فنُرجع النتيجة فوراً دون الاتصال بخادم خارجي.
  • إذا لم نجدها، نرسل طلباً إلى GitHub API.
  • عند وصول عدد النجوم بنجاح، نستخدم setex لتخزينه لمدة 60 ثانية.
  • تحديد مدة انتهاء يمنع تقديم بيانات قديمة لفترات طويلة.

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

مشروع عملي 2: تطبيق Rate Limiting باستخدام Redis

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

تطبيق تحديد معدل الطلبات باستخدام Redis لحماية واجهات API من الإساءة

app.post('/api/route', async (req, res) => {
  const ip = req.headers['x-forwarded-for'] || req.ip
  const reqs = await redis.incr(ip)
  await redis.expire(ip, 2)

  if (reqs > 15) {
    return res.json({ status: 'rate-limited' })
  } else if (reqs > 10) {
    return res.json({ status: 'about-to-rate-limit' })
  } else {
    res.json({ status: 'ok' })
  }
})

شرح منطق التنفيذ

  • نحدّد عنوان IP من الترويسة x-forwarded-for أو من req.ip.
  • نستخدم INCR لزيادة عدد الطلبات الخاصة بهذا IP.
  • إذا لم يكن المفتاح موجوداً من قبل، فسيتم إنشاؤه تلقائياً وبدء العد من 1.
  • نضبط مدة انتهاء المفتاح باستخدام expire حتى تتم إعادة العداد بعد فترة قصيرة.
  • إذا تجاوز عدد الطلبات الحد الأعلى، نمنع الوصول إلى الوظيفة الأساسية ونرجع استجابة تفيد بوجود تقييد.

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

خصائص إضافية مهمة في Redis

Redis تعمل بخيط تنفيذ واحد

قد يبدو غريباً أن Redis تعمل كعملية single-threaded حتى على الأنظمة متعددة الأنوية، لكن هذا القرار تصميمي ومقصود. الهدف منه تقليل التعقيد المرتبط بتزامن العمليات والوصول المتوازي إلى نفس المفاتيح.

بدلاً من الاعتماد على آليات قفل locking قد تستهلك وقتاً وتسبب تعقيدات، تعتمد Redis على تنفيذ متسلسل سريع، وهو ما يحقق توازناً ممتازاً بين الأداء والموثوقية في كثير من الاستخدامات.

المعاملات في Redis باستخدام MULTI وEXEC

ليست كل المهام قابلة للتنفيذ بأمر واحد. لذلك توفر Redis أسلوباً لتجميع عدة أوامر وتنفيذها دفعة واحدة من خلال MULTI وEXEC.

MULTI
SET hello world
SET yo lo
SET number 1
INCR number
EXPIRE hello 10
EXPIRE yo 5
EXEC

بعد الأمر MULTI، يتم تجميع الأوامر دون تنفيذ فوري، ثم تُنفذ جميعها معاً عند وصول EXEC. هذا مفيد عندما تحتاج إلى سلسلة من العمليات المترابطة بشكل منظم.

دعم هياكل وميزات أوسع

ما تعلّمناه هنا ليس سوى البداية. تدعم Redis أيضاً أنواع بيانات إضافية مثل القوائم lists والمجموعات sets، كما يمكن استخدامها كنظام نشر واشتراك pub/sub لإرسال الإشعارات بين الخدمات والعملاء في البنى متعددة المكونات.

أفضل ممارسات عند استخدام Redis

  • استخدم TTL بذكاء عند التعامل مع البيانات المؤقتة.
  • تجنب تخزين بيانات لا تحتاج إلى السرعة الفائقة داخل الذاكرة، لأن الذاكرة مورد أعلى كلفة من التخزين التقليدي.
  • اعتمد أسماء مفاتيح واضحة ومنظمة لتسهيل الصيانة، مثل user:123:profile.
  • راقب معدلات القراءة والكتابة وحجم المفاتيح باستمرار، خاصة في البيئات الإنتاجية.
  • استفد من Redis CLI في الاختبارات السريعة وتشخيص المشكلات قبل الانتقال إلى طبقة التطبيق.

الخلاصة التقنية

Redis ليست مجرد قاعدة بيانات سريعة، بل أداة عملية تعالج مشكلات شائعة في هندسة البرمجيات الحديثة مثل التخزين المؤقت، ومشاركة الحالة بين الخدمات، وحماية الواجهات البرمجية من الإساءة. إذا كنت تحتاج إلى أداء عالٍ وزمن استجابة منخفض، فتعلم أساسيات Redis CLI وأوامر مثل SET وGET وINCR وEXPIRE سيمنحك نقطة انطلاق ممتازة. ومن الناحية التقنية، تبدأ القيمة الحقيقية لـ Redis عندما توظفها في سيناريوهات عملية مدروسة، لا كحل عام لكل شيء، بل كأداة متخصصة تُستخدم في المكان المناسب لتحقيق أفضل نتيجة.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *