Использование Redis со сложными запросами

У меня есть серверная служба node js, которая в настоящее время извлекает данные непосредственно из базы данных postgres, и я работаю над внедрением среднего уровня кэширования.

Я впервые использую Redis, и я столкнулся с некоторыми проблемами, связанными с тем, как эффективно использовать его для своих сложных запросов. Меня здесь смущает две вещи: как сопоставить запрос с ключом в кеше Redis. Как следует обновлять кеш Redis после вызова функций обновления/создания.

У меня есть, например. следующая функция для объединения нескольких таблиц (здесь для краткости показаны только две)

async findAll(query: PaginateQuery, user: User): Promise<Paginated<any>> {

    const limit = query.limit && query.limit < MAX_LIMIT ? query.limit : MAX_LIMIT
    const page = query.page ?? DEFAULT_PAGE
    const skip = (page - 1) * limit
    const queryBuilder = getConnection().getRepository(tableEntryX).createQueryBuilder('tableX').leftJoin('tableX.fk1', 'fk1').addSelect(['fk1.id', 'fk1.gender']).leftJoin('tableX.fk2', 'fk2').addSelect(['fk2.id', 'fk2.weigth'])
    if (query.filter?.createdAt) {
       
      ///  udpate query based on this filter
    }
    
   // filter 2
       
   // filter 3

 

// fetch
         const [data, count] = await     Promise.all([queryBuilder.skip(skip).take(limit).getMany(), queryBuilderCount.getCount()])
      const res = EMPTY_PAGINATED_DATA
      res.data = data
      res.meta.itemsPerPage = limit
      res.meta.currentPage = page
      res.meta.totalItems = count
      res.meta.totalPages = Math.ceil(count / limit)
      res.meta.sortBy = sorting
      return res
 }

Одна и та же функция проверяет наличие нескольких фильтров, и на основе этих фильтров мы изменяем запрос с помощью функций и/илиWhere.

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

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

Однако я считаю, что более острая проблема с этим подходом — это когда происходит обновление/новая запись. Вот что нам делать со всеми нашими кэшами. Кажется пустой тратой просто удалять все кеши и начинать с нуля. Особенно, если учесть, что обновление/создание записей происходит довольно регулярно.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
78
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Любой кеш — это всегда компромисс. Таким образом, правильный ответ будет зависеть от многих факторов (сколько чтений, сколько записей, сколько параметров, какие индексы и т. д.; вы поняли). Рассмотрим пару самых простых подходов.

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

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

Моя личная рекомендация — проанализировать ваши данные и запрос. Возможно, вам не понадобится сложное решение для кэширования, а кэширование запроса с параметрами по умолчанию может сэкономить 95 % ресурсов.

Другие вопросы по теме

Похожие вопросы

Рабочие функции не найдены. Попробуйте сделать свои классы и методы заданий общедоступными (NODEJS v4)
Сторонние файлы cookie будут заблокированы – предупреждение, невозможно выйти из системы
Приложению RAG не удается использовать DataAPIClient: «Ошибка загрузки клиента fetch-h2 для DataAPIClient... попробуйте установить для httpOptions.client значение «fetch»»
Aws Redis Connection не проходит аутентификацию через NodeJS
Flash-сообщение не отображается после выхода из системы
Использование переменных окружения действий github для запуска различных базовых URL-адресов в функции и промежуточной стадии для теста Snowflake Cypress
Порядок импорта конфигурации puppeteer вызывает ошибку
Как дождаться, пока все сжатые файлы будут извлечены
Ошибка Angular 18 и SignalR при создании приложения: [ОШИБКА] Не удалось разрешить «url», «https», «http», «util» из источника событий
Невозможно найти модуль index.js в Google Cloud VM Docker