الفرق بين المراجعتين لصفحة: «Laravel/redis»
رؤيا-بنعطية (نقاش | مساهمات) أنشأ الصفحة ب'<noinclude>{{DISPLAYTITLE:التعامل مع قواعد بيانات Redis في Laravel}}</noinclude> تصنيف:Laravel تصنيف:Laravel Database' |
رؤيا-بنعطية (نقاش | مساهمات) لا ملخص تعديل |
||
سطر 2: | سطر 2: | ||
[[تصنيف:Laravel]] | [[تصنيف:Laravel]] | ||
[[تصنيف:Laravel Database]] | [[تصنيف:Laravel Database]] | ||
== مقدمة == | |||
Redis هو مخزن متقدم لمفتاح-قيمة (key-value) وهو مفتوح المصدر، وغالبًا ما يشار إليه على أنه خادم هيكلية البيانات حيث يمكن أن تحتوي المفاتيح على سلاسل نصيّة وشيفرات وقوائم ومجموعات ومجموعات مرتبة. | |||
قبل أن نستخدم Redis مع Laravel، ستحتاج إلى تثبيت حزمة predis/predis عن طريق Composer:<syntaxhighlight lang="php"> | |||
composer require predis/predis | |||
</syntaxhighlight>ويمكنك بدلًا من ذلك تثبيت ملحق PhpRedis PHP عن طريق PECL، ويعد هذا الملحق الأكثر تعقيدًا، ولكن ستكون النتائج ذات أداء أفضل لتطبيقات التي تستخدم Redis بشكل مكثف. | |||
== الضبط == | |||
إن ملف ضبط Redis لتطبيقك موجود في ملف الضبط <code>config/database.php</code>، وفي هذا الملف، سترى مصفوفة redis تحتوي على خوادم Redis التي سيستخدمها تطبيقك:<syntaxhighlight lang="php"> | |||
'redis' => [ | |||
'client' => 'predis', | |||
'default' => [ | |||
'host' => env('REDIS_HOST', 'localhost'), | |||
'password' => env('REDIS_PASSWORD', null), | |||
'port' => env('REDIS_PORT', 6379), | |||
'database' => 0, | |||
], | |||
], | |||
</syntaxhighlight>يجب أن يكون ضبط الخادم الافتراضي كافي للتطوير. ومع ذلك، يمكنك تعديل هذه المصفوفة بحريّة بناءً على البيئة الخاصة بك. كل خادم Redis معرّف في ملف الضبط يتطلّب اسم ومضيف ومنفذ. | |||
=== ضبط العناقيد Clusters === | |||
إذا كان تطبيقك يستخدم عنقود من خوادم Redis، فيجب عليك تعريف هذه العناقيد داخل مفتاح clusters عند ضبط Redis الخاص بك:<syntaxhighlight lang="php"> | |||
'redis' => [ | |||
'client' => 'predis', | |||
'clusters' => [ | |||
'default' => [ | |||
[ | |||
'host' => env('REDIS_HOST', 'localhost'), | |||
'password' => env('REDIS_PASSWORD', null), | |||
'port' => env('REDIS_PORT', 6379), | |||
'database' => 0, | |||
], | |||
], | |||
], | |||
], | |||
</syntaxhighlight>بشكل افتراضي، ستقسّم العناقيد البيانات من جهة العميل على عدة عقد مما يسمح لك بتجميع العقد لاحقًا وإنشاء مساحة كبيرة من الذاكرة العشوائية (RAM) المتوفّرة. ومع ذلك، لاحظ أن تقسيم البيانات من جهة العميل لا يعالج تجاوز الفشل (failover)، لذلك، فهي تتناسب بشكل أساسي مع البيانات المخزّنة مؤقتًا والمتوافرة من مخزن بيانات أساسي آخر. إذا كنت ترغب في استخدام مجموعات Redis المحليّة، يجب عليك تحديد ذلك في مفتاح <code>options</code> في ملف ضبط Redis:<syntaxhighlight lang="php"> | |||
'redis' => [ | |||
'client' => 'predis', | |||
'options' => [ | |||
'cluster' => 'redis', | |||
], | |||
'clusters' => [ | |||
// ... | |||
], | |||
], | |||
</syntaxhighlight> | |||
=== Predis === | |||
بالإضافة إلى خيارات ضبط الخادم الافتراضيّة: <code>host</code> و <code>port</code> و <code>database</code> و <code>password</code>، يدعم Predis معاملات اتصال إضافيّة يمكن تعريفها لكل من خوادم Redis الخاصة بك، وللاستفادة من خيارات الضبط الإضافيّة، أضفهم إلى ضبط خادم Redis في ملف الضبط <code>config/database.php</code>:<syntaxhighlight lang="php"> | |||
'default' => [ | |||
'host' => env('REDIS_HOST', 'localhost'), | |||
'password' => env('REDIS_PASSWORD', null), | |||
'port' => env('REDIS_PORT', 6379), | |||
'database' => 0, | |||
'read_write_timeout' => 60, | |||
], | |||
</syntaxhighlight> | |||
=== PhpRedis === | |||
تنبيه: إذا ثبتّ ملحق PhpRedis PHP عن طريق PECL، فستحتاج إلى تغيير اسم Redis المستعار في ملف الضبط <code>config/app.php</code>. | |||
يجب عليك تغيير خيار <code>client</code> من ملف ضبط Redis إلى phpredis للاستفادة من ملحق PhpRedis، ويوجد هذا الخيار في ملف الضبط <code>config/database.php</code>:<syntaxhighlight lang="php"> | |||
'redis' => [ | |||
'client' => 'phpredis', | |||
// Rest of Redis configuration... | |||
], | |||
</syntaxhighlight>بالإضافة إلى خيارات ضبطا الخادم الافتراضيّة: <code>host</code> و <code>port</code> و <code>database</code> و <code>password</code>، يدعم PhpRedis معاملات الاتصال الإضافيّة التالية: <code>persistent</code>، <code>prefix</code>، <code>read_timeout</code>، <code>timeout</code>، ويمكنك إضافة أي من هذه الخيارات لضبط خادم Redis في ملف الضبط <code>config/database.php</code>:<syntaxhighlight lang="php"> | |||
'default' => [ | |||
'host' => env('REDIS_HOST', 'localhost'), | |||
'password' => env('REDIS_PASSWORD', null), | |||
'port' => env('REDIS_PORT', 6379), | |||
'database' => 0, | |||
'read_timeout' => 60, | |||
], | |||
</syntaxhighlight> | |||
== التفاعل مع Redis == | |||
قد تتفاعل مع Redis من خلال استدعاء توابع مختلفة على واجهة Redis. تدعم واجهة Redis أساليب حيويّة، مما يعني أنه يمكنك استدعاء أي أمر من Redis على الواجهة وسيمرّر الأمر مباشرةً إلى Redis. في هذا المثال، سنستدعي أمر Redis GET عن طريق استدعاء التابع <code>get</code> على واجهة Redis:<syntaxhighlight lang="php"> | |||
<?php | |||
namespace App\Http\Controllers; | |||
use App\Http\Controllers\Controller; | |||
use Illuminate\Support\Facades\Redis; | |||
class UserController extends Controller | |||
{ | |||
/** | |||
* إظهار ملف المستخدم المعطى * | |||
* @param int $id | |||
* @return Response | |||
*/ | |||
public function showProfile($id) | |||
{ | |||
$user = Redis::get('user:profile:'.$id); | |||
return view('user.profile', ['user' => $user]); | |||
} | |||
} | |||
</syntaxhighlight> | |||
كما ذكر أعلاه، يمكنك بالطبع الاتصال بأي من أوامر Redis على واجهة Redis. يستخدم Laravel توابع سحريّة لتمرير الأوامر إلى خادم Redis، لذا مرّر المعاملات التي يتوقعها أمر Redis:<syntaxhighlight lang="php"> | |||
Redis::set('name', 'Taylor'); | |||
$values = Redis::lrange('names', 5, 10); | |||
</syntaxhighlight>يمكنك أيضًا بدلًا من ذلك تمرير الأوامر إلى الخادم باستخدام التابع <code>command</code>، والذي سيقبل اسم الأمر كمعامل أول، ومصفوفة من القيم كمعامل ثاني:<syntaxhighlight lang="php"> | |||
$values = Redis::command('lrange', ['name', 5, 10]); | |||
</syntaxhighlight> | |||
==== استخدام اتصالات Redis متعدّدة ==== | |||
تستطيع الحصول على نسخة Redis عن طريق استدعاء التابع <code>Redis::connection</code>:<syntaxhighlight lang="php"> | |||
$redis = Redis::connection(); | |||
</syntaxhighlight>سيعطيك هذا التابع نسخة لخادم Redis الافتراضي، ويمكنك تمرير اسم الاتصال أو العنقود للتابع <code>connection</code>، للحصول على خادم أو عنقود محدّد كما هو معرّف عند ضبط Redis:<syntaxhighlight lang="php"> | |||
$redis = Redis::connection('my-connection'); | |||
</syntaxhighlight> | |||
=== أوامر Pipelining === | |||
يجب استخدام Pipelining عندما تحتاج إلى إرسال العديد من الأوامر إلى الخادم في عمليّة واحدة. يقبل التابع <code>pipeline</code> معامل واحد: النطاق المغلق (Closure) الذي يتلقى نسخة Redis. يمكنك إصدار جميع أوامرك إلى نسخة Redis وستُنفّذ جميعها في عمليّة واحدة:<syntaxhighlight lang="php"> | |||
Redis::pipeline(function ($pipe) { | |||
for ($i = 0; $i < 1000; $i++) { | |||
$pipe->set("key:$i", $i); | |||
} | |||
}); | |||
</syntaxhighlight> | |||
= Pub / Sub = | |||
يوفّر Laravel واجهة ملائمة لأوامر Redis التالية: <code>publish</code> و <code>subscribe</code>. تسمح لك هذه الأوامر بالاستماع إلى الرسائل على "قناة" معيّنة، ويمكنك نشر الرسائل في القناة من تطبيق آخر، أو حتى استخدام لغة برمجة أخرى، مما يتيح لك سهولة الاتصال بين التطبيقات والعمليات. | |||
لنعّد أولًا مستمع القناة باستخدام التابع <code>subscribe</code>، وسنضع نداء هذا التابع داخل أمر Artisan لأن استدعاء التابع <code>subscribe</code> يبدأ عملية طويلة الأمد:<syntaxhighlight lang="php"> | |||
<?php | |||
namespace App\Console\Commands; | |||
use Illuminate\Console\Command; | |||
use Illuminate\Support\Facades\Redis; | |||
class RedisSubscribe extends Command | |||
{ | |||
/** | |||
* اسم وتوقيع أمر الطرفية * | |||
* @var string | |||
*/ | |||
protected $signature = 'redis:subscribe'; | |||
/** | |||
* وصف أمر الطرفية | |||
* | |||
* @var string | |||
*/ | |||
protected $description = 'Subscribe to a Redis channel'; | |||
/** | |||
* تنفيذ أمر الطرفية * | |||
* @return mixed | |||
*/ | |||
public function handle() | |||
{ | |||
Redis::subscribe(['test-channel'], function ($message) { | |||
echo $message; | |||
}); | |||
} | |||
} | |||
</syntaxhighlight> | |||
يمكننا الآن نشر الرسائل في القناة باستخدام التابع <code>publish</code>:<syntaxhighlight lang="php"> | |||
Route::get('publish', function () { | |||
// Route logic... | |||
Redis::publish('test-channel', json_encode(['foo' => 'bar'])); | |||
}); | |||
</syntaxhighlight> | |||
==== اشتراكات أحرف البدل ==== | |||
باستخدام التابع <code>psubscribe</code>، يمكنك الاشتراك في قناة حرف البدل، والتي قد تكون مفيدة في التقاط جميع الرسائل على جميع القنوات، ويمرّر اسم <code>$channel</code> كمعامل ثاني لتوفير رد انداء (callback) للنطاق المغلق (Closure):<syntaxhighlight lang="php"> | |||
Redis::psubscribe(['*'], function ($message, $channel) { | |||
echo $message; | |||
}); | |||
Redis::psubscribe(['users.*'], function ($message, $channel) { | |||
echo $message; | |||
}); | |||
</syntaxhighlight> | |||
== مصادر == | |||
* [https://laravel.com/docs/5.6/redis صفحة Redis في توثيق Laravel الرسمي.] |
مراجعة 21:20، 20 أكتوبر 2018
مقدمة
Redis هو مخزن متقدم لمفتاح-قيمة (key-value) وهو مفتوح المصدر، وغالبًا ما يشار إليه على أنه خادم هيكلية البيانات حيث يمكن أن تحتوي المفاتيح على سلاسل نصيّة وشيفرات وقوائم ومجموعات ومجموعات مرتبة.
قبل أن نستخدم Redis مع Laravel، ستحتاج إلى تثبيت حزمة predis/predis عن طريق Composer:
composer require predis/predis
ويمكنك بدلًا من ذلك تثبيت ملحق PhpRedis PHP عن طريق PECL، ويعد هذا الملحق الأكثر تعقيدًا، ولكن ستكون النتائج ذات أداء أفضل لتطبيقات التي تستخدم Redis بشكل مكثف.
الضبط
إن ملف ضبط Redis لتطبيقك موجود في ملف الضبط config/database.php
، وفي هذا الملف، سترى مصفوفة redis تحتوي على خوادم Redis التي سيستخدمها تطبيقك:
'redis' => [
'client' => 'predis',
'default' => [
'host' => env('REDIS_HOST', 'localhost'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],
],
يجب أن يكون ضبط الخادم الافتراضي كافي للتطوير. ومع ذلك، يمكنك تعديل هذه المصفوفة بحريّة بناءً على البيئة الخاصة بك. كل خادم Redis معرّف في ملف الضبط يتطلّب اسم ومضيف ومنفذ.
ضبط العناقيد Clusters
إذا كان تطبيقك يستخدم عنقود من خوادم Redis، فيجب عليك تعريف هذه العناقيد داخل مفتاح clusters عند ضبط Redis الخاص بك:
'redis' => [
'client' => 'predis',
'clusters' => [
'default' => [
[
'host' => env('REDIS_HOST', 'localhost'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],
],
],
],
بشكل افتراضي، ستقسّم العناقيد البيانات من جهة العميل على عدة عقد مما يسمح لك بتجميع العقد لاحقًا وإنشاء مساحة كبيرة من الذاكرة العشوائية (RAM) المتوفّرة. ومع ذلك، لاحظ أن تقسيم البيانات من جهة العميل لا يعالج تجاوز الفشل (failover)، لذلك، فهي تتناسب بشكل أساسي مع البيانات المخزّنة مؤقتًا والمتوافرة من مخزن بيانات أساسي آخر. إذا كنت ترغب في استخدام مجموعات Redis المحليّة، يجب عليك تحديد ذلك في مفتاح options
في ملف ضبط Redis:
'redis' => [
'client' => 'predis',
'options' => [
'cluster' => 'redis',
],
'clusters' => [
// ...
],
],
Predis
بالإضافة إلى خيارات ضبط الخادم الافتراضيّة: host
و port
و database
و password
، يدعم Predis معاملات اتصال إضافيّة يمكن تعريفها لكل من خوادم Redis الخاصة بك، وللاستفادة من خيارات الضبط الإضافيّة، أضفهم إلى ضبط خادم Redis في ملف الضبط config/database.php
:
'default' => [
'host' => env('REDIS_HOST', 'localhost'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
'read_write_timeout' => 60,
],
PhpRedis
تنبيه: إذا ثبتّ ملحق PhpRedis PHP عن طريق PECL، فستحتاج إلى تغيير اسم Redis المستعار في ملف الضبط config/app.php
.
يجب عليك تغيير خيار client
من ملف ضبط Redis إلى phpredis للاستفادة من ملحق PhpRedis، ويوجد هذا الخيار في ملف الضبط config/database.php
:
'redis' => [
'client' => 'phpredis',
// Rest of Redis configuration...
],
بالإضافة إلى خيارات ضبطا الخادم الافتراضيّة: host
و port
و database
و password
، يدعم PhpRedis معاملات الاتصال الإضافيّة التالية: persistent
، prefix
، read_timeout
، timeout
، ويمكنك إضافة أي من هذه الخيارات لضبط خادم Redis في ملف الضبط config/database.php
:
'default' => [
'host' => env('REDIS_HOST', 'localhost'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
'read_timeout' => 60,
],
التفاعل مع Redis
قد تتفاعل مع Redis من خلال استدعاء توابع مختلفة على واجهة Redis. تدعم واجهة Redis أساليب حيويّة، مما يعني أنه يمكنك استدعاء أي أمر من Redis على الواجهة وسيمرّر الأمر مباشرةً إلى Redis. في هذا المثال، سنستدعي أمر Redis GET عن طريق استدعاء التابع get
على واجهة Redis:
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Redis;
class UserController extends Controller
{
/**
* إظهار ملف المستخدم المعطى *
* @param int $id
* @return Response
*/
public function showProfile($id)
{
$user = Redis::get('user:profile:'.$id);
return view('user.profile', ['user' => $user]);
}
}
كما ذكر أعلاه، يمكنك بالطبع الاتصال بأي من أوامر Redis على واجهة Redis. يستخدم Laravel توابع سحريّة لتمرير الأوامر إلى خادم Redis، لذا مرّر المعاملات التي يتوقعها أمر Redis:
Redis::set('name', 'Taylor');
$values = Redis::lrange('names', 5, 10);
يمكنك أيضًا بدلًا من ذلك تمرير الأوامر إلى الخادم باستخدام التابع command
، والذي سيقبل اسم الأمر كمعامل أول، ومصفوفة من القيم كمعامل ثاني:
$values = Redis::command('lrange', ['name', 5, 10]);
استخدام اتصالات Redis متعدّدة
تستطيع الحصول على نسخة Redis عن طريق استدعاء التابع Redis::connection
:
$redis = Redis::connection();
سيعطيك هذا التابع نسخة لخادم Redis الافتراضي، ويمكنك تمرير اسم الاتصال أو العنقود للتابع connection
، للحصول على خادم أو عنقود محدّد كما هو معرّف عند ضبط Redis:
$redis = Redis::connection('my-connection');
أوامر Pipelining
يجب استخدام Pipelining عندما تحتاج إلى إرسال العديد من الأوامر إلى الخادم في عمليّة واحدة. يقبل التابع pipeline
معامل واحد: النطاق المغلق (Closure) الذي يتلقى نسخة Redis. يمكنك إصدار جميع أوامرك إلى نسخة Redis وستُنفّذ جميعها في عمليّة واحدة:
Redis::pipeline(function ($pipe) {
for ($i = 0; $i < 1000; $i++) {
$pipe->set("key:$i", $i);
}
});
Pub / Sub
يوفّر Laravel واجهة ملائمة لأوامر Redis التالية: publish
و subscribe
. تسمح لك هذه الأوامر بالاستماع إلى الرسائل على "قناة" معيّنة، ويمكنك نشر الرسائل في القناة من تطبيق آخر، أو حتى استخدام لغة برمجة أخرى، مما يتيح لك سهولة الاتصال بين التطبيقات والعمليات.
لنعّد أولًا مستمع القناة باستخدام التابع subscribe
، وسنضع نداء هذا التابع داخل أمر Artisan لأن استدعاء التابع subscribe
يبدأ عملية طويلة الأمد:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Redis;
class RedisSubscribe extends Command
{
/**
* اسم وتوقيع أمر الطرفية *
* @var string
*/
protected $signature = 'redis:subscribe';
/**
* وصف أمر الطرفية
*
* @var string
*/
protected $description = 'Subscribe to a Redis channel';
/**
* تنفيذ أمر الطرفية *
* @return mixed
*/
public function handle()
{
Redis::subscribe(['test-channel'], function ($message) {
echo $message;
});
}
}
يمكننا الآن نشر الرسائل في القناة باستخدام التابع publish
:
Route::get('publish', function () {
// Route logic...
Redis::publish('test-channel', json_encode(['foo' => 'bar']));
});
اشتراكات أحرف البدل
باستخدام التابع psubscribe
، يمكنك الاشتراك في قناة حرف البدل، والتي قد تكون مفيدة في التقاط جميع الرسائل على جميع القنوات، ويمرّر اسم $channel
كمعامل ثاني لتوفير رد انداء (callback) للنطاق المغلق (Closure):
Redis::psubscribe(['*'], function ($message, $channel) {
echo $message;
});
Redis::psubscribe(['users.*'], function ($message, $channel) {
echo $message;
});