قوائم Redis (الجزء 1)

القائمة هي تسلسل مرتب وقابل للتكرار من السلاسل. يغطي هذا الدرس عمليات القوائم الأساسية.

ما هي القائمة؟

القائمة تشبه:

ميزات قائمة 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). يُوصى بالعمل فقط عند الرأس والذيل。

📖 ملخص

📝 تمارين

  1. تنفيذ قائمة انتظار: استخدم RPUSH و LPOP لتنفيذ قائمة انتظار مهام، محاكاة منتج ومستهلك
  2. تنفيذ مكدس: استخدم LPUSH و LPOP لتنفيذ مكدس، محاكاة الدفع والإخراج
  3. قائمة حديثة: نفذ قائمة أحدث المقالات، أضف مقالات واحتفظ بحد أقصى 10
  4. انتظار محظور: استخدم BLPOP لتنفيذ قائمة انتظار مهام محظورة (يحتاج طرفيتين)

الدرس التالي

في الدرس التالي، سنتعلم قوائم Redis (الجزء 2)، والتي تغطي الاستعلام والتعديل وعمليات القوائم المتقدمة.

100%