Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124


Коли ваш PHP-застосунок починає гальмувати під навантаженням, а запити до бази даних стають вузьким місцем, саме час познайомитися з Redis. Ця потужна система кешування здатна прискорити роботу вашого проєкту в десятки разів, зберігаючи дані безпосередньо в оперативній пам’яті.
У цій статті розповім, як інтегрувати Redis у PHP-застосунки, коли це дійсно потрібно, і покажу реальні приклади коду, які можна використовувати вже сьогодні.
Redis — це in-memory сховище типу key-value, яке працює блискавично швидко завдяки збереженню даних у RAM. На відміну від традиційних баз даних, Redis не шукає інформацію на жорсткому диску, а миттєво повертає її з оперативної пам’яті.
Основні сценарії використання Redis у PHP-проєктах включають кешування результатів запитів до бази даних, зберігання сесій користувачів, роботу з чергами завдань та реалізацію лічильників у реальному часі. Наприклад, якщо у вас є каталог товарів, де категорії змінюються рідко, немає сенсу щоразу діставати їх з MySQL — можна закешувати в Redis і оновлювати раз на годину.


Перед тим як писати код, потрібно встановити сам Redis-сервер і PHP-розширення для роботи з ним. Процес залежить від вашої операційної системи.
Для Ubuntu/Debian команда виглядає так:
sudo apt update
sudo apt install redis-server
sudo systemctl start redis
sudo systemctl enable redisДля macOS найзручніше використовувати Homebrew:
brew install redis
brew services start redisПеревірити, чи працює Redis, можна командою:
redis-cli pingЯкщо побачите відповідь “PONG”, значить все налаштовано правильно.
Існує два основних розширення: phpredis (написане на C, швидше) та Predis (чистий PHP, простіше у розгортанні). Рекомендую phpredis для продакшену через кращу продуктивність.
Встановлення phpredis через PECL:
sudo pecl install redis
echo "extension=redis.so" | sudo tee /etc/php/8.2/mods-available/redis.ini
sudo phpenmod redis
sudo systemctl restart php8.2-fpmCode language: PHP (php)Або через Composer, якщо віддаєте перевагу Predis:
composer require predis/predisCode language: JavaScript (javascript)Детальніше про встановлення та налаштування PHP-розширень можна прочитати в офіційній документації PHP.
Почнемо з найпростіших операцій: підключення, запису та читання даних. Ось базовий приклад роботи з phpredis:
<?php
// Підключення до Redis
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
// Перевірка з'єднання
if ($redis->ping()) {
echo "Підключено до Redis!\n";
}
// Збереження простого значення
$redis->set('user:1000:name', 'Олексій');
// Читання значення
$name = $redis->get('user:1000:name');
echo "Ім'я користувача: " . $name . "\n";
// Встановлення значення з часом життя (TTL) 60 секунд
$redis->setex('session:abc123', 60, 'session_data');
// Перевірка існування ключа
if ($redis->exists('user:1000:name')) {
echo "Ключ існує\n";
}
// Видалення ключа
$redis->del('user:1000:name');
?>Code language: PHP (php)Зверніть увагу на setex — це одна з найкорисніших команд для кешування. Вона автоматично видалить дані після закінчення часу, що ідеально підходить для тимчасових даних.
Redis підтримує не лише рядки, але й списки, множини, хеші та відсортовані множини. Розглянемо практичний приклад із хешами для зберігання даних користувача:
<?php
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
// Зберігання даних користувача як хеш
$redis->hMSet('user:2000', [
'name' => 'Марія',
'email' => 'maria@example.com',
'age' => 28,
'city' => 'Львів'
]);
// Отримання одного поля
$email = $redis->hGet('user:2000', 'email');
echo "Email: " . $email . "\n";
// Отримання всіх полів
$userData = $redis->hGetAll('user:2000');
print_r($userData);
// Збільшення лічильника
$redis->hIncrBy('user:2000', 'age', 1);
?>Code language: HTML, XML (xml)Хеші чудово підходять для зберігання об’єктів, бо дозволяють оновлювати окремі поля без необхідності перезаписувати всю структуру.
Найпопулярніший сценарій — це кешування результатів запитів до MySQL або PostgreSQL. Ось реальний приклад з перевіркою кешу:
<?php
class ProductRepository {
private $redis;
private $pdo;
public function __construct($redis, $pdo) {
$this->redis = $redis;
$this->pdo = $pdo;
}
public function getProductById($id) {
$cacheKey = "product:{$id}";
// Спробувати отримати з кешу
$cached = $this->redis->get($cacheKey);
if ($cached !== false) {
echo "Дані з кешу\n";
return json_decode($cached, true);
}
// Якщо в кеші немає — запитуємо базу
echo "Дані з бази даних\n";
$stmt = $this->pdo->prepare("SELECT * FROM products WHERE id = ?");
$stmt->execute([$id]);
$product = $stmt->fetch(PDO::FETCH_ASSOC);
// Зберігаємо в кеш на 1 годину
if ($product) {
$this->redis->setex($cacheKey, 3600, json_encode($product));
}
return $product;
}
public function invalidateProduct($id) {
// Видалити з кешу при оновленні товару
$this->redis->del("product:{$id}");
}
}
?>Code language: HTML, XML (xml)Цей підхід дає величезний виграш у швидкості — перший запит іде в базу, а всі наступні за годину повертаються з Redis майже миттєво. Критично важливо не забувати про інвалідацію кешу — коли товар оновлюється, треба видалити старі дані з Redis.
Стандартне файлове зберігання сесій у PHP працює повільно на високонавантажених проєктах. Redis вирішує цю проблему елегантно. Є два способи: через налаштування php.ini або програмно.
Спосіб через php.ini (простіший):
session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379?database=1"Code language: JavaScript (javascript)Програмний спосіб з більшим контролем:
<?php
ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://127.0.0.1:6379?database=1');
session_start();
$_SESSION['user_id'] = 1000;
$_SESSION['username'] = 'developer';
// Сесії тепер зберігаються в Redis
echo "Сесія ID: " . session_id();
?>Code language: HTML, XML (xml)Особливо це корисно для розподілених систем — коли у вас кілька серверів із PHP, вони можуть спільно використовувати один Redis для сесій. Користувач може потрапити на будь-який сервер, і його сесія буде доступна.


Черги завдань — ще один сильний бік Redis. Можна використовувати структури списків (LPUSH/RPOP) для створення простої черги:
<?php
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
// Додавання завдання в чергу
$task = json_encode([
'type' => 'send_email',
'to' => 'user@example.com',
'subject' => 'Привіт!',
'body' => 'Текст листа'
]);
$redis->lPush('email_queue', $task);
echo "Завдання додано в чергу\n";
// Обробка завдання (у воркері)
$task = $redis->brPop(['email_queue'], 5); // Блокуюче читання з таймаутом 5с
if ($task) {
$taskData = json_decode($task[1], true);
echo "Обробляю: " . $taskData['type'] . "\n";
// Тут логіка відправки листа
}
?>Code language: HTML, XML (xml)Команда brPop блокує виконання скрипта, поки не з’явиться завдання або не спрацює таймаут. Це ідеально для фонових воркерів, які постійно чекають нові завдання.
Сучасні фреймворки мають вбудовану підтримку Redis, що спрощує роботу. Розглянемо приклади для Laravel та Symfony.
У Laravel кешування через Redis вмикається в .env файлі:
CACHE_DRIVER=redis
SESSION_DRIVER=redis
QUEUE_CONNECTION=redisПриклад використання в коді:
<?php
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Redis;
// Кешування з фасаду Cache
$users = Cache::remember('users.all', 3600, function () {
return DB::table('users')->get();
});
// Пряма робота з Redis
Redis::set('visits:homepage', 0);
Redis::incr('visits:homepage');
$visits = Redis::get('visits:homepage');
?>Code language: HTML, XML (xml)У Symfony потрібно встановити компонент:
composer require symfony/cache
composer require predis/predisCode language: JavaScript (javascript)Конфігурація в config/packages/cache.yaml:
framework:
cache:
app: cache.adapter.redis
default_redis_provider: redis://localhostCode language: JavaScript (javascript)Використання в контролері:
<?php
use Symfony\Contracts\Cache\CacheInterface;
class ProductController {
public function show(CacheInterface $cache, int $id) {
$product = $cache->get("product_{$id}", function () use ($id) {
return $this->productRepository->find($id);
});
return $this->json($product);
}
}
?>Code language: HTML, XML (xml)Як і будь-яка технологія, Redis має свої сильні та слабкі сторони. Важливо розуміти їх перед впровадженням у проєкт.
За кілька років роботи з Redis накопичилося чимало корисних практик, якими хочу поділитися.
Правильне іменування ключів: використовуйте структуровані імена з двокрапками, наприклад user:1000:profile замість userprofile1000. Це спрощує пошук та управління ключами.
Завжди встановлюйте TTL: навіть якщо дані потрібні “назавжди”, встановіть великий TTL (наприклад, тиждень). Це захистить від забитої пам’яті застарілими ключами.
Використовуйте pipeline для масових операцій: замість десятків окремих SET-команд, відправте їх одним пайплайном. Це радикально зменшує мережеві затримки.
<?php
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
// Неефективно
for ($i = 0; $i < 1000; $i++) {
$redis->set("key:$i", "value:$i");
}
// Ефективно з pipeline
$redis->multi(Redis::PIPELINE);
for ($i = 0; $i < 1000; $i++) {
$redis->set("key:$i", "value:$i");
}
$redis->exec();
?>Code language: HTML, XML (xml)Моніторинг і алерти: налаштуйте моніторинг використання пам’яті Redis через команду INFO. Коли заповнення досягає 80%, час збільшувати ресурси або чистити застарілі дані.
Обробка помилок: Redis може бути недоступний. Завжди додавайте try-catch блоки та логіку fallback до основної бази даних.
<?php
try {
$redis = new Redis();
$redis->connect('127.0.0.1', 6379, 2); // таймаут 2 секунди
$data = $redis->get('important_data');
} catch (RedisException $e) {
// Fallback на базу даних
error_log("Redis недоступний: " . $e->getMessage());
$data = $database->query("SELECT * FROM cache WHERE key='important_data'");
}
?>Code language: HTML, XML (xml)Redis — чудовий інструмент, але не універсальне рішення. Є сценарії, де його використання недоцільне або навіть шкідливе.
Якщо ваш застосунок має низьке навантаження (менше 100 запитів на хвилину), то складність підтримки Redis може перевищити вигоду від прискорення. Простіше використати вбудований кеш файлової системи PHP або APCu.
Для зберігання великих об’єктів (понад 1 МБ) Redis не підходить — це забиває пам’ять і сповільнює інші операції. Краще використати файлове сховище або об’єктне S3-сумісне рішення.
Якщо у вас немає досвіду в налаштуванні та моніторингу серверів, краще почати з керованих сервісів типу AWS ElastiCache або Redis Cloud, щоб не зіткнутися з проблемами втрати даних.
Більше про вибір правильних інструментів для PHP-розробки можна дізнатися в нашому матеріалі про кращі IDE для PHP.