Кеширование
Многие системы имеют встроенные механизмы кеширование и 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.appAlias | env.userId, env.roles, env.companyId, env.agencyId |
cache-scope='company' | Разрешено всё | env.companyId, env.agencyId, env.applicationId, env.appAlias | env.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
в новой терминологии.