Кэширование в TypeScript: Redis, Memcached и встроенные решения: от А до Я
Кэширование — один из ключевых инструментов для повышения производительности веб-приложений и сервисов. В экосистеме TypeScript и Node.js разработчики могут выбирать между мощными внешними системами (Redis, Memcached) и легковесными встроенными решениями. В этой статье мы разберём все три подхода, приведём практические примеры кода на TypeScript и поможем выбрать оптимальную стратегию для вашего проекта.
Зачем нужно кэширование в TypeScript?
Кэширование позволяет сократить время ответа сервера, снизить нагрузку на базы данных и внешние API, а также уменьшить задержки при повторных запросах. В TypeScript, работающем поверх Node.js, кэш особенно полезен для:
- хранения результатов дорогих вычислений;
- кэширования ответов от внешних API;
- сохранения сессий пользователей;
- уменьшения количества запросов к базе данных.
1. Встроенные решения для кэширования в TypeScript
Для небольших проектов или прототипов можно использовать встроенные средства Node.js без установки дополнительных пакетов.
1.1. Использование Map
Самый простой способ — объект Map или простой объект. Однако такой кэш живёт только в памяти одного процесса и теряется при перезапуске.
// Простой кэш на основе Map
class SimpleCache<T> {
private cache = new Map<string, T>();
get(key: string): T | undefined {
return this.cache.get(key);
}
set(key: string, value: T): void {
this.cache.set(key, value);
}
clear(): void {
this.cache.clear();
}
}
// Пример использования
const cache = new SimpleCache<string>();
cache.set('user:1', 'Alice');
console.log(cache.get('user:1')); // Alice
1.2. Кэш с TTL (Time-To-Live)
Более продвинутая версия — кэш с автоматическим удалением записей через заданное время.
// Кэш с TTL
class TtlCache<T> {
private cache = new Map<string, { value: T; expiry: number }>();
get(key: string): T | undefined {
const item = this.cache.get(key);
if (!item) return undefined;
if (Date.now() > item.expiry) {
this.cache.delete(key);
return undefined;
}
return item.value;
}
set(key: string, value: T, ttlMs: number): void {
this.cache.set(key, {
value,
expiry: Date.now() + ttlMs,
});
}
}
// Пример
const ttlCache = new TtlCache<number>();
ttlCache.set('price', 100, 5000); // живёт 5 секунд
setTimeout(() => console.log(ttlCache.get('price')), 6000); // undefined
2. Кэширование с Redis в TypeScript
Redis — это популярное in-memory хранилище данных, которое поддерживает продвинутые структуры данных, pub/sub и персистентность. Для TypeScript используется пакет ioredis.
2.1. Установка и подключение
npm install ioredis
npm install @types/ioredis --save-dev
import Redis from 'ioredis';
const redis = new Redis({
host: 'localhost',
port: 6379,
});
redis.on('connect', () => console.log('Connected to Redis'));
redis.on('error', (err) => console.error('Redis error', err));
2.2. Базовые операции set/get
// Сохраняем значение
await redis.set('user:1:name', 'Alice');
// Получаем значение
const name = await redis.get('user:1:name');
console.log(name); // Alice
// Устанавливаем TTL (в секундах)
await redis.setex('session:123', 3600, 'active');
2.3. Работа с объектами (JSON)
// Сохраняем объект
const user = { id: 1, name: 'Alice', email: 'alice@example.com' };
await redis.set('user:1', JSON.stringify(user));
// Читаем и парсим
const raw = await redis.get('user:1');
if (raw) {
const parsedUser = JSON.parse(raw);
console.log(parsedUser.name); // Alice
}
2.4. Инвалидация кэша
// Удаление одного ключа
await redis.del('user:1');
// Удаление по шаблону (требуется осторожность)
const keys = await redis.keys('user:*');
if (keys.length > 0) {
await redis.del(...keys);
}
3. Кэширование с Memcached в TypeScript
Memcached — ещё одна популярная система кэширования, проще Redis, но с меньшим набором функций. Для TypeScript используется пакет memcached.
3.1. Установка и подключение
npm install memcached
npm install @types/memcached --save-dev
import Memcached from 'memcached';
const memcached = new Memcached('localhost:11211');
memcached.on('issue', (details) => {
console.error('Memcached issue', details);
});
3.2. Базовые операции
// Запись с TTL (в секундах)
memcached.set('user:1', { name: 'Bob' }, 3600, (err) => {
if (err) console.error(err);
});
// Чтение
memcached.get('user:1', (err, data) => {
if (err) console.error(err);
console.log(data); // { name: 'Bob' }
});
// Удаление
memcached.del('user:1', (err) => {
if (err) console.error(err);
});
3.3. Промисная обёртка для удобства
import { promisify } from 'util';
const getAsync = promisify(memcached.get).bind(memcached);
const setAsync = promisify(memcached.set).bind(memcached);
async function cacheExample() {
await setAsync('product:1', { title: 'Laptop', price: 1000 }, 600);
const product = await getAsync('product:1');
console.log(product);
}
4. Сравнение и выбор стратегии
| Критерий | Встроенное
БлогиРекомендаций по книгамЧитайте также |
|---|