ример 1: обманчивые общесистемные данные
После нескольких месяцев попыток договориться с клиентом из Далласа о визите, в понедельник в отделе продаж hotsos.com раздался телефонный звонок. Люди, с которыми мы пытались договориться о встрече, зашли в тупик, пытаясь найти причину ухудшения производительности, и собирались дать нам шанс все исправить. В среду мы этим шансом воспользовались.
Что-то похожее мы уже видели. Компания несколько месяцев боролась с ухудшением производительности, связанным со слишком большим временем отклика одной программы. Все эти месяцы штатные специалисты компании старались найти решение, но ни одна из их попыток не была успешной. В конце концов они опустили руки, и руководство решило выделить серьезную сумму на решение проблемы. Поэтому в выходные, предшествующие полученному нами телефонному звонку, компания заменила в системе процессоры на более производительные. Модернизация прошла успешно, и, конечно же, все надеялись (хоть и нервничали немного), что в понедельник все будет работать гораздо лучше.
К их ужасу производительность медленной программы после чрезвычайно дорогостоящего обновления оборудования стала еще хуже. Причем значительно хуже. Поэтому в понедельник они нам позвонили: «Приходите и покажите нам, что можно сделать». Через два дня мы сели в машину и поехали. Вот что мы обнаружили:
Компания работала с продуктом Oracle Payroll. Он был сконфигурирован традиционным способом: пакетные задания выполнялись на сервере базы данных, а десятки пользователей, работавших через броузеры, были распределены по зданию и связаны локальной сетью (LAN).
Производительность программы PYUGEN мешала нормальной работе компании уже несколько месяцев. Когда мы появились, программа PYUGEN могла обрабатывать около 27 заданий в минуту. Производительность надо было увеличить вдвое.
Мониторинг производительности выполнялся при помощи хорошо известного полнофункционального средства, которое запрашивало данные фиксированных представлений V$SYSTEM_EVENT и V$LATCH. Это средство показывало, что источником неприятностей в системе были события ожидания освобождения защелок latch free. Подавляющее большинство ожиданий latch free относилось к защелкам цепочек буферов кэша.
Специалисты компании правильно поняли, что конкуренция за защелки цепочек буферов кэша является вероятным признаком неэффективного SQL (т. е. содержащего большое количество LIO). Однако разработчики приложений заказчика проанализировали программу PYUGEN и не смогли уменьшить количество LIO в SQL.
Только что произведенное повышение частоты всех двенадцати процессоров системы с 700 МГц до 1 ГГц значительно ухудшило производительность программы PYUGEN. Отсутствие повышения производительности при замене процессоров стало последней каплей, заставившей клиента пригласить к себе команду hotsos.com.
К моменту нашего прибытия клиент уже завершил этап выбора пользовательской операции, определив, что основную проблему для производительности системы представляет собой PYUGEN. Поэтому нашим первым шагом по прибытии был сбор корректно выбранных диагностических данных. Для этого клиента сбор данных расширенной трассировки SQL был прост, т. к. время отклика пользовательской операции формировалось исключительно выполнением программы PYUGEN. Для включения и отключения расширенной трассировки SQL мы применили собственную свободно распространяемую программу Sparky (http://www.hotsos.com).
Программа, которую мы собирались исследовать, выполнялась более получаса, в результате чего было сформировано около 70 Мбайт данных расширенной трассировки. Данные трассировки обрабатывались программой Hotsos Profiler, которая сформировала профиль ресурсов, приведенный в примере 12.1.
Пример 12.1. Профиль ресурсов для программы Oracle Payroll
Response Time Component
|
Duration
|
# Calls
|
Dur/Call
|
|
SQL*Net message from client
|
984.0s
|
49.6%
|
95,161
|
0.010340s
|
SQL*Net more data from client
|
418.8s
|
21.1%
|
3,345
|
0.125208s
|
db file sequential read
|
279.3s
|
14.1%
|
45,084
|
0.006196s
|
CPU service
|
248.7s
|
12.5%
|
222,760
|
0.001116s
|
unaccounted-for
|
27.9s
|
1.4%
|
||
latch free
|
23.7s
|
1.2%
|
34,695
|
0.000683s
|
log file sync
|
1.1s
|
0.1%
|
506
|
0.002154s
|
SQL*Net more data to client
|
0.8s
|
0.0%
|
15,982
|
0.000052s
|
log file switch completion
|
0.3s
|
0.0%
|
3
|
0.093333s
|
enqueue
|
0.3s
|
0.0%
|
106
|
0.002358s
|
buffer busy waits
|
0.2s
|
0.0%
|
67
|
0.003284s
|
SQL*Net message to client
|
0.2s
|
0.0%
|
95,161
|
0.000003s
|
db file scattered read
|
0.0s
|
0.0%
|
2
|
0.005000s
|
SQL*Net break/reset to client
|
0.0s
|
0.0%
|
2
|
0.000000s
|
Total
|
1,985.3s
|
100.0%
|
Данные профиля ресурсов удивили всех, кто работал над проектом последние несколько месяцев. Уже по одному только профилю ресурсов с абсолютной уверенностью можно утверждать, что вклад ожидания освобождения защелок в общее время отклика PYUGEN был чрезвычайно мал. Если бы компании удалось вообще исключить событие ожидания latch free из системы, время выполнения программы изменилось бы на 1%.
Такое в нашей работе бывает часто: многие проблемы производительности пользовательских операций невозможно определить на основе исследования данных в масштабе всей системы. Данные из представления V$SYSTEM_EVENT верны; просто они не имеют отношения к решаемой проблеме. Помните - по агрегированным данным нельзя восстановить составляющие.
На самом деле представление V$SYSTEM_EVENT ясно указывало на то, что основным событием ожидания является SQL*Net message from client, но ведь каждый уважающий себя аналитик производительности Oracle знает, что надо исключить из рассмотрения все события SQL*Net, т. к. они являются событиями «простоя».
Около 50% общего времени отклика PYUGEN было занято выполнением системных вызовов чтения SQL*Net. Расположение событий SQL*Net message from client во главе профиля ресурсов заставило нас быстро перепроверить собранные данные с тем, чтобы убедиться, что такое главенствующее положение событий, происходящих между вызовами базы данных, не является результатом ошибки сбора данных. Ошибки не было. События SQL*Net message from client и их продолжительности были равномерно распределены по файлу трассировки и являлись результатом тысяч вызовов базы данных. Если принять в рассмотрение еще одно событие SQL*Net, SQL*Net more data from client, то окажется, что мы выявили более 70% общего времени отклика PYUGEN.
Естественно, нельзя игнорировать 70% времени отклика программы, даже если соответствующие события называют событиями «простоя». Будь то событие простоя или нет, в любом случае это время вошло в пользовательское время отклика, значит, с ним нужно разобраться. Если бы статистика собиралась не так аккуратно (у нас корректно выбрана программа и временная область), то события SQL*Net message from client, вероятно, занимали бы гораздо больше времени в полученных данных. При такой ошибке сбора необходимо исключить из рассмотрения так называемые события простоя.
Все правильно, имя хоста, выведенное справа от символа @ в V$SESSION, точно совпадает с именем узла (Node name) из преамбулы файла трассировки SQL. PYUGEN точно работает на том же самом хосте, что и сервер
Мы начали исследование с первой строки профиля ресурсов. Поскольку речь шла о поставляемом приложении, мы считали, что вряд ли удастся манипулировать количеством вызовов базы данных, и поэтому сконцентрировались на столбце продолжительности вызова. И значение данного столбца показалось нам подозрительным - его порядок отражал скорее работу в локальной сети (сотые доли секунды, о чем мы говорили в главе 10), чем межпроцессное взаимодействие (IPC) (тысячные доли секунды или меньше). Поэтому мы перепроверили, действительно ли пакетная программа PYUGEN выполняется на сервере базы данных (там же, где и соответствующий PYUGEN серверный процесс Oracle), для чего обратились к данным V$SESSION, автоматически собранным программой Sparky при включении сбора (см. пример 12.2).
базы данных. Почему же тогда при работе программы PYUGEN наблюдаются такие задержки SQL*Net message from client? В поисках ответа мы обратились к файлу tnsnames.ora системы. Оказалось, что системный инженер, стремясь облегчить жизнь системных администраторов, установил для всей системы единый псевдоним TNS. Пакетные задания направлялись на тот же адаптер протокола TCP/IP, что и броузеры клиентов системы.
Разработать стратегию, отлично вписавшуюся в рамки благоприятствования системному администрированию, было несложно. Можно было добавить второй псевдоним в файл tnsnames.ora. Второй псевдоним был бы идентичен первому, только имя у него было бы другое, а синтаксис (PROTOCOL=BEQ) занял бы место (PROTOCOL=TCP). Заказчику надо было бы остановить и заново запустить Oracle Applications Concurrent Manager, указав новый псевдоним, использующий адаптер протокола bequeath. Новый файл tnsnames.ora можно было бы без побочных эффектов распространить по всей системе. Все, кроме запустивших Concurrent Manager, продолжали бы использовать тот же TNS-псевдоним, что и ранее.
Прежде чем претворять это изменение в жизнь, заказчик провел простой эксперимент. Была выполнена команда SELECT, которая потребовала бы нескольких тысяч вызовов базы данных из сеанса SQL*Plus, работающего на сервере базы данных, и для нее были сняты временные характеристики. Сначала команду выполнили в сеансе, установленном при помощи старого псевдонима, использующего адаптер протокола TCP/IP, а затем в сеансе, установленном при помощи нового псевдонима, использующего адаптер протокола bequeath. Тест показал, что использование адаптера протокола bequeath снизило задержки SQL*Net message from client до менее чем 0,001 секунды. Выполнив лишь одно это изменение, мы могли ожидать сокращения общего времени отклика программы как минимум на 40% (рис. 12.1).
На самом деле у нас есть причины ожидать улучшения более чем на 40%. Второй по значимости вклад во время отклика PYUGEN вносит еще одно событие SQL*Net - SQL*Net more data from client. Это событие вызвано последовательностью вызовов разбора, передававших слишком длинные текстовые строки SQL по SQL*Net от клиента к серверу (вместо того чтобы достигать той же цели посредством вызовов хранимых процедур). Длинные текстовые строки SQL не помещались в один пакет SQL*Net, поэтому ядро Oracle довольно долго ожидало второго и, возможно, последующих пакетов SQL*Net в ходе вызовов разбора. Конечно, учитывая, что Oracle Payroll поставляется без исходных текстов, наши надежды на быстрое уменьшение количества выполнений данного события были достаточно призрачны. Однако можно было надеяться, что задержка SQL*Net more data from client частично связана с передачей по сети, и что смена адаптера протокола ускорит исполнение этого события.
Результаты оказались просто замечательными. Производительность программы Payroll возросла с 27 заданий в минуту до 61. Проверка предложенного изменения tnsnames.ora заняла 15 минут и еще около недели ушло на процедуру контроля за изменениями. В целом мы провели у заказчика менее четырех часов. Из них два заняла инсталляция Sparky (потребовалось обновить Perl на хосте сервера базы данных), и чуть менее получаса потребовалось для прогона программы PYUGEN с включенной трассировкой SQL уровня 8. Оставшиеся полтора часа были посвящены встречам, приветствиям, анализу, тестированию и подведению итогов.
Да, кстати... почему программа Payroll стала работать медленнее после модернизации процессоров? Ей требовалось немного процессорного времени, поэтому такая модернизация имела чрезвычайно малый положительный эффект на PYUGEN. Большая часть времени уходила на простаивание в очереди для сетевого обслуживания. При этом наряду с заданием Payroll исполнялись и другие программы. Обновление процессора сделало их более быстрыми, в результате чего они стали интенсивнее генерировать сетевые вызовы (число которых осталось неизменным после модернизации процессоров) в течение более короткого промежутка времени. В результате конкуренция за сетевое обслуживание в процессе работы Payroll усилилась. Следовательно, каждый сетевой вызов ввода/вывода, совершаемый программой Payroll, стал чуть более медленным, чем до модернизации. Ухудшение сетевого времени отклика перечеркнуло небольшое улучшение времени обслуживания процессором, что привело к итоговому снижению производительности Payroll. А это было нехорошо... ведь программа Payroll имела самый высокий бизнес-приоритет в системе.
Рассмотренный пример иллюстрирует несколько важных моментов:
Нельзя опираться на данные V$, определяя причину низкой производительности системы. Главную роль в постановке задачи должен играть бизнес. Реальная проблема производительности системы -это то, что вызывает недопустимо большое время отклика для самой важной, с точки зрения бизнеса, пользовательской операции.
По агрегированным данным нельзя восстановить составляющие. Анализ общесистемных статистик для экземпляра не позволяет гарантированно определить, в чем причина плохой производительности одной конкретной программы.
Модернизация оборудования - более сомнительная, в смысле повышения производительности, операция, чем можно себе представить. Можно не только зря потратить много денег, но и снизить производительность «усовершенствуемой» программы.
Выявить и устранить причину плохой производительности посредством старого метода проб и ошибок практически невозможно. Плохая производительность может быть вызвана огромным количеством разнообразных факторов. Не надо проверять все, что могло бы ее вызвать, достаточно исследовать пользовательскую операцию и найти причину.
< Предыдущая | Следующая > |
---|