Как кэшировать приложения Node.JS с помощью Redis

    Команда Simple-Server
    03.06.2026
    12 мин

    Материал подготовлен командой Simple-Server для администраторов VPS и выделенных серверов. Команды и пути проверяйте на тестовой машине перед production.

    Кратко о задаче

    Redis (remote dictionary server, удаленный сервер словарей) — это резидентная база данных (in-memory database/store) с открытым исходным кодом (open source), которая работает с простыми структурами «ключ — значение».

    Это лишь вопрос терминологии — называть Redis базой данных, инструментом кэширования или как-то еще. Главное, что Redis размещает данные не на жестком диске, а в оперативной памяти — отсюда и более высокая производительность. Собственно, именно поэтому база и называется «резидентной».

    Несмотря на то, что данные находятся в оперативной памяти, периодически они сохраняются на жесткий диск в виде снимков.

    Установка Redis под разные операционные системы отличается — на официальном сайте можно найти подробную инструкцию под каждую из них.

    В этой статье рассматривается вариант с использованием Ubuntu или Debian. Поэтому, последнюю версию Redis мы возьмем из официального APT (Advanced Packaging Tool) репозитория — packages.redis.io:

    sudo apt update sudo apt install redis

    После этого сервер Redis готов к работе. На локальной машине им можно управлять с помощью команд, которые будут рассмотрены ниже — запускать, останавливать, добавлять и удалять ключи.

    Для Windows необходимо загрузить установщик с официального репозитория GitHub. После установки сервер Redis запускается с помощью CLI-команды:

    Если же вы используете macOS, то установить Redis можно с помощью пакетного менеджера Homebrew:

    После установки сервер запускается так:

    Конфигурация проекта Node.js

    Прежде чем начать разбираться в принципах взаимодействия с Redis через Node-приложение, давайте сперва создадим отдельный рабочий каталог и перейдем в него:

    mkdir node_redis cd node_redis

    Как и всегда, создадим конфигурационный файл package.json с минимальным набором данных:

    { "name": "node_redis", "version": "1.0.0", "description": "Simple example of using Redis by Simple-Server", "main": "index.js", "license": "MIT", "dependencies": { "express": "latest", "axios": "latest", "redis": "latest" } }

    Обратите внимание на указанные зависимости. Для проекта нам потребуются последние версии популярного сетевого фреймворка Express и официального клиента клиент Redis на NPM — это отдельная библиотека Node.js, содержащая высокоуровневое API (классы и функции) для взаимодействия с сервером Redis.

    Модуль Axios поможет парсить JSON-данных, которые будет возвращать удаленный сервер в ответ на API-запросы.

    Для установки зависимостей нам потребуется пакетный менеджер NPM. Если на вашей машине он отсутствует, установить его можно с помощью команды:

    О том, как установить последнюю версию Node.js в операционной системе Ubuntu, вы можете прочитать в отдельной инструкции. Так как в коде нашего приложения будет использоваться async/await-синтаксис, минимальная версия Node.js — 8.

    Теперь, когда все зависимости указаны, их можно установить:

    Приложение на Express без кэширования

    В этом примере приложение будет использовать фейковое API сервиса JSONPlaceholder — он был создан как раз для этих целей. Мы будем отправлять запрос по адресу https://jsonplaceholder.typicode.com/posts/1, получая в ответе импровизированные данные в JSON-формате:

    { "userId": 1, "id": 1, "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto" }

    Соответственно, последующая загрузка данных из кеша (вместо выполнения повторных запросов к удаленному серверу) увеличит скорость работы приложения.

    Однако сперва мы реализуем сам процесс обработки пользовательских запросов без использования кэша — его мы добавим позднее.

    Давайте сначала создадим наш index.js-файл и отредактируем его. В скрипте по возможности будет использоваться современный синтаксис JS (ES6) с применением операторов async/await:

    Теперь можно запустить данный скрипт, открыть localhost в браузере и увидеть на веб-странице вывод полученных JSON-данных:

    Каждый запрос к локальному серверу будет в свою очередь вызывать запрос к удаленному серверу. Например, если вы 3 раза обновите страницу в браузере, то в терминале приложения Node.js (запущенный сервер) 3 раза выводится указанное в коде сообщение « There was a request to a remote server ».

    Однако зачем? С рациональной точки зрения в этом нет необходимости.

    Данные, полученные в первый раз, имеет смысл закешировать, чтобы сократить количество операций и время ожидания пользователя. Это актуально только в том случае, если предполагается статичность получаемых данных некоторый промежуток времени — то есть кэшировать можно только те данные, которые меняются относительно нечасто.

    Приложение на Express с использованием кэша

    Давайте модифицируем ранее написанный пример, чтобы наше приложение «научилось» кэшировать данные.

    Для этого сначала подключим клиент Redis — добавим новую строку в начало index.js:

    ... const redis = require("redis"); ...

    Теперь закономерно нам необходимо подключиться к ранее запущенному серверу Redis, после чего мы сможем устанавливать и получать ключи. Добавим еще несколько строк кода:

    ... (async () => { client = redis.createClient(); client.on("error", (error) => console.log('Что-то пошло не так', error)); // вешаем хук на ошибку подключения к серверу Redis await client.connect(); // подключаемся к серверу })(); ...

    Обратите внимание, что подключение к серверу Redis происходит в безымяной самовызывающейся асинхронной функции. Это нужно для последовательного выполнения всех предварительных конфигураций нашего приложения. К тому же, функция connect возвращает обещание (promise), которое обрабатывается либо с помощью операторов then/catch, либо внутри асинхронной функции.

    В нашем примере логика работы с кэшем будет следующая: если API-запрос к удаленному серверу происходит первый раз, то полученные данные мы кэшируем. Если нет, то данные уже были получены ранее, а значит они есть в кэше — достаем их и отправляем пользователю.

    Давайте модифицируем функцию (middleware) обработки запросов onRequest:

    ... async function onRequest(req, res) { let results; // заранее объявляем переменную для результата const cacheData = await client.get(“post”); // пытаемся получить переменную post из базы данных Redis if(cacheData) { results = JSON.parse(cacheData); // парсим данные из формата сырой строки в формат структуры } else { results = await getRemoteData(); // вызываем функцию получения данных с удаленного сервера if(results.length === 0) throw "API error"; // обрабатываем пустой результат ошибкой await client.set(“post”, JSON.stringify(results)); // кэшируем полученные данные } res.send(results); // отвечаем на запрос JSON-данными }

    Обратите внимание, что функция get возвращает null в том случае, если по данному ключу в Redis нет никаких сохраненных значений. Соответственно, если это так, то выполняется API-запрос к удаленному серверу. А если нет — пользователю отправляются данные из кеша.

    При этом функция set непосредственно отвечает за кэширование — она устанавливает указанное значение по названию ключа таким образом, что впоследствии его можно получить через get.

    Полный код приложения на данном этапе выглядит так:

    Установка срока действия кэша

    Данные, записанные в кэш, должны периодически обновляться, чтобы не устаревать.

    API реальных проектов часто сообщают дополнительную информацию о том, с какой частотой необходимо обновлять кэшированные данные. Эта информация используется для установки своего рода таймаута — срока, в течение которого данные в кэше действительны. По прошествии этого времени приложение выполняет повторный запрос, получая свежие обновления.

    В нашем случае мы пойдем по более простому пути, который тоже встречается на практике. Мы установим константный срок действия кэша — 60 секунд. По прошествии этого времени мы будем делать повторный запрос к удаленному серверу за свежими данными.

    Важно, что функция срока действия кэша выполняется на стороне Redis. Это возможно с помощью указания дополнительных параметров при использовании функции set.

    Для этого модифицируем вызов этой функции с помощью дополнительной структуры в качестве третьего аргумента. Таким образом строка кода:

    ... await client.set(“post”, JSON.stringify(results)); // кэшируем полученные данные ...

    преобразуется в следующий вид:

    ... await client.set(“post”, JSON.stringify(results), { EX: 60, NX: true }); // кэшируем полученные данные ...

    В данном случае мы обновили ранее написанную строчку кода, установив параметр EX — срок истечения кэша в секундах. NX при этом гарантирует, что ключ установится только в том случае, если его еще нет в базе данных Redis. Последний параметр действительно важен, ведь в противном случае повторная установка ключа будет приводить к обновлению таймаута кеша, не позволяя ему полностью истечь.

    Теперь значение ключа post будет храниться в базе данных 60 секунд — далее оно стирается. Это значит, что в коде нашего приложения переменная cacheData будет получать значение null каждую минуту — это приведет к API-запросу к удаленному серверу и повторному кэшированию полученного результата.


    Нужен сервер для практики? Арендуйте VPS/VDS в России — root-доступ, NVMe, DDoS-защита и поддержка 24/7.

    VPS для проекта

    VPS с root-доступом, NVMe и поддержкой 24/7 на Simple-Server.

    StarterVDS

    490

    в месяц

    1 ядро

    1 ГБ RAM

    20 ГБ NVMe

    • 1 IPv4
    • KVM
    • Root-доступ
    • Безлимитный трафик
    Заказать VPS
    Рекомендуем

    PerformanceVDS

    1190

    в месяц

    2 ядра

    4 ГБ RAM

    60 ГБ NVMe

    • 1 IPv4
    • KVM
    • Root-доступ
    • Базовая DDoS-защита
    Заказать VPS

    Нужна другая конфигурация или чистый VPS без панели?

    Все тарифы VPS

    Похожие статьи, которые могут быть вам интересны