التعامل مع قواعد بيانات Redis في Laravel

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث

مقدمة

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;

});

مصادر