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