21 мая 2011

17,7 секунд - быстро, но долго

Перемещено из блога Oracle Hyperion Planning: заметки администратора с разрешения автора - Романа Удальцова

Запуск бизнес-правил из командной строки с использованием Hyperion CmdLineLauncher – это удобно в ситуации, когда необходимо многократно запускать вручную кучу последовательностей, содержащих в себе большое число бизнес-правил. Один раз автоматизировал, и сиди себе запускай батничек.

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

У меня запускается ряд последовательностей, содержащих в себе в общей сложности 547 бизнес-правил. Очень многие из них, судя по hbrlaunch.log, выполняются за доли секунды.

Статистика автоматизированного запуска из командной строки выглядит следующим образом (число бизнес-правил / время выполнения):


Самое интересное происходит в левой части графика:


Видно, что ни одно бизнес-правило не выполнилось быстрей, чем за 17,7 секунд.

Простая арифметика показывает, что на моем примере это целых... 17,7 х 547 = 9681,9 сек. = 2 часа 41 минута 21,9 секунды, потраченные непонятно на что! Распараллеливание запусков бизнес-правил несколько уменьшает это время (примерно до полутора часов), но от этого не легче.

Всё это пока просто наблюдение, если докопаюсь до причины – расскажу.
Есть предположение, что это причиной задержки может служить запуск Java для каждого из процессов, но почему так долго?

UPD
Завёл по этому поводу SR, за 3 дня переписки ничего толкового не посоветовали.
Их резюме – «I'm afraid that we have no other reports of this timing difference nor any documentation that would explain why it might occur. If you believe that this is a significant issue I could test it and then raise it with Development as a bug, although I'm not sure they would accept it as such.»

UPD2
Финальный ответ от Oracle.
Мое предположение подтвердилось. Ну и надо учесть время подключения к EAS:
«I have been able to get an explanation as to why the rules will take longer to run when launched via the cmdlnlauncher: CmdLnLauncher has to connect to remote EAS server in order to launch the rule. For Planning, the rule engine runs within the same JVM and that's why it can launch the rule faster compared to CmdLnlauncher.»

CmdLineLauncher - Параллельное выполнение бизнес-правил

Перемещено из блога Oracle Hyperion Planning: заметки администратора с разрешения автора - Романа Удальцова

Возникла задача ускорить выполнение немаленькой (под 500 шагов) последовательности бизнес-правил. При внимательном рассмотрении выяснилось, что часть из них может выполняться параллельно, чем я и воспользовался с помощью стандартной утилиты Hyperion CmdLineLauncher (лежит в \Hyperion\products\Essbase\eas\console\bin\).

Результатом творческого поиска стала следующая конструкция:

/logs/*.log – логи последнего запуска, старые складываются в logs.rar
/prompts/*.prompts – временные файлы значений переменных
/sys/ – служебные файлы и скрипты, см. подробности далее
Описание последовательности.txt – специально подготовленный текстовый файл
Запуск бизнес-правил.bat – запуск выполнения последовательности

Процесс начинается с подготовки файла Описание последовательности.txt. По сути, это csv-файл следующего вида:

Application;Rule;DBName;Year;Scenario;Version;Entity;Parallel[0/1]
Прил1;Бизнес-правило 1;Plan1;FY11;Budget;Version 1;ЦФО 1;1
Прил1;Бизнес-правило 1;Plan1;FY11;Budget;Version 1;ЦФО 2;0
Прил1;Бизнес-правило 2;Plan1;FY11;Budget;Version 1;-;0

Некоторые пояснения:
– Полное название бизнес-правила включает в себя префикс в виде наименования приложения, оно было выделено в отдельный столбец просто для удобства подготовки файла, позже 1 и 2 столбцы склеиваются
– В столбцах перечисляются все возможные измерения, элементы которых могут встречаться во входных параметрах бизнес-правил
– В случае отсутствия значения (например, Прил1.Бизнес-правило 2 не требует Entity) ставится символ -
– Первая строка форматируется произвольно, т.к. она исключается из обработки
– Parallel можно читать следующим образом: Следующий шаг выполняется [1 – параллельно / 0 – последовательно] с текущим

Таким образом, в приведенном выше примере Прил1.Бизнес-правило 1 будет запущено на параллельное выполнение для ЦФО 1 и ЦФО 2, после чего выполнится Прил1.Бизнес-правило 2 (последовательно).

Далее "Описание последовательности.txt" скармливается скрипту "Запуск бизнес-правил.bat" (запуск из cmd вида "Запуск бизнес-правил.bat" "Описание последовательности.txt" или просто drag-n-drop):

@echo off
chcp 1251 >nul

:: Определение пути к папке HBRLauncher
set HBRPath=%~dp0
set HBRPath=%HBRPath:~0,-1%

:: Определение общих параметров
call "%HBRPath%\sys\Глобальные переменные.cmd" %HBRPath%

:: Архивация старых логов
%HBRPath%\sys\rar.exe m -ep1 -idp %HBRPath%\logs\logs.rar %HBRPath%\logs\*.log >nul

:: Удаление старых временных файлов значений переменных
if exist %HBRPath%\*.prompts del %HBRPath%\*.prompts

:: i:App – j:Rule – k:DBName – l:Year – m:Scenario – n:Version – o:Entity – p:Parallel[0/1] – q:Timeout

for /f "usebackq skip=1 eol=# tokens=1-9 delims=;" %%i in (%1) do (
echo [%%i][%%k][%%l][%%m][%%n][%%j][%%o]
if '%%p'=='1' start "" /d"%HBRPath%\sys\" /min %HBRPath%\sys\RunHBR.bat "%%i" "%%j" "%%k" "%%l" "%%m" "%%n" "%%o"
if '%%p'=='0' start "" /d"%HBRPath%\sys\" /min /w %HBRPath%\sys\RunHBR.bat "%%i" "%%j" "%%k" "%%l" "%%m" "%%n" "%%o"
timeout %%q >nul
)
Основные шаги понятны из комментариев, вот несколько уточнений:
– Строки входного файла можно комментировать символом, указанным в eol, в данном случае #
– Разделители меняются в delims, например, можно заменить ; на или любой другой на ваш вкус
– Между запусками установлен таймаут 4 секунды, если timeout у вас не работает (он входит в Windows Resource Kit), можно использовать конструкцию вида ping -n 5 127.0.0.1>nul (необходимое число секунд + 1)
– skip указывает на число игнорируемых верхних строк

Здесь используется довольно простой скрипт для назначения общих переменных \sys\Глобальные переменные.cmd:

:: Входные переменные: %HBRPath%
@echo off

:: Essbase Administration Server
set EAS=EASServerName

:: Логин
set User=admin

:: Активное приложение
set App=Essbase/EssbaseServerName/AppName/

:: Зашифрованный пароль – файл формируется отдельно (см. \Essbase\eas\console\bin\PasswordEncryption.bat)
set PwdFile=%HBRPath%\sys\%User%.password

Как видно из Запуск бизнес-правил.bat, он построчно обрабатывает входной текстовый файл и в зависимости от параметра Parallel запускает \sys\RunHBR.bat в указанными в строке входного файла параметрами в параллель (1) с промежутками в 4 секунды, либо перед запуском следующего бизнес-правила ожидает завершения текущего (0).

А вот сам \sys\RunHBR.bat, запускающий CmdLineLauncher:

:: 1:App - 2:Rule - 3:DBName - 4:Year - 5:Scenario - 6:Version - 7:Entity

:: Запись входных параметров бизнес-правила (с удалением кавычек)
set Rule=%~1.%~2
set DBName=%~3
set Year=%~4
set Scenario="%~5"
set Version="%~6"
set Entity="%~7"

:: Лог-файл
set Log="%HBRPath%\logs\%date:~6,4%%date:~3,2%%date:~0,2%.%time:~0,2%%time:~3,2%%time:~6,2%%time:~9,2%.%~2.%~7.log"

:: Начало выполнения
echo [%date:~0,2%.%date:~3,2%.%date:~6,4% %time:~0,2%:%time:~3,2%:%time:~6,2%.%time:~9,2%] – Начало выполнения бизнес-правила "%Rule%" (%~7) 1>>%Log%
echo. 1>>%Log%

:: Путь к временному файлу значений входных переменных
set Prompts="%HBRPath%\prompts\%date:~6,4%%date:~3,2%%date:~0,2%.%time:~0,2%%time:~3,2%%time:~6,2%%time:~9,2%.%~2.%~7.prompts"

:: Формирование файла значений переменных
echo %Rule% >>%Prompts%
echo ExecDB::%App%%DBName% >>%Prompts%

if not [%Year%]==[-] echo YearPrompt::"%Year%" >>%Prompts%
if not [%Entity%]==["-"] echo EntityPrompt::"%Entity%" >>%Prompts%
if not [%Version%]==["-"] echo VersionPrompt::"%Version%" >>%Prompts%
if not [%Scenario%]==["-"] echo ScenarioPrompt::"%Scenario%" >>%Prompts%

:: Запуск бизнес-правила
call %HBRPath%\sys\CmdLineLauncher -p:"%PwdFile%" -S%EAS% -U%User% -r"%Rule%" -f%Prompts% 1>>%Log% 2>&1

:: Удаление файла значений переменных
del %Prompts%

echo. 1>>%Log%
echo [%date:~0,2%.%date:~3,2%.%date:~6,4% %time:~0,2%:%time:~3,2%:%time:~6,2%.%time:~9,2%] – Окончание выполнения бизнес-правила "%Rule%" (%~7) 1>>%Log%

exit

15 мая 2011

Пост с Большим респектом

Небольшой пост с Большим респектом (благодраностью) Андрею Пивоварову за серию статей про то, как нужно готовить, готовиться и проводить презентации, в которых нужно не продать, а действительно что-то рассказать на доступном для аудитории уровне!

- Начало
- Продолжение
- Еще
- И конец

Не в первый раз уже перечитываю, применяю и убеждаюсь, что написанное в этих статьях верно и полезно. Категорически рекомендую!

07 мая 2011

Batch Sequence via MaxL

Занимаюсь старинной версией Hyperion Planning 3.5/Essbase 7.1
Приложение HBRules (для создания и управления бизнес-правилами; современный аналог - CalcManager) имеет ряд неприятных ограничений. В этот раз меня разозлил момент, связанный с тем, что невозможно создавать длинные последовательности (sequences). А именно такая задача и стояла, озаглавленная как «Полный пересчет модели».
Итак, один большой сиквенс сделать невозможно. Разбить на несколько – неудобно, потому что пересчеты возможно запускать только по ночам. Да, еще хочется иметь лог для оценки времени (для поиска узких мест и дальнейшей их оптимизации) и статуса завершения расчетов.

Итак, пришел к такому варианту:

1. Переводим (Export) нужные правила в Essbase, чтобы иметь возможность запускать их через MaxL. Минус очевиден: мы теряем связь правила, которое будет портировано в Essbase, и оригинального правила в HBRules, которое может измениться. Лучшее, что я придумал – создать таблицу соответствий имен правил HBRules – Essbase. При изменении правила в HBRules необходимо экспортировать его в Essbase-правило с тем же именем.

2. Готовим список правил Essbase, которые нужно запускать. Располагаем их в необходимом порядке запуска:
FC-1-01
FC-1-02
FC-2-01
Список сохраним в ascii-файлик RulesList.txt.

3. Пишем batch-скрипт, который будет генерить(!) MaxL-скрипт для полного расчета:
@echo off
echo =======================================================
echo Batch AutoCalc Essbase App Script by Antun Kulkov, 2011
echo See more at http://silw.blogspot.com
setlocal
rem ------ Settings -------
set year=%date:~6%
set month=%date:~3,2%
set day=%date:~0,2%
set hour=%time:~0,2%
if '%hour:~0,1%'==' ' set hour=0%time:~1,1%
set minute=%time:~3,2%
set tdate=%year%-%month%-%day%-%hour%%minute%
set STARTPATH=D:\Hyperion\AutoCalc
set ESSMSH=%ARBORPATH%\bin\essmsh.exe
set SERVER=essbase_server_name_or_ip
set USER=ess_admin
set PASSWORD=ess_admin_password
set APPNAME=app_name
set FILE_MAXL=%STARTPATH%\%APPNAME%_script.maxl
set FILE_LOG=%STARTPATH%\logs\AutoCalc_%APPNAME%_%tdate%.log
rem ------ End settings -------
echo Start: %tdate%

echo spool on to '%FILE_LOG%'; > %FILE_MAXL%
echo login '%USER%' '%PASSWORD%' on '%SERVER%'; >> %FILE_MAXL%
echo alter application '%APPNAME%' enable startup; >> %FILE_MAXL%
for /f %%i in (%STARTPATH%\RulesList.txt) do (
echo execute calculation '%APPNAME%'.'Plan1'.'%%i'; >> %FILE_MAXL%
)
echo logout; >> %FILE_MAXL%

echo MaxL script has been generated and run:
echo %FILE_MAXL%
echo See details of calc execution in:
echo %FILE_LOG%
%ESSMSH% %STARTPATH%\%APPNAME%_script.maxl
echo =======================================================
где STARTPATH – директория запуска данного скрипта,
SERVER, USER, PASSWORD – задают сервер Essbase и его пользователя с администраторскими правами,
APPNAME – имя приложения (скажу, что работал с одним кубом Plan1, поэтому прописал его жестко в скрипте). Не забываем брать в кавычки значения переменных, которые содержат пробелы!

Принцип работы:
В папке с этим batch-скриптом генрим MaxL-скрипт (APPNAME_script.maxl), получая имена правил из файла RulesList.txt. И выполняем этот MaxL-скрипт, на всякий случай запуская приложение в Essbase. Лог выполнения MaxL-скрипта пишется в APPNAME_AutoCalc_{дата-время}.log. Все прозрачно!

Замечание: Для правил, использующих переменные с вводом данных (например, предела ставки начисления ЕСН), необходимо установить необходимые значения как дефолтные!

4. Добавляем наш batch-скрипт в расписание, если нужно.

Enjoy!

UPD: Альтернативный (несколько более сложный, но более функциональный) вариант описан у Романа Удальцова здесь