Profiler в MarkLogic Server

от автора

Профилирование – это очень важный аспект при разработке и поддержке почти любого приложения. Не в меньшей мере это относится и к базам данных. Особенно при больших объёмах информации производительность запросов к хранилищу данных является очень критичным. Что же касается производительности запросов в MarkLogic Server и их профилирования, можно сказать что эти вопросы являются одними из самых важных так как XQuery используемый в MarkLogic Server позволяет писать не только очень сложные запросы к самой DB но и довольно сложные приложения.

В MarkLogic Server есть достаточно хороший функционал профилирования представленный в десяти встроенных функциях. Все они располагаются в пространстве имен “http://marklogic.com/xdmp/profile“ и доступны с префиксом “prof:

prof:eval(    $xquery as xs:string,    [$vars as item()*],    [$options as node()?] ) as item()*

Этой функции передается XQuery в виде текстовой строки производительность которого стоит протестировать.

prof:eval( "1 + 1" )

Возвращаемым значением для prof:eval является последовательность (<XML с отчетом>, <результат выполнения XQuery>). Отчет содержит достаточно подробную информацию о выполнении XQuery.

Пример

<prof:metadata>       <prof:overall-elapsed>PT0S</prof:overall-elapsed>       <prof:created>2013-09-13T00:00:00.000+04:00</prof:created>       <prof:server-version>6.0-3</prof:server-version>     </prof:metadata>     <prof:histogram>       <prof:expression> 	<prof:expr-id>13367197075475374717</prof:expr-id> 	<prof:expr-source>1 + 1</prof:expr-source> 	<prof:uri/> 	<prof:line>1</prof:line> 	<prof:column>33</prof:column> 	<prof:count>1</prof:count> 	<prof:shallow-time>PT0S</prof:shallow-time> 	<prof:deep-time>PT0S</prof:deep-time>       </prof:expression>     </prof:histogram>   </prof:report>,   2 

Стоить заметить, что передаваемый таким образом XQuery никак не связан с контекстом в котором выполняется prof:eval. Для того чтобы передать параметры в отлаживаемый XQuery можно воспользоваться параметром $vars, который представляет из себя последовательность переменных в виде (QName, <значение>). Пример

prof:eval( 	"declare variable $a external; $a + 1", 	(fn:QName("", "a"), 1)  ) 

или так

prof:eval(    "declare variable $a external; declare variable $b external; $a + $b",      (fn:QName("", "a"), 1, fn:QName("", "b"), 1) ) 

Если при выполнении XQuery происходит ошибка то prof:eval выкидывает исключение PROF-PROFILEALLOW.

Про следующую функцию можно сказать, что она аналогична prof:eval за тем лишь исключением, что на вход она принимает не XQuery в виде текстовой строки, а путь к XQuery модулю.

prof:invoke(    $path as xs:string,    [$vars as item()*],    [$options as node()?] ) as item()* 

XQuery модуль не должен быть библиотекой, он должен быть “главным” исполняемым модулем. Путь к модулю резолвится относительно корня application server’а. А в остальном prof:invoke полностью аналогична prof:eval.

MarkLogic Server позволяет создавать профили не только для XQuery переданного в функции prof:eval и prof:invoke, но и для инструкций находящихся непосредственно в модуле программы. Причем, профилирование привязано не к конкретному коду программы а к запросу обрабатываемому сервером. Это позволяет отлаживать не только код в текущем запросе, но и производить анализ любого запроса зная его ID и не вмешиваясь в код приложения, что может быть очень полезным в случает анализа приложения в продакшн середе.

Для того чтобы начать сбор информации о выполнении нужно вызвать функцию

prof:enable(    $request-id as xs:unsignedLong ) as empty-sequence()

Где $request-id идентификатор запроса для которого следует начать профилирование.
Получить ID текущего запроса можно функцией xdmp:request().
Для того чтобы остановить сбор информации нужно воспользоваться функцией

prof:disable(    $request-id as xs:unsignedLong ) as empty-sequence()

Как следует из вышесказанного профилировать можно любой код обрабатываемый между вызовами функций prof:enable и prof:disable если профилирование выполняется для текущего запроса, либо между моментами времени к которые вызывались эти функции если производится анализ не текущего запроса.

При попытке использовать профайлер проверяется наличие следующих прав пользователя
“http://marklogic.com/xdmp/privileges/profile-my-requests” – для профилирования своих запросов
“http://marklogic.com/xdmp/privileges/profile-any-requests” – для профилирования любых запросов
Конечно же есть и маленькое исключение – для профилирования текущего запроса (запроса к котором находятся функции профилирования) не требуется специальных привидений, а “profile-my-requests” дает право на профайлинг всех (исключая текущий) запросов текущего пользователя.
Для проверки доступно ли профилирование для определенного запроса можно воспользоваться функцией

prof:allowed(    $request-id as xs:unsignedLong ) as xs:boolean

Для того чтобы получить собранную информацию о выполнении запроса следует воспользоваться функцией

prof:report(    $request-id as xs:unsignedLong ) as element(prof:report)? 

В отличии от prof:eval, которая возвращает отчет и результат выполнения XQuery функции prof:report возвращает только отчет.

Пример использования prof:report

let $e as empty-sequence() := prof:enable( xdmp:request() ) let $r as xs:string := fn:string( 1 + 2 ) return     prof:report( xdmp:request() )

Иногда возникает необходимость удалить накопленную информацию и начать вести отчет заново, для этого используется функция

prof:reset(    $request-id as xs:unsignedLong ) as empty-sequence() 

Следующая функция аналогична функции prof:eval, но в отличии от неё prof:value наследует контекст при выполнении указанного XQuery

prof:value(    $expr as xs:string ) as item()*

Наследование контекста функцией prof:value позволяет писать такой код

let $a := 1 let $b := 2 return      prof:value('$a + $b')

Существует еще две интересные функции

prof:xslt-eval(    $stylesheet as element(),    $input as node()?,    [$params as map:map?],    [$options as node()?] ) as item()*
prof:xslt-invoke(    $path as xs:string,    $input as node()?,    [$params as map:map?],    [$options as node()?] ) as item()*

Где $input – это XML документ, обрабатываемый в XSLT процессоре.
Из названия этих функций понятно что они аналогичны функциям prof:eval и prof:invoke, но используются для профилирования XSLT, процессор которого разработчики MarkLogic Server так заботливо встроили в свой продукт.

MarkLogiс Server предоставляет достаточно мощные средства для анализа производительности. С помшью этого механизма можно создавать сложные профайлеры для разнообразных задач. Вместе с тем MarkLogiс Server имеет графический профайлер во встроенной консоли что делает процесс анализа более простым и удобным для небольших задач и в процессе разработки.

ссылка на оригинал статьи http://habrahabr.ru/post/193674/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *