نسخه:

ردیس

معرفی

Redis یک فروشگاه منبع باز و پیشرفته با ارزش کلیدی است. اغلب از آن به عنوان سرور ساختار داده یاد می شود زیرا کلیدها می توانند شامل رشته ها ، هش ها ، لیست ها ، مجموعه ها و مجموعه های مرتب شده باشند .

قبل از استفاده از Redis با لاراول، ما شما را به نصب و استفاده از پسوند phpredis PHP از طریق PECL تشویق می کنیم. نصب افزونه در مقایسه با بسته‌های PHP «سرزمین کاربر» پیچیده‌تر است، اما ممکن است برای برنامه‌هایی که از Redis استفاده زیادی می‌کنند، عملکرد بهتری داشته باشد. اگر از Laravel Sail استفاده می کنید ، این افزونه قبلاً در کانتینر Docker برنامه شما نصب شده است.

اگر نمی توانید پسوند phpredis را نصب کنید، می توانید predis/predis بسته را از طریق Composer نصب کنید. Predis یک کلاینت Redis است که به طور کامل با PHP نوشته شده است و نیازی به پسوند اضافی ندارد:

composer require predis/predis

پیکربندی

می توانید تنظیمات Redis برنامه خود را از طریق config/database.php فایل پیکربندی پیکربندی کنید. در این فایل، یک redis آرایه حاوی سرورهای Redis که توسط برنامه شما استفاده می شود را مشاهده خواهید کرد :

'redis' => [
 
'client' => env('REDIS_CLIENT', 'phpredis'),
 
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DB', 0),
],
 
'cache' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_CACHE_DB', 1),
],
 
],

هر سرور Redis که در فایل پیکربندی شما تعریف شده است باید دارای یک نام، میزبان و یک پورت باشد، مگر اینکه یک URL واحد برای نشان دادن اتصال Redis تعریف کنید:

'redis' => [
 
'client' => env('REDIS_CLIENT', 'phpredis'),
 
'default' => [
'url' => 'tcp://127.0.0.1:6379?database=0',
],
 
'cache' => [
'url' => 'tls://user:password@127.0.0.1:6380?database=1',
],
 
],

پیکربندی طرح اتصال

به طور پیش فرض، مشتریان Redis tcp هنگام اتصال به سرورهای Redis شما از این طرح استفاده می کنند. با این حال، می توانید با تعیین یک scheme گزینه پیکربندی در آرایه پیکربندی سرور Redis خود، از رمزگذاری TLS / SSL استفاده کنید:

'redis' => [
 
'client' => env('REDIS_CLIENT', 'phpredis'),
 
'default' => [
'scheme' => 'tls',
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DB', 0),
],
 
],

خوشه ها

اگر برنامه شما از خوشه ای از سرورهای Redis استفاده می کند، باید این خوشه ها را در یک clusters کلید از پیکربندی Redis خود تعریف کنید. این کلید پیکربندی به طور پیش فرض وجود ندارد، بنابراین باید آن را در config/database.php فایل پیکربندی برنامه خود ایجاد کنید:

'redis' => [
 
'client' => env('REDIS_CLIENT', 'phpredis'),
 
'clusters' => [
'default' => [
[
'host' => env('REDIS_HOST', 'localhost'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],
],
],
 
],

به‌طور پیش‌فرض، خوشه‌ها اشتراک‌گذاری سمت کلاینت را در گره‌های شما انجام می‌دهند و به شما این امکان را می‌دهند که گره‌ها را ادغام کرده و مقدار زیادی RAM در دسترس ایجاد کنید. با این حال، اشتراک‌گذاری سمت کلاینت، Failover را کنترل نمی‌کند. بنابراین، در درجه اول برای داده های کش موقتی مناسب است که از یک فروشگاه داده اولیه دیگر در دسترس است.

اگر می‌خواهید از خوشه‌بندی بومی Redis به‌جای اشتراک‌گذاری سمت کلاینت استفاده کنید، می‌توانید این را با تنظیم options.cluster مقدار پیکربندی در فایل پیکربندی redis برنامه خود مشخص کنید: config/database.php

'redis' => [
 
'client' => env('REDIS_CLIENT', 'phpredis'),
 
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
],
 
'clusters' => [
// ...
],
 
],

پردیس

اگر می خواهید برنامه شما از طریق بسته Predis با Redis تعامل داشته باشد، باید مطمئن شوید که REDIS_CLIENT مقدار متغیر محیطی predis :

'redis' => [
 
'client' => env('REDIS_CLIENT', 'predis'),
 
// ...
],

علاوه بر گزینه‌های پیش‌فرض host ،،، و پیکربندی سرور، Predis از پارامترهای اتصال اضافی که ممکن است برای هر یک از سرورهای Redis شما تعریف شوند، پشتیبانی port می‌کند . برای استفاده از این گزینه های پیکربندی اضافی، آنها را به پیکربندی سرور Redis خود در فایل پیکربندی برنامه خود اضافه کنید : database password config/database.php

'default' => [
'host' => env('REDIS_HOST', 'localhost'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
'read_write_timeout' => 60,
],

نام مستعار نمای ردیس

config/app.php فایل پیکربندی لاراول حاوی aliases آرایه‌ای است که تمام نام‌های مستعار کلاس را که توسط فریم‌ورک ثبت می‌شوند، تعریف می‌کند. به طور پیش فرض، هیچ نام مستعاری گنجانده نشده است زیرا با نام کلاس ارائه شده توسط پسوند phpredis Redis در تضاد است . Redis اگر از مشتری Predis استفاده می کنید و می خواهید Redis نام مستعار اضافه کنید، می توانید آن را به آرایه موجود در فایل پیکربندی aliases برنامه خود اضافه کنید: config/app.php

'aliases' => Facade::defaultAliases()->merge([
'Redis' => Illuminate\Support\Facades\Redis::class,
])->toArray(),

phpredis

به طور پیش فرض، لاراول از پسوند phpredis برای برقراری ارتباط با Redis استفاده می کند. کلاینتی که لاراول از آن برای برقراری ارتباط با Redis استفاده می کند، توسط مقدار redis.client گزینه پیکربندی دیکته می شود، که معمولاً مقدار REDIS_CLIENT متغیر محیطی را منعکس می کند:

'redis' => [
 
'client' => env('REDIS_CLIENT', 'phpredis'),
 
// Rest of Redis configuration...
],

علاوه بر گزینه های پیش فرض scheme ،،،، و پیکربندی سرور، phpredis از پارامترهای اتصال اضافی زیر پشتیبانی می کند host : , , , , , , و . می توانید یکی از این گزینه ها را به پیکربندی سرور Redis خود در فایل پیکربندی اضافه کنید: port database password name persistent persistent_id prefix read_timeout retry_interval timeout context config/database.php

'default' => [
'host' => env('REDIS_HOST', 'localhost'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
'read_timeout' => 60,
'context' => [
// 'auth' => ['username', 'secret'],
// 'stream' => ['verify_peer' => false],
],
],

phpredis سریال سازی و فشرده سازی

پسوند phpredis همچنین ممکن است برای استفاده از انواع الگوریتم های سریال سازی و فشرده سازی پیکربندی شود. این الگوریتم ها را می توان از طریق options آرایه پیکربندی Redis پیکربندی کرد:

'redis' => [
 
'client' => env('REDIS_CLIENT', 'phpredis'),
 
'options' => [
'serializer' => Redis::SERIALIZER_MSGPACK,
'compression' => Redis::COMPRESSION_LZ4,
],
 
// Rest of Redis configuration...
],

الگوریتم‌های سریال‌سازی پشتیبانی‌شده در حال حاضر عبارتند از: ( Redis::SERIALIZER_NONE پیش‌فرض) Redis::SERIALIZER_PHP ،،،، و . Redis::SERIALIZER_JSON Redis::SERIALIZER_IGBINARY Redis::SERIALIZER_MSGPACK

الگوریتم های فشرده سازی پشتیبانی شده عبارتند از: Redis::COMPRESSION_NONE (پیش فرض) Redis::COMPRESSION_LZF ،،، Redis::COMPRESSION_ZSTD و Redis::COMPRESSION_LZ4 .

تعامل با Redis

می توانید با فراخوانی روش های مختلف در Redis نما با Redis تعامل کنید . نما Redis از روش های پویا پشتیبانی می کند، به این معنی که می توانید هر دستور Redis را در نما فراخوانی کنید و دستور مستقیماً به Redis ارسال می شود. در این مثال، GET دستور Redis را با فراخوانی get متد روی نما فراخوانی می کنیم Redis :

<?php
 
namespace App\Http\Controllers;
 
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Redis;
 
class UserController extends Controller
{
/**
* Show the profile for the given user.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
return view('user.profile', [
'user' => Redis::get('user:profile:'.$id)
]);
}
}

همانطور که در بالا ذکر شد، می توانید هر یک از دستورات Redis را در Redis نما فراخوانی کنید. لاراول از متدهای جادویی برای ارسال دستورات به سرور Redis استفاده می کند. اگر یک دستور Redis انتظار آرگومان‌هایی را دارد، باید آن‌ها را به روش مربوط به نما منتقل کنید:

use Illuminate\Support\Facades\Redis;
 
Redis::set('name', 'Taylor');
 
$values = Redis::lrange('names', 5, 10);

Redis از طرف دیگر، می‌توانید با استفاده از متد facade دستورات را به سرور ارسال کنید command ، که نام دستور را به عنوان اولین آرگومان و آرایه‌ای از مقادیر را به عنوان آرگومان دوم می‌پذیرد:

$values = Redis::command('lrange', ['name', 5, 10]);

استفاده از چندین اتصال Redis

فایل پیکربندی برنامه شما config/database.php به شما امکان می دهد چندین اتصال / سرور Redis را تعریف کنید. می توانید با استفاده از روش Redis نما به یک اتصال Redis خاص متصل شوید connection :

$redis = Redis::connection('connection-name');

برای به دست آوردن نمونه ای از اتصال Redis پیش فرض، می توانید connection متد را بدون هیچ آرگومان اضافی فراخوانی کنید:

$redis = Redis::connection();

معاملات

روش Redis نما، پوشش مناسبی را در اطراف دستورات و دستورات transaction Redis فراهم می کند . روش بسته شدن را به عنوان تنها آرگومان خود می پذیرد. این بسته یک نمونه اتصال Redis را دریافت می کند و ممکن است هر دستوری را که مایل است به این نمونه صادر کند. تمام دستورات Redis صادر شده در بسته شدن در یک تراکنش اتمی اجرا می شوند: MULTI EXEC transaction

use Illuminate\Support\Facades\Redis;
 
Redis::transaction(function ($redis) {
$redis->incr('user_visits', 1);
$redis->incr('total_visits', 1);
});

هنگام تعریف تراکنش Redis، نمی توانید هیچ مقداری را از اتصال Redis بازیابی کنید. به یاد داشته باشید، تراکنش شما به صورت یک عملیات اتمی انجام می شود و تا زمانی که کل بسته شدن شما اجرای دستورات خود را به پایان نرساند، آن عملیات اجرا نمی شود.

اسکریپت های لوا

این eval روش روش دیگری را برای اجرای چندین دستور Redis در یک عملیات اتمی ارائه می دهد. با این حال، این eval روش این مزیت را دارد که می‌تواند با مقادیر کلیدی Redis در طول آن عملیات تعامل داشته باشد و آنها را بازرسی کند. اسکریپت های Redis به زبان برنامه نویسی Lua نوشته شده اند .

این eval روش در ابتدا می تواند کمی ترسناک باشد، اما ما یک مثال اساسی برای شکستن یخ را بررسی می کنیم. روش eval انتظار چندین آرگومان را دارد. ابتدا باید اسکریپت Lua (به عنوان رشته) را به متد ارسال کنید. در مرحله دوم، شما باید تعداد کلیدهایی را که اسکریپت با آنها تعامل دارد (به عنوان یک عدد صحیح) ارسال کنید. ثالثاً باید نام آن کلیدها را بفرستید. در نهایت، می‌توانید هر آرگومان اضافی دیگری را که نیاز به دسترسی دارید در اسکریپت خود ارسال کنید.

در این مثال، یک شمارنده را افزایش می‌دهیم، مقدار جدید آن را بررسی می‌کنیم و اگر مقدار شمارنده اول بزرگتر از پنج باشد، شمارنده دوم را افزایش می‌دهیم. در نهایت، مقدار اولین شمارنده را برمی گردانیم:

$value = Redis::eval(<<<'LUA'
local counter = redis.call("incr", KEYS[1])
 
if counter > 5 then
redis.call("incr", KEYS[2])
end
 
return counter
LUA, 2, 'first-counter', 'second-counter');

لطفاً برای اطلاعات بیشتر در مورد اسکریپت نویسی Redis به مستندات Redis مراجعه کنید.

دستورات لوله کشی

گاهی اوقات ممکن است لازم باشد ده ها دستور Redis را اجرا کنید. به جای اینکه برای هر دستور به سرور Redis خود سفر کنید، می توانید از این pipeline روش استفاده کنید. این pipeline روش یک آرگومان را می پذیرد: یک بسته که یک نمونه Redis را دریافت می کند. شما می توانید تمام دستورات خود را به این نمونه Redis صادر کنید و همه آنها به طور همزمان به سرور Redis ارسال می شوند تا سفرهای شبکه به سرور کاهش یابد. دستورات همچنان به ترتیبی که صادر شده اند اجرا می شوند:

use Illuminate\Support\Facades\Redis;
 
Redis::pipeline(function ($pipe) {
for ($i = 0; $i < 1000; $i++) {
$pipe->set("key:$i", $i);
}
});

میخانه / فرعی

لاراول یک رابط کاربری مناسب برای Redis publish و subscribe دستورات فراهم می کند. این دستورات Redis به شما این امکان را می دهد که به پیام ها در یک "کانال" خاص گوش دهید. می‌توانید پیام‌هایی را از برنامه‌ای دیگر به کانال منتشر کنید، یا حتی از زبان برنامه‌نویسی دیگری استفاده کنید، که امکان ارتباط آسان بین برنامه‌ها و فرآیندها را فراهم می‌کند.

ابتدا، بیایید یک شنونده کانال را با استفاده از subscribe روش تنظیم کنیم. ما این فراخوانی متد را در یک دستور Artisan قرار می‌دهیم زیرا فراخوانی subscribe متد یک فرآیند طولانی‌مدت را آغاز می‌کند:

<?php
 
namespace App\Console\Commands;
 
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Redis;
 
class RedisSubscribe extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'redis:subscribe';
 
/**
* The console command description.
*
* @var string
*/
protected $description = 'Subscribe to a Redis channel';
 
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
Redis::subscribe(['test-channel'], function ($message) {
echo $message;
});
}
}

اکنون می توانیم با استفاده از روش زیر پیام هایی را برای کانال منتشر کنیم publish :

use Illuminate\Support\Facades\Redis;
 
Route::get('/publish', function () {
// ...
 
Redis::publish('test-channel', json_encode([
'name' => 'Adam Wathan'
]));
});

اشتراک های Wildcard

با استفاده از این psubscribe روش، می‌توانید مشترک یک کانال عام شوید، که ممکن است برای دریافت همه پیام‌ها در همه کانال‌ها مفید باشد. نام کانال به عنوان آرگومان دوم برای بسته شدن ارائه شده ارسال می شود:

Redis::psubscribe(['*'], function ($message, $channel) {
echo $message;
});
 
Redis::psubscribe(['users.*'], function ($message, $channel) {
echo $message;
});