META
Руководства
Кеширование

Кеширование

Многие системы имеют встроенные механизмы кеширование и META не исключение.

Мета позволяет кешировать результаты выполнения скриптов в двух срезах - срез по области видимости и по области действия

Независимо от настройки срезов, для включения кеширования у скрипта должен быть определен атрибут cache, выполняющий две функции:

  • Его наличие говорит о том, что требуется кеширование
  • Его значение задает время кеширования, например: 10s - 10 секунд, 5m - 5 минут, 1h - 1 час. Комбинирование значений не допускается.

Срез по области видимости

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

Область видимости - пользователь

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

//Пример
<script type="meta/sql" id="res" cache="5m" cache-scope="user">
SELECT ...
</script>
//или даже так, без атрибута вообще
<script type="meta/sql" id="res" cache="5m">
    SELECT ...
</script>

Область видимости - компания

Запись кеша будет общий для всех пользователей компании (env.companyId). Подходит, когда данные в пределах одной компании всегда одинаковы

//Пример
<script type="meta/sql" id="res" cache="5m" cache-scope="company">
SELECT ...
</script>

Область видимости - все

Запись кеша будет общий для всех пользователей вообще. Подходит для общих справочников, которые отображаются одинакого для всех пользователей Меты

//Пример
<script type="meta/sql" id="res" cache="5m" cache-scope="all">
SELECT ...
</script>

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

Срез по области действия

Область действия - это область, в пределах которой будет кешироваться результат работы скрипта. Всего выделено три области:

  • instance - инстанс. Скрипт будет кешироваться среди всех приложений в рамках одного инстанса Меты (т.е. среди всех подов Kubernates тоже кеш будет общий)
  • application - приложение. Скрипт будет кешироваться в рамках всего приложения.
  • page - страница. Скрипт будет кешироваться в пределах одной страницы каждого приложения отдельно. Т.е. если страница доступна в нескольких приложениях, скрипт в каждом приложении будет кешироваться отдельно

Срез instance

Инстанс - самая большая область действия кеша, включающая в себя все приложения и все поды в случае, если приложение развернуто в Kubernates.

Срез application

Приложение - срез поменьше. Может пригодится в случае, когда данные скрипта одинаковы в пределах всего приложения

Срез page

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

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

В срезе page в ключе используются максимально возможные данные: pageId, applicationId, objectId, entityId, stateParams, limit/offset, language. Т.е. при изменении на странице любого из этих параметров скрипт будет выполняться и кешироваться заново.

В срезе application от всех этих переменных сохраняться будет только applicationId и language

В срезе instance будет использоваться только language.

Но как тогда в двух последних средах понять, что два скрипта на разных страницах - это по сути один скрипт, которые должны делить общий кеш? На помощь приходит механизм хэширования содержимого скрипта. Т.е. скрипты с одинаковым содержимым и одинаковым id будут считаться идентичными и если два таких скрипта будут пересекаться по настройкам кеширования (области видимости и области действия) они будут делить одну запись в кеше.

Например:

<script type="meta/sql" id="res" cache="5m" cache-area="page">
    SELECT ...
</script>

Тут все просто. область действия - страница и уникальный идентификатор res вместе с остальными параметрами ключа кеша позволяет обеспечить уникальнойть записи в кеше.

Еще пример:

<script type="meta/sql" id="res" cache="5m" cache-area="instance">
    SELECT 100
</script>

Здесь область действия - весь инстанс, все приложения. Если несколько скриптов с такими настройками кеша

Ограничения

Области действия application и instance добавлены для того, чтобы максимально часто использовать кеш, в первую очередь, для справочников. Поэтому в составе ключей скриптов с такими областями действия нет ни stateParams ни objectId ни других специфичных для отдельных страниц данных, из-за наличия которых кеш скрипта должен был бы существовать во множестве экземпляров.

Именно по этому введены дополнительные ограничения на синтаксис таких скриптов. В скриптах с cache-area равным application или instance запрещено использование шаблонизации FreeMarker, а также обращений :env., ${env. и ${pvm..

В качестве исключения есть набор разрешенных обращений.

Вначале список тех, которые можно использовать всегда, независимо от настроек кеша:

  • env.metaAccountInstance
  • env.language
  • env.referer

А теперь разрешенные обращения, зависящие от настроек кеша:

cache-area='page'cache-area='application'cache-area='instance'
cache-scope='user'Разрешено всёenv.userId, env.roles, env.companyId, env.agencyId, env.applicationId, env.appAliasenv.userId, env.roles, env.companyId, env.agencyId
cache-scope='company'Разрешено всёenv.companyId, env.agencyId, env.applicationId, env.appAliasenv.companyId, env.agencyId
cache-scope='all'Разрешено всёenv.applicationId, env.appAlias
  • Если cache-scope=user, можно обращаться к env.userId, env.roles, env.companyId и env.agencyId
  • Если cache-scope=company, можно обращаться к env.companyId и env.agencyId

Очевидно, что распространение области действия кеша скрипта с page на application или, тем более, instance при невнимательном подходе может повлечь за собой получение в других местах

Матрица распространения кеша

Данная таблица поможет по комбинации параметров понять, для кого будет расшарен кеш того или иного скрипта

cache-area='page'cache-area='application'cache-area='instance'
cache-scope='user'Для каждого пользователя отдельно в пределах страницы текущего приложенияДля каждого пользователя отдельно в пределах текущего приложенияДля каждого пользователя отдельно в пределах всех приложений
cache-scope='company'Для всех пользователей компании в пределах страницы текущего приложенияДля всех пользователей компании в пределах текущего приложенияДля всех пользователей компании в пределах всех приложений
cache-scope='all'Для всех пользователей в пределах страницы текущего приложенияДля всех пользователей в пределах текущего приложенияДля всех пользователей в пределах всех приложений

Миграция со старой системы кеширования

До июня 2025 года действовала упрощенная схема, допускающая, кроме атрибута cache только определение кеша по компании и глобального кеша.

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

Кеш с областью видимости - пользователь

//Было
<script type="meta/sql" id="res" cache="5m">
</script>
//Стало
<script type="meta/sql" id="res" cache="5m" cache-scope="user">
</script>
//В новой схеме cache-scope можно не указывать, если нужна область видимости до пользователя
//Это сделано для обратной совместимости двух схем

Кеш с областью видимости - все пользователи компании

//Было
<script type="meta/sql" id="res" cache="5m" cache-company>
</script>
//Стало
<script type="meta/sql" id="res" cache="5m" cache-scope="company">
</script>

Кеш с областью видимости - все пользователи сервиса

//Было
<script type="meta/sql" id="res" cache="5m" cache-global>
</script>
//Стало
<script type="meta/sql" id="res" cache="5m" cache-scope="all">
</script>

Срезов по области действия в старой схеме не было - все скрипты кешировались с область page в новой терминологии.