Кэширование в TypeScript: Redis и другие инструменты
Кэширование — одна из ключевых стратегий оптимизации производительности веб-приложений. В экосистеме TypeScript и Node.js существует несколько мощных библиотек, позволяющих эффективно управлять кэшированием данных. В этой статье мы подробно разберём популярные инструменты, их применение и лучшие практики.
Зачем нужно кэширование?
Кэширование позволяет временно хранить часто запрашиваемые данные в быстром хранилище, чтобы не выполнять дорогостоящие операции (запросы к БД, вычисления, внешние API) каждый раз. Это снижает нагрузку на сервер и уменьшает время ответа.
Основные инструменты для кэширования в TypeScript
1. Redis через библиотеку ioredis
Redis — это высокопроизводительное in-memory хранилище данных, поддерживающее различные структуры данных. Для TypeScript лучшим выбором является ioredis — клиент с полной поддержкой типов и промисов.
import Redis from 'ioredis';
// Создаём клиент
const redis = new Redis({
host: 'localhost',
port: 6379,
});
// Функция для кэширования с TTL
async function cacheGet(key: string): Promise<string | null> {
const data = await redis.get(key);
return data;
}
async function cacheSet(key: string, value: string, ttl: number = 3600): Promise<void> {
await redis.setex(key, ttl, value);
}
// Пример использования
async function getUserData(userId: string) {
const cacheKey = `user:${userId}`;
const cached = await cacheGet(cacheKey);
if (cached) {
return JSON.parse(cached);
}
// Эмуляция дорогого запроса
const userData = { id: userId, name: 'John Doe' };
await cacheSet(cacheKey, JSON.stringify(userData), 3600);
return userData;
}
2. node-cache — in-memory кэш для небольших проектов
node-cache — простая in-memory библиотека, не требующая внешних зависимостей. Идеальна для прототипов и микросервисов с небольшим объёмом данных.
import NodeCache from 'node-cache';
const myCache = new NodeCache({ stdTTL: 600, checkperiod: 120 });
// Сохраняем данные
myCache.set('key', { data: 'value' });
// Получаем данные
const value = myCache.get('key');
if (value) {
console.log('Из кэша:', value);
} else {
console.log('Кэш пуст, запрашиваем данные...');
}
// Удаление по ключу
myCache.del('key');
// Очистка всего кэша
myCache.flushAll();
3. async-cache-dedupe — для предотвращения дублирующих запросов
Эта библиотека решает проблему "cache stampede" (когда множество запросов одновременно пытаются заполнить кэш). Она автоматически дедуплицирует параллельные запросы к одному и тому же ключу.
import { createCache } from 'async-cache-dedupe';
const cache = createCache({
ttl: 60, // время жизни в секундах
stale: 10, // время, когда данные считаются устаревшими, но ещё могут быть отданы
});
// Оборачиваем асинхронную функцию
const getData = cache.define('getData', async (id: number) => {
// Дорогой запрос
const result = await fetch(`https://api.example.com/data/${id}`);
return result.json();
});
// Используем
const result = await getData(42);
Стратегии инвалидации кэша
Одной из сложнейших задач в кэшировании является инвалидация — обновление устаревших данных. Рассмотрим основные подходы:
- TTL (Time-To-Live) — данные автоматически удаляются через заданное время. Простой и надёжный метод.
- Ленивая инвалидация — проверяем актуальность данных при каждом запросе (например, по версии).
- Event-driven инвалидация — при изменении данных в БД отправляем событие для очистки соответствующего кэша.
- Write-through — обновляем кэш одновременно с записью в основное хранилище.
Продвинутые паттерны с Redis
Кэширование с сериализацией и компрессией
import { compress, decompress } from 'lz-string';
import Redis from 'ioredis';
const redis = new Redis();
async function setCompressed(key: string, data: object, ttl: number) {
const json = JSON.stringify(data);
const compressed = compress(json);
await redis.setex(key, ttl, compressed);
}
async function getCompressed(key: string): Promise<object | null> {
const compressed = await redis.get(key);
if (!compressed) return null; Также в библиотеке
kotlinx-datetime для Kotlin: полное руководство с примерами
Обработка изображений в Node.js: библиотеки и инструменты
Библиотека cpp-httplib: OAuth 2.0 клиент на C++ для веб-приложений
Отправка email на Go (Golang): библиотеки и примеры кода