Кэширование в OBI
Автор: Егор Демьянов (все
статьи)
При создании эффективной аналитической системы, удовлетворяющей
нужды десятков или сотен пользователей и имеющей разумные требования
к железу, практически не обойтись без такого механизма, как кэширование.
В этой заметке я хотел бы поговорить о кэшировании в Oracle BI Suite.
В OBI кэширование реализовано в двух компонентах – в BI Server и
в BI Presentation Server.
Начнем с того, что ближе к пользователю – с BI Presentation Server.
Итак, BI Presentation Server имеет так называемый курсорный кэш
(Cursor Cache). В этом кэше хранятся результаты запросов, которые
Presentation Server направлял в BI Server. Если пользователь повторно
выполнит тот же запрос, то результат (курсор) будет взят из кэша.
В этом легко убедиться: перезапустите сервисы OBI, зайдите в Answers
пользователем с уровнем логирования равным 2, создайте запрос и
выполните его, нажав на кнопку Show how results will look on a Dashboard
(в правом верхнем углу). Затем откройте файл NQSQuery.log, там должна
появиться запись вида:
+++paint:300000:300004:----2007/06/19
22:31:31
##############################################
——————– SQL Request:
SET VARIABLE QUERY_SRC_CD=’Report’;SELECT FC_SALARY.ID_EMP saw_0,…
Если теперь повторно нажать на ту же кнопку, то новой записи в
логе не появится. Presentation Server возьмет результат из курсорного
кэша. Можно принудительно заставить Presentation Server выполнить
запрос, нажав на ссылку Refresh. В этом случае запрос будет отправлен
BI Server’у (произойдет ли при этом физическое обращение к БД –
еще вопрос, но об этом чуть позже).
Содержимое курсорного кэша персонифицировано, т.е. если Вася запросит
тот же отчет, для которого уже хранится запись в кэше, созданная
Петей, то Васин запрос все равно будет выполнен заново. Оно и понятно,
ведь Вася и Петя могут иметь разные области видимости данных, а
разбираться с этими вещами не презентационного сервера дело.
Настройками курсорного кэша можно управлять через настроечный файл
instanceconfig.xml. Доступны следующие параметры: максимальное время
хранения записи в кэше, минимальное время хранения записи с момента
её создания, минимальное время хранения записи с момента последнего
к ней обращения, максимальное количество записей в кэше. Просмотреть
курсорный кэш, очистить его полностью или выборочно можно в окне
Presentation Services, выбрав Settings -> Administration ->
Manage Sessions.
Теперь перейдем к аналитическому серверу, который тоже имеет возможность
кэширования. Глобально кэширование включается настройкой в файле
параметров NQSConfig.ini. Опять же при включенном кэшировании результат
запроса сохраняется в кэше, а затем, если выполняется такой же запрос,
результат возвращается сразу из кэша, без обращения к физическим
источникам. Посмотрим журнал запросов. Если первый раз выполнить
запрос, то ему будет соответствовать например такая запись в логе:
+++Administrator:2d0000:2d0018:----2007/06/19
23:01:13
——————– Sending query to database named egor_local (id: <<4225>>):
select distinct T2388.ID_EMP as c1,
T2388.SALARY as c2
from
EGOR.FC_SALARY T2388
order by c1, c2
При повторном выполнении такого же запроса в логе может появится
запись о том, что результат берется из кэша:
+++Administrator:2d0000:2d0019:----2007/06/19
23:01:16
——————– Cache Hit on query:
Matching Query: SET VARIABLE QUERY_SRC_CD=’Report’;SELECT FC_SALARY.ID_EMP
saw_0, FC_SALARY.SALARY saw_1 FROM EGOR ORDER BY saw_0, saw_1
Created by: Administrator
Новый запрос не обязательно должен полностью совпадать с уже хранящимся
в кэше для кэш-хита. Также, в отличие от презентационного сервера,
где записи в кэше персонифицированы, в аналитическом сервере для
выполнения запроса может использоваться запись кэша, созданная другим
пользователем.
Опять же, в отличии от презентационного сервера, где настройки
времени хранения записей в кэше являются глобальными, аналитический
сервер позволяет более гибко управлять тем, сколь долго закэшированный
результат будет считаться актуальным. Для этого используются атрибуты
таблиц на физическом уровне.
Если в свойствах таблицы не стоит флаг Cacheable, то любой запрос,
который использует эту таблицу не будет кэшироваться. Если же таблица
кэшируемая, то можно указать период, через который результат будет
считаться устаревшим. Можно выбрать Cache never expires, и тогда
запись из кэша не будет удаляться, если только администратор не
предпримет каких-либо действий (например, почистит кэш через Administration
Tool). А можно указать какой-либо интервал, в течении которого запись
кэша с момента её создания, может быть использована для возврата
результатов. Как только по истечении этого периода будет выполняться
запрос, для которого запись кэша могла бы подойти, произойдет автоматическое
удаление из кэша, затем будет выполнено обращение к физическим источникам,
и уже свежий результат будет вновь закэширован. В журнале при автоматическом
удалении из кэша появляется запись вида:
+++Administrator:fffe0000:fffe0001:----2007/06/19
23:24:04
——————– Cache Purge of query:
SET VARIABLE QUERY_SRC_CD=’Report’;SELECT FC_SALARY.ID_EMP…
Опять же экспериментально легко убедиться, что если запрос затрагивает
несколько таблиц, то время хранения кэшированного результата этого
запроса будет равно минимальному времени в настройках кэширования
для таблицы. Например, если из двух таблиц, участвующих в запросе,
для одной в настройках стоит 10 минут, а для другой Cache never
expires, то результат запроса будет храниться в кэше 10 минут.
И наконец про самый гибкий способ удаления устаревших записей из
кэша - использование Event-Polling Tables (даже не знаю как это
красиво назвать по-русски, пока буду писать EPT). EPT представляет
собой обычную таблицу базы данных, в которую помещается информация
о том, что произошло обновление таблиц с данными. BI сервер через
заданные интервалы времени опрашивает EPT, и если обнаруживает записи
об обновлении какой-либо таблицы, то автоматически из кэша удаляются
результаты запросов, использовавших обновленную таблицу. Создать
EPT можно при помощи следующего скрипта:
create table UET (
UpdateType Integer not null,
UpdateTime date DEFAULT SYSDATE not null,
DBName char(40) null,
CatalogName varchar(40) null,
SchemaName varchar(40) null,
TableName varchar(40) not null,
Other varchar(80) DEFAULT NULL);
Затем, проимпортировав определение EPT на физический уровень репозитория,
нужно в Administration Tool запустить утилиту Oracle BI Event Table,
в ней указать интервал опроса EPT:
Сразу же по нажатию на OK сервер начинает опрашивать EPT и в логе
появляются записи:
+++Administrator:fffe0000:fffe0002:----2007/06/21
23:45:51
——————– Sending query to database named egor_local (id: <<5045>>):
select T3145.UPDATETYPE as c1,
T3145.UPDATETIME as c2,
T3145.DBNAME as c3,
T3145.CATALOGNAME as c4,
T3145.SCHEMANAME as c5,
T3145.TABLENAME as c6
from
EGOR.EPT T3145
where ( T3145.OTHER in (”) or T3145.OTHER is null )
minus
select T3145.UPDATETYPE as c1,
T3145.UPDATETIME as c2,
T3145.DBNAME as c3,
T3145.CATALOGNAME as c4,
T3145.SCHEMANAME as c5,
T3145.TABLENAME as c6
from
EGOR.EPT T3145
where ( T3145.OTHER = ‘edemyanov’ )
На физическом уровне у меня есть таблица FC_SALARY, для которой
я установил свойство Cache never expires. Я запускаю какой-нибудь
запрос, чтобы в кэше появилась запись, а потом помещаю в EPT уведомление
о том, что таблица FC_SALARY обновлялась:
insert into EPT values(1,
sysdate, 'egor_local', null, 'EGOR', 'fc_salary', NULL);
И опять же через некоторое время в логе видим следующий фрагмент:
-------------------- Sending
query to database named egor_local (id: <<5088>>):
insert into
EGOR.EPT(”UPDATETYPE”, “UPDATETIME”, “DBNAME”, “CATALOGNAME”, “SCHEMANAME”,
“TABLENAME”, “OTHER”) values (1, TO_DATE(’2007-06-21 23:44:00? ,
‘YYYY-MM-DD HH24:MI:SS’), ‘egor_local’, ”, ‘EGOR’, ‘FC_SALARY’,
‘edemyanov’)
+++Administrator:fffe0000:fffe0001:—-2007/06/21 23:45:51
——————– Cache Purge of query:
SET VARIABLE QUERY_SRC_CD=’Report’;SELECT FC_SALARY.ID_EMP saw_0,
FC_SALARY.SALARY saw_1 FROM EGOR ORDER BY saw_0, saw_1
+++Administrator:fffe0000:fffe0002:—-2007/06/21 23:45:51
——————– Sending query to database named egor_local (id: <<5132>>):
delete from
EGOR.UET where EGOR.UET.UPDATETIME = TO_DATE(’2007-06-21 23:44:00?
, ‘YYYY-MM-DD HH24:MI:SS’)
Таким образом, проставив во всех таблицах свойство Cache never
expires, и настроив в ETL-процессах заполнение EPT, мы получаем
автоматическое очищение только устаревших записей в кэше, с минимальными
усилиями.
По этой теме также можжно почитать:
Для удобства отслеживания новых публикаций на сайте рекомендую
подписаться на рассылку или подписаться
на канал RSS.
Если вы нашли в сети интересные ссылки на ресурсы по технологиям
хранилищ данных, OLAP, CRM или data mining, и хотите поделиться
ими с другими, присылайте их.
Я с удовольствием размещу их на этом сайте.
|
|