استخدامات Redis: التخزين المؤقت، الطوابير، وتحديد المعدل
لقد قمت ببناء تطبيق ويب يكتسب زخماً، ولكن مع نمو حركة المرور، لاحظت استعلامات قاعدة بيانات بطيئة ومهلات عرضية. يعاني خادمك تحت الحمل، ويشتكي المستخدمون من زمن الاستجابة. تحتاج إلى مخزن بيانات سريع في الذاكرة لتفريغ المهام المتكررة وإدارة ذروات حركة المرور. Redis هو الحل الأمثل للعديد من تحديات الواجهة الخلفية، وفي هذا المقال، سنستكشف ثلاثة حالات استخدام عملية: التخزين المؤقت، والطوابير، وتحديد المعدل.
لماذا Redis؟
Redis هو مخزن مفتوح المصدر للقيم والمفاتيح في الذاكرة، معروف بسرعته وتعدد استخداماته. يدعم هياكل البيانات مثل السلاسل النصية، والتجزئات، والقوائم، والمجموعات، والمجموعات المرتبة، مما يجعله مناسبًا لمجموعة واسعة من المهام. على عكس قواعد البيانات التقليدية، يحتفظ Redis بالبيانات في الذاكرة العشوائية (RAM)، مما يوفر زمن استجابة أقل من مللي ثانية. كما يقدم خيارات الاستمرارية، والنسخ المتماثل، والتجميع لضمان التوافر العالي.
1. التخزين المؤقت باستخدام Redis
يُعد التخزين المؤقت أكثر حالات استخدام Redis شيوعًا. من خلال تخزين البيانات التي يتم الوصول إليها بشكل متكرر في Redis، تقلل الحمل على قاعدة البيانات الأساسية وتسرع أوقات الاستجابة. على سبيل المثال، إذا كان تطبيقك يعرض قائمة بالمنتجات الشائعة، يمكنك تخزين نتيجة الاستعلام مؤقتًا لبضع دقائق.
كيفية تنفيذ التخزين المؤقت
- تحقق من ذاكرة التخزين المؤقت: قبل الاستعلام من قاعدة البيانات، تحقق مما إذا كانت البيانات موجودة في Redis.
- إذا وُجدت (إصابة ذاكرة التخزين المؤقت): أعد البيانات المخزنة مؤقتًا.
- إذا لم توجد (فشل ذاكرة التخزين المؤقت): استعلم من قاعدة البيانات، وخزّن النتيجة في Redis مع وقت انتهاء الصلاحية (TTL)، وأعد البيانات.
إليك مثال بلغة Python باستخدام redis-py:
import redis
import json
r = redis.Redis(host='localhost', port=6379, db=0)
def get_products():
cache_key = 'products:popular'
cached = r.get(cache_key)
if cached:
return json.loads(cached)
# Simulate database query
products = [{'id': 1, 'name': 'Product A'}, {'id': 2, 'name': 'Product B'}]
r.setex(cache_key, 300, json.dumps(products)) # Cache for 5 minutes
return products
أفضل الممارسات: استخدم مفاتيح تخزين مؤقت ذات معنى، واضبط أوقات انتهاء صلاحية مناسبة، وفكر في استراتيجيات إبطال ذاكرة التخزين المؤقت. للبيانات المتغيرة بشكل متكرر، استخدم TTL قصيرة أو نفذ التخزين المؤقت الكتابي.
2. الطوابير باستخدام Redis
قوائم Redis والتدفقات ممتازة لبناء طوابير رسائل بسيطة. تسمح لك بفصل المهام التي تستهلك وقتًا (مثل إرسال البريد الإلكتروني أو معالجة الصور) عن دورة الطلب والاستجابة، مما يحسن تجربة المستخدم وقابلية التوسع.
استخدام القوائم كطابور
يمكنك استخدام LPUSH لإضافة المهام إلى قائمة وBRPOP لإزالة المهام بشكل ذري من الطرف الآخر. يؤدي هذا إلى إنشاء طابور FIFO.
المنتج:
r.lpush('email_queue', json.dumps({'to': 'user@example.com', 'subject': 'Welcome'}))
المستهلك (في عملية عامل):
while True:
_, job = r.brpop('email_queue', timeout=30)
if job:
process_email(json.loads(job))
اعتبارات: قوائم Redis بسيطة ولكنها تفتقر إلى ميزات متقدمة مثل الإقرارات. للاحتياجات الأكثر قوة، فكر في Redis Streams، التي تدعم مجموعات المستهلكين وإقرار الرسائل.
3. تحديد المعدل باستخدام Redis
يحمي تحديد المعدل واجهة برمجة التطبيقات الخاصة بك من الإساءة ويضمن الاستخدام العادل. عمليات Redis الذرية تجعله مثاليًا لتنفيذ محددات المعدل. الخوارزمية الشائعة هي عداد النافذة المنزلقة، ولكن نهج النافذة الثابتة الأبسط يعمل جيدًا أيضًا.
محدد المعدل بنافذة ثابتة
قم بزيادة عداد لكل مستخدم وتعيين وقت انتهاء الصلاحية. إذا تجاوز العداد الحد، ارفض الطلب.
def is_allowed(user_id, limit=100, window=60):
key = f'rate_limit:{user_id}'
current = r.incr(key)
if current == 1:
r.expire(key, window)
return current