Кеширование
Многие системы имеют встроенные механизмы кеширование и 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.metaAccountInstanceenv.languageenv.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 в новой терминологии.