Redis یک مکانی برای ذخیره داده است که داده ها را عمدتاً در حافظه ذخیره می کند. این سریعتر از دیتابیس های سنتی است و بسیار محبوب شده است.
در این آموزش، اصول اولیه و نحوه عملکرد Redis، زمان استفاده از آن، نحوه نصب آن بر روی دستگاه خود و نحوه استفاده از آن به عنوان یک سیستم کش در یک برنامه وب PHP را خواهید آموخت.
Redis چیست؟
Redis یک ذخیره کننده داده است،مانند یک دیتابیس، اما به این صورت ذخیره می کند که دادهها را عمدتاً در حافظه ذخیره میکند. این باعث می شود آن را بسیار سریعتر از دیتابیس های سنتی که در آن داده ها در دیسک ها ذخیره می شود. به دلیل این سرعت، Redis اغلب به عنوان یک ابزار ذخیره سازی استفاده می شود.
Redis می تواند داده ها را در هر نوع داده ای ذخیره کند، زیرا از یک سیستم جفت کلید-مقدار برای ذخیره داده ها استفاده می کند. این نیز بر خلاف دیتابیس های سنتی است که از داکیومنت یا ردیف ها استفاده می کنند.
شما می توانید دیتابیس Redis را به عنوان یک شی بزرگ JSON در نظر بگیرید، جایی که همه چیز در دیتابیس یک جفت کلید-مقدار است. این بدان معناست که ممکن است بهترین مکان برای ذخیره داده های ساختاریافته نباشد.
شما همچنین می توانید از Redis به عنوان دیتابیس استفاده کنید، زیرا توانایی نوشتن داده ها بر روی دیسک را برای ماندگاری دارد. میتوانید Redis را به گونهای پیکربندی کنید که دادهها به صورت دورهای یا پس از هر فرمانی که صادر میکنید، باقی بماند. هنگامی که Redis برای داده های ماندگار پیکربندی نشده است، بسیار فرار است و خرابی سیستم منجر به از دست رفتن داده می شود.
Redis در برنامه های سطح تولید محبوب است و توسط شرکت های بزرگی مانند Twitter، Github، SnapChat و StackOverFlow استفاده می شود.
چه زمانی از Redis استفاده کنیم؟
برای گذرواژه های یک بار مصرف (OTP): این رمزها معمولا برای یک بار استفاده تولید می شوند و طول عمر کوتاهی دارند. با توانایی Redis برای تعیین تاریخ انقضا برای دادهها، میتوانید OTP را بدون نگرانی در مورد حذف آنها پس از یک دوره مشخص، با خیال راحت ذخیره کنید.
برای منابعی که اغلب به آنها دسترسی پیدا می کنید: برای داده هایی که زیاد تغییر نمی کنند اما دسترسی زیادی به آنها می شود، می توانید از Redis برای صرفه جویی در زمانی که صرف کوئری از دیتابیس یا برقراری تماس با برخی از سرویس های خارجی می شد استفاده کنید.
برای کوئری های سنگین: برای کوئری های دیتابیس داده که زمان بر هستند و همچنین اغلب تغییر نمی کنند، از Redis استفاده کنید تا با ذخیره نتایج تا زمانی که دوست دارید، این زمان را کاهش دهید.
نحوه نصب Redis
شما می توانید Redis را روی هر سیستم عاملی نصب کنید. در اینجا دستورالعملهای مربوط به macOS و Windows Subsystem برای لینوکس و لینوکس آمده است.
سیستم عامل مک
برای نصب Redis در macOS، اجرا کنید:
brew install redis
سپس این دستور را برای شروع Redis اجرا کنید:
redis-server
Windows Subsystem برای لینوکس و لینوکس
Redis هنوز دقیقاً از سیستم عامل ویندوز پشتیبانی نمی کند، بنابراین می توانید WSL (زیر سیستم ویندوز برای لینوکس) را روی ویندوز نصب کنید تا یک محیط لینوکس داشته باشید.
برای نصب Redis در لینوکس، اجرا کنید:
curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list
sudo apt-get update
sudo apt-get install redis
سپس این دستور را برای شروع Redis اجرا کنید:
sudo service redis-server start
اکنون که Redis نصب شده است، می توانید با اجرای redis-cli ping
آن را تست کنید. این خروجی "PONG"
را خواهد داد.
مبانی ردیس
برای استفاده از Redis به عنوان یک REPL یا به عنوان یک برنامه مستقل، redis-cli
را اجرا کنید. محیط REPL را باز می کند.
نحوه تنظیم داده ها
از کلمه کلیدی SET برای تنظیم یک جفت مقدار کلید در Redis استفاده کنید. برای تنظیم یک کلید username
به مقدار abdorrahmani، این را اجرا کنید:
SET username abdorrahmani
نحوه دریافت داده
برای دریافت کلید username
اخیراً ذخیره شده، از کلمه کلیدی GET مانند زیر استفاده کنید:
GET username
نحوه حذف داده ها
همچنین می توانید کلید ذخیره شده قبلی را با استفاده از کلمه کلیدی DEL مانند زیر حذف کنید:
DEL username
چگونه بررسی کنیم که آیا یک مقدار وجود دارد یا خیر؟
با استفاده از کلمه کلیدی EXISTS
می توانید وجود یک کلید را بررسی کنید. وقتی کلید وجود نداشته باشد 0
و اگر وجود داشته باشد 1
را برمی گرداند. می توانید با بررسی اینکه آیا کلید نام کاربری اخیراً حذف شده وجود دارد یا خیر، آزمایش کنید.
نحوه تعیین زمان برای زندگی برای کلیدها
Redis به شما امکان می دهد مشخص کنید که چه مدت زمانی باید یک کلید در هنگام ایجاد آن وجود داشته باشد. این یکی از ویژگی های واقعا عالی Redis است. برای انجام این کار، از کلمه کلیدی SETEX
مانند زیر استفاده کنید:
SETEX key seconds value
با استفاده از کلمه کلیدی TTL
می توانید زمان زندگی برای یک کلید خاص را بررسی کنید. اگر کلید منقضی نشده باشد، 1-
را برمی گرداند، به این معنی که به طور نامحدود ذخیره می شود. اگر کلید وجود نداشته باشد 2-
را برمی گرداند. و در صورت وجود کلید زمان را بر حسب ثانیه برمی گرداند.
می توانید با استفاده از کلمه کلیدی EXPIRE
برای کلیدی که قبلاً بدون زمان انقضا ایجاد شده است، زمان انقضا را بر حسب ثانیه تنظیم کنید. به عنوان مثال، یک کلید برای ذخیره یک متغیر age
با مقدار 26 ایجاد کنید.
SET age 26
سپس، زمان انقضا 10 ثانیه برای آن تعیین کنید.
EXPIRE age 20
زمان باقی مانده برای زندگی را چند بار بررسی کنید تا ببینید که چگونه در واقع کاهش می یابد و در نهایت دوباره وجود ندارد.
چگونه یک اپلیکیشن ساده با Redis بسازیم
برای کمک به درک نحوه عملکرد Redis، اکنون یک برنامه وب پایه ایجاد می کنیم که از Redis برای ذخیره داده ها برای بارگیری سریعتر پاسخ ها استفاده می کند. شما در حال ساخت یک برنامه کاربردی ساده خواهید بود که داده های تصاویر را از JSONPlaceholder
فتچ می کند و آنها را برمی گرداند.
با استفاده از Composer یک پروژه PHP جدید ایجاد کنید
یک پوشه جدید برای پروژه ایجاد کنید، دایرکتوری را به پوشه ایجاد شده جدید تغییر دهید و ترکیب زیر را برای ایجاد یک پروژه Composer جدید اجرا کنید:
composer init -q
این یک فایل composer.json
جدید ایجاد می کند که باید شبیه به این باشد:
{
"require": {}
}
در مرحله بعد، یک پوشه عمومی برای قرار دادن فایل های کد رو به رو عمومی خود ایجاد کنید. سپس یک فایل index.php
جدید در پوشه ایجاد کنید.
فعلاً مقداری از محتوای boilerplate
را در فایل PHP قرار دهید و یک سرور راه اندازی کنید.
<?php
echo "Hello World!";
php -S localhost:8080
یک روتر ساده نصب کنید و به درخواست ها رسیدگی کنید
برای تکمیل پروژه، یک روتر ساده PHP، Altorouter
، و یک سرویس کلاینت وب، Guzzlehttp
را نصب کنید.
composer require altorouter/altorouter guzzlehttp/guzzle
index.php
را بهروزرسانی کنید تا حاوی این کد باشد:
<?php
// Import composer autoload file
require_once __DIR__ . '/../vendor/autoload.php';
// Import GuzzleHttp Client
use GuzzleHttp\Client;
// Instantiate router and web client
$router = new AltoRouter();
$client = new Client();
// Register Sample route
$router->map('GET', '/', function () {
// Set response Content-Type
header('Content-Type: application/json; charset=utf-8');
// Return basic response
echo json_encode(['data' => 'Hello World']);
});
/**
* Route to get all photos
*/
$router->map('GET', '/photos', function () use ($client) {
// Make request to JSONPlaceholder
$response = $client->request('GET', 'https://jsonplaceholder.typicode.com/photos');
header('Content-Type: application/json; charset=utf-8');
echo json_encode([
'data' => json_decode($response->getBody()->getContents())
]);
});
/**
* Route to get single photo by id
*/
$router->map('GET', '/photos/[i:id]', function (int $id) use ($client) {
$response = $client->request('GET', 'https://jsonplaceholder.typicode.com/photos/' . $id);
header('Content-Type: application/json; charset=utf-8');
echo json_encode([
'data' => json_decode($response->getBody()->getContents())
]);
});
$match = $router->match();
if( is_array($match) && is_callable( $match['target'] ) ) {
call_user_func_array( $match['target'], $match['params'] );
} else {
// no route was matched
header( $_SERVER["SERVER_PROTOCOL"] . ' 404 Not Found');
}
کد کاملاً واضح است. اما، در اینجا یک تفکیک برای وضوح وجود دارد. از خطوط 1-11، کلاس های مورد نیاز GuzzleHttp و AltoRouter وارد و نمونه سازی می شوند.
از خطوط 14-20، اولین مسیر با یک پکیج ساده که "Hello World
" را برمی گرداند، ثبت می شود.
خطوط 25-45 دو مسیر دیگر را ثبت میکنند، یکی برای fetch همه عکسها، photos/
و دیگری برای fetch یک عکس، photos/id/
.
خطوط نهایی بر اساس مستندات پکیج روتر مورد نیاز است تا در واقع پکیج های تعیین شده در اعلامیه مسیرها را اجرا کند.
می توانید این مسیرها را با استفاده از Postman تست کنید.
Redis را نصب و راه اندازی کنید
این زمانها را میتوان با ذخیره کردن نتایج درخواست اصلی به JSONPlaceholder
کاهش داد، سپس به جای درخواست هر بار، یک پاسخ از حافظه پنهان بازگردانید.
برای استفاده از Redis با PHP، پسوند PhpRedis را نصب کنید. این افزونه یک API برای برقراری ارتباط با Redis فراهم می کند. با استفاده از دستور زیر می توانید آن را به راحتی نصب کنید:
pecl install redis
پس از نصب، می توانید از این کلاس در پروژه PHP خود استفاده کنید. کلاس را وارد کنید و آن را در بالای فایل index.php
خود نمونه سازی کنید:
$redis = new Redis();
$redis->connect('127.0.0.1');
پس از انجام این کار، اکنون می توانید از Redis در پروژه خود استفاده کنید.
نحوه کش کردن داده ها با Redis
پاسخ JSON خام برگشتی از JSONPlaceholde
r به Redis را با زمان انقضا 1 ساعت (3600 ثانیه) ذخیره کنید.
$response = $client->request('GET', 'https://jsonplaceholder.typicode.com/photos');
$redis->setex(
'photos',
3600,
$response->getBody()->getContents()
);
در اینجا، یک کلید جدید به نام photos
ایجاد میکنید، به آن زمان انقضا ۱ ساعت میدهید، سپس پاسخ خام دریافتشده از JSONPlaceholder
را به آن اختصاص میدهید.
اما در این مرحله API هنوز زمان زیادی طول می کشد تا پاسخ دهد. این به این دلیل است که شما فقط این پاسخ را ذخیره می کنید، اما از Redis برای برگرداندن پاسخ استفاده نمی کنید.
برای رفع این مشکل، وقتی درخواست جدیدی وارد میشود، بررسی کنید که آیا قبلاً دادههایی در حافظه ذخیره شده است یا خیر. اگر بله، داده ها را در حافظه برمی گردانید، در غیر این صورت، با JSONPlaceholder
صدا می زند.
بلوک photos/
را به این آپدیت کنید:
/**
* Route to get all photos
*/
$router->map('GET', '/photos', function () use ($client, $redis) {
// Check if Redis has the key
if (!$redis->exists('photos')) {
$response = $client->request('GET', 'https://jsonplaceholder.typicode.com/photos');
// Store the data for next use
$redis->setex(
'photos',
REDIS_STANDARD_EXPIRY,
$response->getBody()->getContents()
);
}
header('Content-Type: application/json; charset=utf-8');
echo json_encode([
'data' => json_decode($redis->get('photos'))
]);
});
با آزمایش در Postman برای مشاهده پیشرفتها، میبینید که میانگین زمان پاسخ پس از اولین تماس (تماس اصلی قبل از ذخیره شدن در حافظه پنهان) به طور متوسط به 20 میلیثانیه برای مسیر photos/
کاهش یافته است. این بهبود بیش از 50 برابر است. Redis در زمان و قدرت پردازش بسیار صرفه جویی می کند.
مسیر /photos/id
را بهروزرسانی کنید تا از Redis نیز استفاده کنید:
$router->map('GET', '/photos/[i:id]', function (int $id) use ($client, $redis) {
if (!$redis->exists('photos:' . $id)) {
$response = $client->request('GET', 'https://jsonplaceholder.typicode.com/photos/' . $id);
$redis->setex(
'photos:' . $id,
REDIS_STANDARD_EXPIRY,
$response->getBody()->getContents()
);
}
header('Content-Type: application/json; charset=utf-8');
echo json_encode([
'data' => json_decode($redis->get('photos:' . $id))
]);
});
مسیر photos/id/
هم اکنون بسیار سریعتر است زیرا کمتر از 5 میلیثانیه طول میکشد تا پاسخ دریافت شود، بهبودی بیش از 45 برابر.
خلاصه
امیدوارم اکنون متوجه شده باشید که Redis چیست، اصول اولیه آن، و چگونه می توانید از آن برای افزایش سرعت برنامه های کاربردی وب PHP خود استفاده کنید.
در صورت داشتن هرگونه سوال یا مشاوره در قسمت نظرات می توانید بپرسید.
اگر می خواهید PHP را به صورت حرفه ای تر یادبگیرید می توانید از دوره آموزش مقدماتی تا پیشرفته PHP وب سایت آنوفل استفاده کنید.