استخدامات Redis: التخزين المؤقت والطوابير وتحديد المعدل
لقد أضفت Redis إلى مجموعة التقنيات الخاصة بك، لكنك تستخدمه فقط كمخزن بسيط للقيم والمفاتيح. يقدم Redis هياكل بيانات وأوامر قوية يمكنها حل التخزين المؤقت والطوابير وتحديد المعدل بأناقة. يوضح لك هذا الدليل كيفية تنفيذ هذه الأنماط بفعالية.
لماذا Redis لهذه الاستخدامات؟
Redis هو مخزن بيانات في الذاكرة معروف بسرعته وتعدد استخداماته. يدعم السلاسل النصية (strings) والتجزئات (hashes) والقوائم (lists) والمجموعات (sets) والمجموعات المرتبة (sorted sets) والمزيد. تجعله عملياته الذرية والانتهاء المدمج مثاليًا للتخزين المؤقت والطوابير وتحديد المعدل. بالإضافة إلى ذلك، يسهل دمجه مع أي لغة.
التخزين المؤقت باستخدام Redis
التخزين المؤقت هو الاستخدام الأكثر شيوعًا لـ Redis. تقوم بتخزين البيانات التي يتم الوصول إليها بشكل متكرر في Redis لتقليل الحمل على قاعدة البيانات وتسريع الاستجابات.
نمط التخزين المؤقت الجانبي الأساسي
في نمط التخزين المؤقت الجانبي، يتحقق تطبيقك من Redis أولاً. إذا لم تكن البيانات موجودة (فشل التخزين المؤقت)، فإنه يجلبها من قاعدة البيانات، ثم يخزنها في Redis للمرة القادمة.
import redis
import json
r = redis.Redis(host='localhost', port=6379, db=0)
def get_user(user_id):
cache_key = f'user:{user_id}'
cached = r.get(cache_key)
if cached:
return json.loads(cached)
user = fetch_user_from_db(user_id) # your DB call
r.setex(cache_key, 3600, json.dumps(user)) # cache for 1 hour
return user
أفضل الممارسات:
- قم دائمًا بتعيين وقت انتهاء الصلاحية (TTL) لتجنب البيانات القديمة.
- استخدم أسماء مفاتيح ذات معنى، مثل
user:123:profile. - تعامل مع إبطال التخزين المؤقت: عند تغيير البيانات، قم بتحديث أو حذف إدخال التخزين المؤقت.
- فكر في استخدام تجزئات Redis لتخزين حقول متعددة لكائن لتوفير الذاكرة.
أنماط التخزين المؤقت المتقدمة
للتطبيقات ذات الحركة العالية، ضع في اعتبارك هذه الأنماط:
- الكتابة عبر (Write-through): قم بتحديث التخزين المؤقت وقاعدة البيانات معًا.
- الكتابة خلف (Write-behind): قم بتحديث التخزين المؤقت أولاً، ثم قم بتحديث قاعدة البيانات بشكل غير متزامن.
- التحديث المسبق (Refresh-ahead): قم بتحديث إدخالات التخزين المؤقت بشكل استباقي قبل انتهاء صلاحيتها.
الطوابير باستخدام Redis
تعد قوائم وتدفقات Redis مثالية لبناء طوابير رسائل بسيطة. استخدم القوائم لطوابير المهام الأساسية والتدفقات لمعالجة الأحداث الأكثر تعقيدًا.
طابور مهام بسيط باستخدام القوائم
استخدم LPUSH لإضافة المهام و BRPOP لمعالجتها. يحظر BRPOP حتى تتوفر مهمة، مما يجعله فعالاً للعمال.
# Producer
r.lpush('jobs', json.dumps({'task': 'send_email', 'to': 'user@example.com'}))
# Consumer (worker)
while True:
_, job_data = r.brpop('jobs', timeout=30)
job = json.loads(job_data)
process_job(job)
أفضل الممارسات:
- استخدم قوائم منفصلة لأنواع المهام أو الأولويات المختلفة.
- قم بتنفيذ طابور الرسائل الميتة للمهام الفاشلة.
- استخدم
BRPOPLPUSH(أوBLMOVEفي Redis 6.2+) لنقل المهام ذريًا إلى قائمة المعالجة، مما يضمن الموثوقية. - راقب طول الطابور باستخدام
LLENلتوسيع نطاق العمال.
تدفقات Redis لتوريد الأحداث
توفر تدفقات Redis (التي تم تقديمها في Redis 5.0) طابورًا أكثر قوة مع مجموعات المستهلكين والإقرارات وإعادة التشغيل. استخدم XADD لإضافة الأحداث و XREADGROUP لاستهلاكها.
# Add event
r.xadd('events', {'type': 'order_placed', 'order_id': '123'})
# Consumer group
r.xgroup_create('events', 'order_processors', id='0', mkstream=True)
while True:
events = r.xreadgroup('order_processors', 'worker1', {'events': '>'}, count=10, block=5000)
for event in events:
process_event(event)
r.xack('events', 'order_processors', event.id)
تحديد المعدل باستخدام 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