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 имеет графический профайлер во встроенной консоли что делает процесс анализа более простым и удобным для небольших задач и в процессе разработки.
    Поделиться публикацией

    Комментарии 0

    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

    Самое читаемое