ردیس
معرفی
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 counterLUA, 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;});