Junior: питання на співбесіді з теми «Кешування»
Питання з реальних співбесід з відповідями: Laravel і PHP, бази даних, JavaScript і фронтенд, Git, Docker, API, безпека й архітектура. Тими самими темами, що й тести.
2 питання
Драйвер задається в config/cache.php і змінною CACHE_STORE. Вибір визначає не швидкість, а те, чи бачать процеси спільний кеш.
array - у памʼяті одного процесу, зникає після запиту. Стандартний драйвер для тестів: кеш не тягнеться між тестами й нічого не треба чистити.
file - файли в storage/framework/cache. Працює без жодного налаштування, тому зручний локально. На кількох серверах кожен матиме свій кеш, а очищення тегів файловий драйвер не підтримує.
database - таблиця в базі. Спільний для всіх серверів, але кожне читання - це запит до тієї самої бази, яку кеш і мав розвантажити.
redis / memcached - окремий сервер у памʼяті. Спільний для всіх процесів, витримує теги й атомарні блокування. Це стандартний вибір для проду.
Практичне правило: локально file, у тестах array, у проді redis.
Що важливо пам'ятати про різницю. Код, написаний під Redis, може мовчки не працювати на file:
Cache::tags(['posts'])->put('list', $posts, 600); // file-драйвер кине виняток
Блокування (Cache::lock()) файловий драйвер підтримує, але блокування живе на диску одного сервера - на кількох вузлах воно вже нічого не гарантує.
Тому середовища краще тримати на однаковому драйвері - інакше помилка знайдеться вже в проді.
Cache::remember() повертає значення з кешу, а якщо його немає - виконує замикання, зберігає результат і повертає.
$categories = Cache::remember('categories:menu', now()->addHour(), function () {
return Category::query()->orderBy('position')->get(['id', 'name', 'slug']);
});
Перший запит за годину піде в базу, решта отримають готовий результат.
Ключ:
- має містити все, від чого залежить результат:
posts:page:3,user:42:stats,products:locale:uk. Забули мову в ключі - українці побачать англійське меню; - з префіксом за сутністю - щоб було зрозуміло, що це, і легко скинути.
Час життя (TTL):
- скільки часу застарілі дані прийнятні для користувача: курс валют - хвилини, меню категорій - години;
rememberForever()- лише коли кеш гарантовано скидають при змінах, інакше застарілі дані житимуть вічно.
Чого уникати:
- кешувати те, що й так швидке: простий запит за первинним ключем часто швидший за звернення до Redis з десеріалізацією;
- кешувати дані конкретного користувача під спільним ключем - це витік чужих даних.