نسخه:

ردیس

معرفی

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

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

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

composer require predis/predis:^2.0

پیکربندی

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

'redis' => [
 
'client' => env('REDIS_CLIENT', 'phpredis'),
 
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
],
 
'default' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'username' => env('REDIS_USERNAME'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_DB', '0'),
],
 
'cache' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'username' => env('REDIS_USERNAME'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_CACHE_DB', '1'),
],
 
],

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

'redis' => [
 
'client' => env('REDIS_CLIENT', 'phpredis'),
 
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
],
 
'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 استفاده کنید:

'default' => [
'scheme' => 'tls',
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'username' => env('REDIS_USERNAME'),
'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'),
 
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
],
 
'clusters' => [
'default' => [
[
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'username' => env('REDIS_USERNAME'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_DB', '0'),
],
],
],
 
// ...
],

به‌طور پیش‌فرض، لاراول از خوشه‌بندی بومی Redis استفاده می‌کند، زیرا options.cluster مقدار پیکربندی روی redis . خوشه‌بندی ردیس یک گزینه پیش‌فرض عالی است، زیرا به‌خوبی شکست را مدیریت می‌کند.

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

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

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

پردیس

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

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

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

'default' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'username' => env('REDIS_USERNAME'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_DB', '0'),
'read_write_timeout' => 60,
],

PhpRedis

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

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

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

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

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

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

'redis' => [
 
'client' => env('REDIS_CLIENT', 'phpredis'),
 
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
'serializer' => Redis::SERIALIZER_MSGPACK,
'compression' => Redis::COMPRESSION_LZ4,
],
 
// ...
],

سریال‌سازهایی که در حال حاضر پشتیبانی می‌شوند عبارتند از: ( 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;
use Illuminate\View\View;
 
class UserController extends Controller
{
/**
* Show the profile for the given user.
*/
public function show(string $id): View
{
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 Redis;
use Illuminate\Support\Facades;
 
Facades\Redis::transaction(function (Redis $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 Redis;
use Illuminate\Support\Facades;
 
Facades\Redis::pipeline(function (Redis $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.
*/
public function handle(): void
{
Redis::subscribe(['test-channel'], function (string $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 (string $message, string $channel) {
echo $message;
});
 
Redis::psubscribe(['users.*'], function (string $message, string $channel) {
echo $message;
});