Кэширование в JavaScript (Node.js): Redis и другие инструменты
Кэширование — один из самых эффективных способов повысить производительность веб-приложений на Node.js. Оно позволяет сократить время ответа, снизить нагрузку на базы данных и уменьшить затраты на инфраструктуру. В этой статье мы разберём основные инструменты кэширования в среде Node.js: Redis, Memcached и встроенное кэширование в памяти (in-memory cache). Вы узнаете, когда какой инструмент выбрать, и увидите рабочие примеры кода.
Зачем нужно кэширование в Node.js?
Node.js — однопоточный, но асинхронный. Каждый запрос к базе данных или внешнему API — это ожидание (I/O). Кэш позволяет сохранить результат дорогой операции (например, сложного SQL-запроса или парсинга HTML) и отдавать его мгновенно. Основные сценарии использования:
- Сохранение результатов запросов к БД (особенно агрегирующих)
- Кэширование ответов внешних API (погода, курсы валют)
- Хранение сессий пользователей
- Временное хранение вычисляемых данных (например, рендеринг шаблонов)
1. Redis — король кэширования
Redis — это in-memory data store, который часто используют как кэш. Он работает в отдельном процессе, поддерживает сложные структуры данных (строки, хэши, списки, множества) и имеет встроенные механизмы TTL (время жизни ключа).
Установка и подключение
Для работы потребуется установленный Redis сервер (локально или в Docker). В Node.js используем пакет redis:
npm install redis
Пример: кэширование данных с TTL
const redis = require('redis');
const client = redis.createClient();
client.on('error', (err) => console.error('Redis error:', err));
// Асинхронная функция получения данных с кэшем
async function getCachedData(key, fetchFunction, ttlSeconds = 60) {
// Пробуем получить из кэша
const cached = await client.get(key);
if (cached) {
return JSON.parse(cached);
}
// Если нет — вызываем дорогую функцию
const freshData = await fetchFunction();
// Сохраняем в кэш с TTL
await client.setEx(key, ttlSeconds, JSON.stringify(freshData));
return freshData;
}
// Использование: кэшируем результат запроса к БД
const users = await getCachedData('users:list', () => db.query('SELECT * FROM users'), 120);
Преимущества Redis
- Высокая производительность (миллионы операций в секунду)
- Поддержка TTL, pub/sub, транзакций
- Персистентность (можно сохранить на диск)
- Подходит для распределённых систем (несколько серверов Node.js)
Недостатки
- Требует отдельного сервера/контейнера
- Потребляет оперативную память
- Избыточен для простых однопоточных приложений
2. Memcached — лёгкий и быстрый
Memcached — ещё один популярный in-memory кэш, но проще Redis: только строки, нет персистентности, нет сложных структур. Идеален для простого кэширования данных.
Установка и пример
npm install memcached
const Memcached = require('memcached');
const memcached = new Memcached('localhost:11211');
async function getCachedData(key, fetchFunction, ttlSeconds = 60) {
return new Promise((resolve, reject) => {
memcached.get(key, async (err, data) => {
if (data) return resolve(JSON.parse(data));
const freshData = await fetchFunction();
memcached.set(key, JSON.stringify(freshData), ttlSeconds, (err) => {
if (err) reject(err);
resolve(freshData);
});
});
});
}
Когда использовать Memcached?
- Нужен только простой кэш ключ-значение
- Не требуется сохранение данных после перезапуска
- Ограничены ресурсы (Memcached легче Redis)
3. In-memory кэш (node-cache)
Для небольших приложений или микросервисов, где не хочется поднимать внешний сервис, можно использовать кэш прямо в процессе Node.js. Популярная библиотека — node-cache.
npm install node-cache
const NodeCache = require('node-cache');
const myCache = new NodeCache({ stdTTL: Также в библиотеке
Rate Limiting в TypeScript: библиотеки, стратегии и примеры
Dependency Injection контейнер для Go (Golang) — wire, dig, fx
Работа с YAML в TypeScript: полное руководство по парсингу и сериализации
Очереди задач в Node.js: Bull, Bee-Queue и Kue