قوائم Redis (الجزء 1)
القائمة هي تسلسل مرتب وقابل للتكرار من السلاسل. يغطي هذا الدرس عمليات القوائم الأساسية.
ما هي القائمة؟
القائمة تشبه:
- list في Python
- Array في JavaScript
- LinkedList في Java
ميزات قائمة Redis:
- مرتبة: العناصر تحافظ على ترتيب الإدراج
- قابلة للتكرار: يمكن أن تظهر نفس القيمة عدة مرات
- عمليات ثنائية الطرف: إدراج وإخراج من كلا الطرفين
mylist
├─ "element1"
├─ "element2"
├─ "element3"
└─ "element4"
💡 التنفيذ الداخلي: تستخدم قوائم Redis quicklist، وهو مزيج من قائمة مزدوجة الربط و ziplist يوازن بين الذاكرة والأداء.
LPUSH و RPUSH: إدراج العناصر
LPUSH: إدراج من اليسار (الرأس)
REDIS
# إدراج عنصر واحد من اليسار
LPUSH mylist "world"
(integer) 1 # يُرجع طول القائمة
# إدراج عناصر متعددة من اليسار
LPUSH mylist "hello"
(integer) 2
# عرض القائمة
LRANGE mylist 0 -1
1) "hello"
2) "world"
⚠️ ملاحظة: عند إدراج عناصر متعددة باستخدام LPUSH، يتم إدراجها من اليسار إلى اليمين بترتيب المعاملات.
LPUSH mylist a b c ينتج [c, b, a, ...].
RPUSH: إدراج من اليمين (الذيل)
REDIS
# إدراج من اليمين
RPUSH mylist "Redis"
(integer) 3
RPUSH mylist "Tutorial"
(integer) 4
# عرض القائمة
LRANGE mylist 0 -1
1) "hello"
2) "world"
3) "Redis"
4) "Tutorial"
LPUSHX و RPUSHX: إدراج فقط إذا كانت القائمة موجودة
REDIS
# فشل الإدراج عندما لا تكون القائمة موجودة
LPUSHX notexist "value"
(integer) 0
# نجاح الإدراج عندما تكون القائمة موجودة
LPUSHX mylist "first"
(integer) 5
RPUSHX mylist "last"
(integer) 6
LPOP و RPOP: إخراج العناصر
LPOP: إخراج من اليسار (الرأس)
REDIS
# عرض القائمة الحالية
LRANGE mylist 0 -1
1) "first"
2) "hello"
3) "world"
4) "Redis"
5) "Tutorial"
6) "last"
# إخراج من اليسار
LPOP mylist
"first"
# إخراج عناصر متعددة (Redis 6.2+)
LPOP mylist 2
1) "hello"
2) "world"
RPOP: إخراج من اليمين (الذيل)
REDIS
# إخراج من اليمين
RPOP mylist
"last"
# إخراج عناصر متعددة (Redis 6.2+)
RPOP mylist 2
1) "Tutorial"
2) "Redis"
عندما تكون القائمة فارغة
REDIS
LPOP emptylist
(nil) # يُرجع nil للقائمة الفارغة
LLEN: الحصول على طول القائمة
REDIS
LPUSH mylist "a" "b" "c"
LLEN mylist
(integer) 3
# القائمة غير موجودة
LLEN notexist
(integer) 0
LRANGE: الحصول على العناصر ضمن نطاق
LRANGE هو أمر استعلام القوائم الأكثر شيوعًا.
الاستخدام الأساسي
REDIS
LPUSH mylist "one" "two" "three" "four" "five"
# الحصول على جميع العناصر
LRANGE mylist 0 -1
1) "five"
2) "four"
3) "three"
4) "two"
5) "one"
# الحصول على أول 3 عناصر
LRANGE mylist 0 2
1) "five"
2) "four"
3) "three"
# الحصول على آخر عنصرين
LRANGE mylist -2 -1
1) "two"
2) "one"
# الحصول على العناصر من الفهرس 1 إلى 3
LRANGE mylist 1 3
1) "four"
2) "three"
3) "two"
قواعد الفهرس
| الفهرس | الوصف |
|---|---|
| 0 | العنصر الأول |
| 1 | العنصر الثاني |
| -1 | العنصر الأخير |
| -2 | العنصر قبل الأخير |
| 0 -1 | جميع العناصر |
⚠️ ملاحظة: فهرس النهاية في LRANGE شامل.
LRANGE 0 2 يُرجع العناصر في الفهارس 0، 1، 2 (3 عناصر إجمالاً).
تنفيذ قوائم الانتظار والمكدسات باستخدام القوائم
قائمة انتظار (FIFO: أول دخول، أول خروج)
باستخدام RPUSH + LPOP:
REDIS
# المنتج: إدراج من اليمين
RPUSH queue:task "task1"
RPUSH queue:task "task2"
RPUSH queue:task "task3"
# المستهلك: إخراج من اليسار
LPOP queue:task
"task1"
LPOP queue:task
"task2"
إدراج → [task1, task2, task3] → إخراج
RPUSH LPOP
مكدس (LIFO: آخر دخول، أول خروج)
باستخدام LPUSH + LPOP:
REDIS
# دفع
LPUSH stack:data "item1"
LPUSH stack:data "item2"
LPUSH stack:data "item3"
# إخراج
LPOP stack:data
"item3"
LPOP stack:data
"item2"
دفع → [item3, item2, item1] → إخراج
LPUSH LPOP
💡 للمساعدة في الحفظ:
- قائمة انتظار: RPUSH + LPOP (يمين دخول، يسار خروج)
- مكدس: LPUSH + LPOP (يسار دخول، يسار خروج)
إخراج محظور: BLPOP و BRPOP
عندما تكون القائمة فارغة، يمنع BLPOP و BRPOP حتى يتوفر عنصر أو يحدث مهلة.
BLPOP: إخراج محظور من اليسار
REDIS
# العميل 1: انتظر مهمة في قائمة الانتظار (بحد أقصى 10 ثوانٍ)
BLPOP queue:task 10
# العميل 2: أضف مهمة
RPUSH queue:task "new_task"
# العميل 1 يستلم:
1) "queue:task" # اسم القائمة
2) "new_task" # العنصر المُخرَج
BRPOP: إخراج محظور من اليمين
REDIS
BRPOP queue:task 10
الحظر على قوائم متعددة
REDIS
# الانتظار على قوائم متعددة، إرجاع أيّها لديه بيانات أولاً
BLPOP queue:high queue:low 10
💡 حالة الاستخدام: BLPOP/BRPOP تُستخدم عادةً لتنفيذ قوائم انتظار المهام وقوائم انتظار الرسائل، حيث ينتظر المستهلكون منعًا لقدوم مهام جديدة.
حالات استخدام القوائم
حالة الاستخدام 1: قائمة انتظار رسائل
REDIS
# المنتج: إرسال رسالة
RPUSH queue:email '{"to":"user@example.com","subject":"Hello"}'
# المستهلك: استلام رسالة (انتظار محظور)
BLPOP queue:email 0
حالة الاستخدام 2: قائمة حديثة
REDIS
# إضافة أحدث المقالات
LPUSH articles:latest "article:123"
LPUSH articles:latest "article:124"
LPUSH articles:latest "article:125"
# الحصول على أحدث 10 مقالات
LRANGE articles:latest 0 9
# الاحتفاظ بالقائمة بحد أقصى 100 مقالة
LTRIM articles:latest 0 99
حالة الاستخدام 3: خط زمني
REDIS
# نشر منشور (إضافة إلى الخط الزمني للمستخدم)
LPUSH timeline:user:1 "post:1001"
LPUSH timeline:user:1 "post:1002"
# عرض الخط الزمني (أحدث 20 منشورًا)
LRANGE timeline:user:1 0 19
حالة الاستخدام 4: سجل العمليات
REDIS
# تسجيل إجراءات المستخدم
RPUSH log:user:1 "login at 2026-06-23 10:00:00"
RPUSH log:user:1 "view article:123"
RPUSH log:user:1 "like article:123"
# عرض الإجراءات الأخيرة
LRANGE log:user:1 -10 -1
LTRIM: قص القائمة
LTRIM يحتفظ بالعناصر ضمن نطاق محدد ويحذف كل ما عداه.
REDIS
LPUSH mylist "one" "two" "three" "four" "five"
# الاحتفاظ فقط بأول 3 عناصر
LTRIM mylist 0 2
OK
LRANGE mylist 0 -1
1) "five"
2) "four"
3) "three"
حالة الاستخدام: الحفاظ على قائمة بحجم ثابت
REDIS
# إضافة مقالة جديدة والاحتفاظ بحد أقصى 100
LPUSH articles:latest "article:new"
LTRIM articles:latest 0 99
💡 نصيحة: LPUSH + LTRIM معًا يحافظان على قائمة محدودة من أحدث العناصر.
❓ أسئلة شائعة
س ما هو الحد الأقصى لعدد العناصر في القائمة؟
ج حتى 2^32 - 1 (حوالي 4.2 مليار)، لكن عمليًا محدود بالذاكرة。
س ما مدى سرعة LPUSH و RPOP؟
ج تعقيد زمني O(1) — سريع جدًا. عمليات الرأس والذيل وقت ثابت。
س ما مدى سرعة LRANGE؟
ج O(N)، حيث N هو عدد العناصر المرجعة. الحصول على نطاق كبير أبطأ。
س هل BLPOP يحظر إلى أجل غير مسمى؟
ج لا. عيّن مهلة؛ بعد المهلة، يُرجع nil. مهلة 0 تعني الانتظار إلى الأبد。
س ماذا عن الإدراج في منتصف القائمة؟
ج استخدم LINSERT، لكن أداؤه O(N). يُوصى بالعمل فقط عند الرأس والذيل。
📖 ملخص
- القائمة هي تسلسل سلسلة مرتب وقابل للتكرار
- LPUSH/RPUSH إدراج من اليسار واليمين، LPOP/RPOP إخراج من اليسار واليمين
- LRANGE الحصول على العناصر ضمن نطاق، LLEN الحصول على الطول
- RPUSH + LPOP = قائمة انتظار (FIFO)
- LPUSH + LPOP = مكدس (LIFO)
- BLPOP/BRPOP إخراج محظور، يُستخدم لقوائم انتظار المهام
- تطبيقات القوائم: قوائم انتظار رسائل، قوائم حديثة، خطوط زمنية، سجلات عمليات
- LTRIM يقص القائمة للحفاظ على حجم ثابت
📝 تمارين
- تنفيذ قائمة انتظار: استخدم RPUSH و LPOP لتنفيذ قائمة انتظار مهام، محاكاة منتج ومستهلك
- تنفيذ مكدس: استخدم LPUSH و LPOP لتنفيذ مكدس، محاكاة الدفع والإخراج
- قائمة حديثة: نفذ قائمة أحدث المقالات، أضف مقالات واحتفظ بحد أقصى 10
- انتظار محظور: استخدم BLPOP لتنفيذ قائمة انتظار مهام محظورة (يحتاج طرفيتين)
الدرس التالي
في الدرس التالي، سنتعلم قوائم Redis (الجزء 2)، والتي تغطي الاستعلام والتعديل وعمليات القوائم المتقدمة.



