Moleculer имеет встроенное решение для кэширования результатов вызова методов сервисов. Чтобы включить его, укажите тип кэша cacher
в параметрах брокера и включите кэш cache: true
в определении метода результаты выполнения которого необходимо кэшировать.
Пример
const { ServiceBroker } = require("moleculer"); |
Сообщения консоли:
[2017-08-18T13:04:33.845Z] INFO dev-pc/BROKER: Broker started. |
Как видите, сообщение Handler called
появляется только один раз, потому что ответ второго запроса был возвращён из кэша.
Ключи кэширования
Ключ кэширования генерируется из имени сервиса, имени метода и параметров контекста. Синтаксис ключа:
<serviceName>.<actionName>:<parameters or hash of parameters> |
Если вызвать метод posts.list
с параметрами { limit: 5, offset: 20 }
, алгоритм кэширования вычислит хэш от параметров. Таким образом, при следующем вызове с такими же параметрами, результат будет найдет кэше по ключу.
Пример хэш-ключа кэша для действия “posts.find”
posts.find:limit|5|offset|20 |
Объект params может содержать свойства, которые не имеют отношения к ключу кэша. Также, это может вызвать проблемы с производительностью, если ключ слишком длинный. Поэтому рекомендуется задать объект cache
со списком основных имён параметров в свойстве keys
. Для указания ключей кэша из объекта мета в свойстве keys
используйте префикс #
.
Для генерации ключа кэша используются свойства только объектов params
и meta
{ |
Performance tipЭто решение работает довольно быстро, поэтому мы рекомендуем использовать его на продакшене.
Ограничение длины ключа кэша
Иногда ключ может быть очень длинным, что может вызвать проблемы с производительностью. Чтобы избежать этого, можно задать параметр кеширования maxParamsLength
. Когда длина ключа превысит указанное значение, алгоритм вычисляет хэш (SHA256) от полного ключа и добавляет его в конец ключа.
Минимум для
maxParamsLength
составляет44
(SHA 256 хэш в Base64).Для отключения этой функции установите значение
0
илиnull
.
Формирование полного ключ из всех параметров без ограничения
cacher.getCacheKey("posts.find", { id: 2, title: "New post", content: "It can be very very looooooooooooooooooong content. So this key will also be too long" }); |
Формирование ключа ограниченной длины
const broker = new ServiceBroker({ |
Условное кэширование
Условное кэширование позволяет обойти кэш и выполнить действие для получения “свежих” данных. Чтобы обойти кэш необходимо присвоить ctx.meta.$cache
false
перед вызовом действия.
Пример отключения кэширования для действия greeter.hello
broker.call("greeter.hello", { name: "Moleculer" }, { meta: { $cache: false }})) |
В качестве альтернативы, можно использовать пользовательскую функцию, чтобы активировать обход кэша. Пользовательская функция принимает в качестве аргумента контекст (ctx
), поэтому она имеет доступ к любым параметрам или мета-данным. Это позволяет передать флаг обхода внутри запроса.
Пример пользовательской функции условного кэширования
// greeter.service.js |
TTL время жизни
Настройки TTL по умолчанию могут быть переопределены в определении действия.
const broker = new ServiceBroker({ |
Пользовательский формирователь ключа
Чтобы переопределить встроенный формирователь ключей кэширования, установите собственную функцию keygen
в параметрах кэширования.
const broker = new ServiceBroker({ |
Ручное кэширование
Модуль кэширования может использоваться вручную. Просто вызовите методы get
, set
, del
в broker.cacher
.
// сохранить в кэш |
Кроме того, при использовании встроенного Redis кэша можно использовать любой метод API ioredis в broker.cacher.client
:
// создать конвейер ioredis |
Очистка кэша
Когда вы создаете новую модель в своём сервисе, вам необходимо очистить старые записи в кэше.
Пример очистки кэша внутри действий
{ |
Очистка кэша для нескольких экземпляров сервиса
Наилучшая практика очистки кэша среди нескольких экземпляров сервиса заключается в использовании широковещательных событий. Note this is only required for non-centralized cachers like Memory
or MemoryLRU
.
Пример
module.exports = { |
Очистка кэша между различными сервисами
Зависимость сервисов - обычная ситуация. Например сервис posts
хранит информацию из сервиса users
в кэшированных записях (в случае заполнения).
Пример записи кэша в сервисе posts
{ |
Поле author
получено из сервиса users
. Если сервис users
очищает записи кэша, то служба posts
также должна очистить собственные записи кэша. Поэтому вы должны также подписаться на событие cache.clear.users
в сервисе posts
.
Чтобы упростить это, создайте примесь CacheCleaner
и определите схему зависимости сервисов.
cache.cleaner.mixin.js
module.exports = function(serviceNames) { |
posts.service.js
const CacheCleaner = require("./cache.cleaner.mixin"); |
При этом, если сервис users
вызывает событие cache.clean.users
, то сервис posts
также очистит свои собственные записи кэша.
Блокировка кэша
Moleculer также поддерживает функцию блокировки кэша. Для получения подробной информации ознакомьтесь с PR.
Включение блокировки
const broker = new ServiceBroker({ |
Включение с TTL
const broker = new ServiceBroker({ |
Отключение блокировки
const broker = new ServiceBroker({ |
Пример кэша Redis с использованием библиотеки redlock
const broker = new ServiceBroker({ |
Встроенные типы кэша
Memory cacher
MemoryCacher
это встроенный модуль кэширования. Он сохраняет записи в памяти кучи.
Включение
const broker = new ServiceBroker({ |
Или
const broker = new ServiceBroker({ |
Включить с параметрами
const broker = new ServiceBroker({ |
Параметры
Имя | Тип | По умолчанию | Описание |
---|---|---|---|
ttl |
Number |
null |
Время жизни в секундах. |
clone |
Boolean или Function |
false |
Клонировать кэшированные данные при возврате. |
keygen |
Function |
null |
Функция формирования ключей кэша. |
maxParamsLength |
Number |
null |
Максимальная длина параметров в сформированных ключах. |
lock |
Boolean или Object |
null |
Включить функцию блокировки. |
Клонирование
Кэшер использует метод клонирования _.cloneDeep
из библиотеки lodash. Чтобы его изменить, передайте Function
в свойство clone
вместо Boolean
.
Пользовательская функция клонирования через JSON сериализацию
const broker = new ServiceBroker({ |
Кэш памяти LRU
Кэш памяти LRU
- это встроенный кэш LRU модуль. Он удаляет наименее используемые элементы.
Включение LRU кэша
const broker = new ServiceBroker({ |
С параметрами
let broker = new ServiceBroker({ |
Параметры
Имя | Тип | По умолчанию | Описание |
---|---|---|---|
ttl |
Number |
null |
Время жизни в секундах. |
max |
Number |
null |
Максимальное количестов элементов в кэше. |
clone |
Boolean или Function |
false |
Клонировать кэшированные данные при возврате. |
keygen |
Function |
null |
Пользовательская функция генерации ключей кэша. |
maxParamsLength |
Number |
null |
Максимальная длина параметров сгенерированных ключей. |
lock |
Boolean или Object |
null |
Включить функцию блокировки. |
DependenciesЧтобы использовать этот тип кэша, необходимо установить модуль
lru-cache
командойnpm install lru-cache --save
.
Кэш Redis
RedisCacher
является встроенным распределенным модулем кэша на базе Redis. Он использует библиотеку ioredis
. Используйте его, если имеется несколько экземпляров сервисов, потому что если в одном экземпляре хранятся некоторые данные в кэше, другие экземпляры смогут найти их.
Включение Redis кэша
const broker = new ServiceBroker({ |
С указанием строки подключения
const broker = new ServiceBroker({ |
С параметрами
const broker = new ServiceBroker({ |
С использованием сериализатора MessagePack Вы можете определить сериализатор для кэша Redis. По умолчанию используется сериализатор JSON.
const broker = new ServiceBroker({ |
С использованием клиента для Redis кластера
const broker = new ServiceBroker({ |
Параметры
Имя | Тип | По умолчанию | Описание |
---|---|---|---|
prefix |
String |
null |
Префикс для сгенерированных ключей. |
ttl |
Number |
null |
Время жизни в секундах. Отключить: 0 или null |
monitor |
Boolean |
false |
Включить функцию мониторинга клиента Redis. Если включено, каждая операция клиента будет записана в лог (на уровне отладки) |
redis |
Object |
null |
Пользовательские параметры Redis. Будут переданы в конструктор new Redis() . Подробнее. |
keygen |
Function |
null |
Пользовательская функция генерации ключей кэша. |
maxParamsLength |
Number |
null |
Максимальная длина параметров сгенерированных ключей. |
serializer |
String |
"JSON" |
Имя встроенного сериализатора. |
cluster |
Object |
null |
Конфигурация кластера Redis. Подробнее |
lock |
Boolean или Object |
null |
Включить функции блокировок. |
pingInterval |
Number |
null |
Emit a Redis PING command every pingInterval milliseconds. Can be used to keep connections alive which may have idle timeouts. |
DependenciesЧтобы использовать этот тип кэша, необходимо установить модуль
ioredis
командойnpm install ioredis --save
.
Собственный алгоритм кэширования
Можно создать собственный модуль кэширования. Рекомендуется использовать в качестве образца модуль MemoryCacher или RedisCacher и реализовать методы get
, set
, del
и clean
.
Создание собственного алгоритма кэширования
const BaseCacher = require("moleculer").Cachers.Base; |
Использование собственного алгоритма кэширования
const { ServiceBroker } = require("moleculer"); |