Кэширование в TypeScript: Redis, Memcached и встроенные решения от А до Я

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Кэширование в 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. Сравнение и выбор стратегии

КритерийВстроенное

Блоги

Рекомендаций по книгам