Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #107, НОЯБРЬ 2007 г.

Поставь сервер на счетчик

 

Хакер, номер #107, стр. 107-148-1

Изучаем приборную панель производительности Windows Server 2003

Еще в первых версиях WinNT был заложен мощный механизм мониторинга, предназначенный для сбора и анализа информации о жизнедеятельности системы в реальном времени, именуемый счетчиками производительности (performance counters). Это словно приборная панель с множеством датчиков, как в автомобиле или даже авианосце. Вот только в Win2k3 этих датчиков на порядок больше, и далеко не каждый знает, для чего они предназначены и как их можно использовать для выявления узких мест в системе и настройки сервера на максимальную производительность.

Вполне типичная ситуация — еще вчера сервер работал нормально, а сегодня он тормозит не по-детски, дрыгает жестким диском, поглощает огромное количество памяти, гоняет по сетке совершенно левый мусор, занимающий практически всю пропускную способность локальной сети. Возможно, на сервере завелся злобный вирус, хакеры решили устроить DDoS-атаку, или какой-то процесс поехал крышей. Но как выяснить, какой из них?!

Опытному администратору достаточно лишь бросить взгляд на счетчики производительности, чтобы проанализировать оперативную обстановку и сделать оргвыводы, прибив дурной процесс или даже написав несложный скрипт, делающий это автоматически (что особенно полезно в тех случаях, когда пользователям разрешается запускать на сервере свои программы).

Счетчики производительности также полезны при планировании аппаратной конфигурации и апгрейде сервера: достаточно ли оперативной памяти, мощности процессора, быстродействия дисковой подсистемы и т.д. Вслепую не так-то просто определить, где происходит затык и какой именно компонент в наибольшей степени ответственен за производительность. А вот собрав данные со счетчиков производительности за некоторое время (например, за день или неделю), мы сможем точно выяснить, что происходит внутри сервера.

Говорить мы будем об английской версии Win2k3 (другой в распоряжении мыщъх'а просто нет), приводя «родные» названия счетчиков. Пользователям русской версии предлагается сыграть в увлекательную игру «Как это называлось в оригинале?!», но читатели у нас со смекалкой, и к таким передрягам им не привыкать, тем более что большинство названий переведено правильно и обратный перевод большой проблемы не составит.

Счетчики производительности в диспетчере задач

Диспетчер задач, вызываемый по <Alt-Ctrl-Del> или <Ctrl-Shift-Esc>, позволяет отображать пару десятков важнейших счетчиков производительности для каждого из процессов. Добавление/удаление счетчиков осуществляется через «View -> Select Columns». К наиболее полезным счетчикам относятся загрузка ЦП (CPU Usage) и объем виртуальной памяти, потребляемой процессом (Memory Usage), что позволяет быстро находить процессы, жрущие ЦП и память. Вкладка Performance рисует красивые графики загрузки ЦП и общего количества выделенной памяти, что вместе с другой важной информацией позволяет оценить среднюю/мгновенную нагрузку на сервер. Соответственно, во вкладке Networking можно найти график общей загруженности сети по всем интерфейсам.

Счетчики производительности в консоли управления

«Монитор производительности», вызываемый через «Start -> Administrative Tools -> Performance» (perfmon.msc), представляет собой основное средство для работы со счетчиками производительности, отображая их значения в виде графика, диаграммы или таблицы. Также имеется возможность записи истории значений в лог-файл, создания истории событий или определенной реакции на достижение счетчиком некоторого порога (например, запуска программы или отправки уведомления администратору). Все эти действия осуществляются через ветвь Performance Logs-n-Alerts, расположенную в левом окне. Интуитивно понятный интерфейс не создает никаких проблем, и «Монитор производительности» осваивается за несколько минут даже без чтения документации.

Обзор важнейших счетчиков производительности

Счетчиков производительности - тысячи, и рассказать о каждом из них нет никакой возможности. Некоторую информацию можно нарыть в базе знаний и MSDN, однако Microsoft дает лишь формальное описание, не вдаваясь в подробности. Между тем интерпретация показаний — дело непростое, и тут есть множество тонкостей, незнание которых может привести к грубым ошибкам. Мыщъх отобрал с десяток важнейших счетчиков и растерзал их в пух и прах.

Processor: % Processor Time

Отображает загрузку процессора в процентах, но мало кто из администраторов задумывается, в процентах от чего. Каждому потоку отпускается определенный квант времени, по истечении которого планировщик принудительно отберет у него управление, передавая его потоку, ближе всех стоящему в очереди (планировка очереди потоков — отдельная песня, и в различных системах она реализована по-разному). Однако поток может вернуть неизрасходованный остаток кванта, обратившись к планировщику, например, через API-функцию Sleep(0).

Счетчик Processor Time на самом деле измеряет не загрузку процессора как таковую, а готовность планировщика предоставить управление потоку по первому требованию. Правильно спроектированная программа практически не загружает процессор, даже если занимается такими «тяжелыми» операциями, как сжатие, криптография и т.д. А кривая программа дает 100%-ную загрузку независимо от мощности процессора (для этого ей достаточно просто войти в длинный цикл - и баста).

Таким образом, 100%-ная загрузка ЦП указывает на наличие одной или нескольких кривых программ. Переход на более мощный ЦП не решает проблемы, и тормоза остаются. В таком случае необходимо найти процесс, который грузит ЦП (удобнее всего это делать через диспетчер задач или систему Alert «Монитора производительности»), и убить его, после чего деинсталлировать соответствующее ему приложение и воспользоваться более корректно написанным программным пакетом. Если же это невозможно, остается либо мириться с тормозами, либо приобрести многопроцессорную машину, тогда загрузка со 100% сразу упадет до 50%. Кстати говоря, на HT-процессорах 50%-ная загрузка равносильна 100%, поскольку загрузка одного виртуального процессора парализует работу другого со всеми вытекающими отсюда последствиями.

В нормальных же условиях средняя загрузка процессора не должна превышать 85%. В противном случае необходимо наращивать частоту процессора/системной шины/оперативной памяти или же увеличивать количество камней, естественно, убедившись, что мы имеем дело с реальной, а не липовой загрузкой ЦП, вызванной кривым ПО. А убедиться в этом очень просто: слегка тормозим процессор (большинство современных матерей позволяет это делать «на лету») и смотрим: если загрузка не изменилась, значит виновато ПО и ЦП тут совсем не причем.

System: Processor Queue Length

Длина очереди потоков, простаивающих в ожидании процессора. Естественно, чем длиннее очередь, тем ниже производительность. Если среднестатистическая длина очереди превышает 10 потоков, имеет смысл задуматься о добавлении в систему новых процессоров, чтобы повысить производительность. Более дешевое решение — увеличить таковую частоту, чтобы очередь потоков продвигалась быстрее, а ее длина, соответственно, сокращалась. Однако оно работает только в тех случаях, когда все программы делятся неиспользованными квантами времени, в противном случае длина очереди останется прежней, поскольку длительность кванта не зависит от тактовой частоты.

Server Work Queues: Queue Length

Рабочая очередь сервера. Чем короче, тем лучше. Если длина очереди меньше четырех запросов, сервер начинает реально тормозить, время отклика увеличивается, и клиенты чувствуют себя крайне некомфортно.

Узким местом может быть и производительность дисковой подсистемы, и недостаточная частота (или количество) процессоров, и нехватка оперативной памяти, поэтому однозначных рекомендаций по устранению этой проблемы, увы, не существует.

Memory: Page Faults/Sec

Количество отказов страниц в секунду. «Отказом страницы» называется ситуация, когда процесс указывает на страницу виртуальной памяти, отсутствующую в рабочем наборе. В некоторых руководствах встречается утверждение, что при избытке оперативной памяти отказов страниц вообще не возникает, но это не более чем расхожее заблуждение.

При запуске исполняемого файла (подключении динамической библиотеки) система грузит его в память не сразу, а по необходимости, частями. При первом обращении к странице (длина которой в большинстве случаев равна 4 Кб) возникает fault и система считывает кусочек файла в память.

Память под стек также выделяется не сразу. На вершине стека располагается специальная «сторожевая» страница, при обращении к которой генерируется отказ, указывающий на необходимость выделения дополнительного стекового пространства.

Таким образом, наличие отказов страниц — это не только нормальное, но и вообще неизбежное явление, которое может быть не связано с файлом подкачки. Однако если в секунду наблюдается пять или более отказов, то, скорее всего, мы имеем дело с хроническим недостатком оперативной памяти, увеличение объема которой позволит существенно повысить производительность. Как вариант - можно оптимизировать файл подкачки, но об этом ниже.

Memory: Pages/Sec

Интенсивность обмена с файлом подкачки (страниц в секунду). Сюда же входят файлы, проецируемые в память (с которыми работают некоторые программы), и сами исполняемые файлы и динамические библиотеки, трактуемые как файлы подкачки, доступные только на чтение. Следовательно, даже если отключить подкачку, установив его размер в ноль, этот счетчик все равно продолжит упорно работать. Так что трактовать его показания нужно с умом.

Если интенсивность обмена с файлом подкачки превышает 10 страниц в секунду, для увеличения производительности необходимо либо добавить оперативной памяти, либо перенести файл подкачки на отдельный диск, желательно подключенный к другому IDE-контроллеру (по умолчанию файл подкачки располагается на системном диске, что не есть хорошо).

При интенсивности обмена в 60 и более страниц в секунду рекомендуется использовать программный или аппаратный RAID уровня 0. Чем больше дисков мы задействуем, тем быстрее будет происходить обмен данными. Как минимум необходимо выделить один диск для каждых 60 страниц. То есть при интенсивности обмена в 180 страниц в секунду нам необходимо по крайней мере три диска, на которых будет размещен только файл подкачки и больше ничего. Однако производительность все равно будет оставаться низкой до тех пор, пока мы не установим дополнительную оперативную память, так что RAID-массив можно рассматривать лишь как временное решение проблемы. Исключение составляют случаи, когда требуемое количество оперативной памяти просто не поддерживается железом (точнее, ее поддержка обходится чересчур дорого) и лучше мириться с низкой производительностью, чем вкладывать огромные средства в быстродействие.

Memory: Available Bytes

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

Допустим, мы имеем 1 Гб RAM, а потребности сервера составляют 10 Гб. Вопрос: какое количество физической памяти покажет счетчик? Ответ: возможно, и ноль байт, но крайне маловероятно. Предположим, что процесс освободил 10 Мб (например, потому что от сервера отключился клиент). Если вся эта память размещалась в RAM, то количество свободной физической памяти увеличится на 10 Мб, притом что ~9 Гб будут болтаться в файле подкачки. Если система интенсивно выделяет/освобождает большое количество памяти, то показания этого счетчика могут достигать 25% и более от общего объема физической памяти, но это еще не значит, что памяти достаточно, и нужно смотреть на количество обращений к файлу подкачки, что описано выше.

Memory: Committed Bytes

Общее количество выделенной памяти в байтах. Если оно превышает объем физической памяти, часть страниц вытесняется в файл подкачки, что, как правило, приводит к снижению производительности. Если количество выделенной памяти не превышает размер физической, то сервер летает на форсаже и никаких особых комментариев тут не требуется. Но это идеализированная ситуация, и в реальной жизни памяти сплошь и рядом оказывается недостаточно. Сам по себе объем выделенной памяти ни о чем не говорит! Вытеснение редко используемого кода/данных в своп практически не снижает производительност, и тут опять-таки нужно смотреть на интенсивность обмена с файлом подкачки.

PhysicalDisk: Current Disk Queue Length

Длина очереди запросов на чтение/запись к физическому диску. Чем короче, тем лучше. Если в очереди постоянно находится два и более запросов, то это не есть хорошо и для увеличения производительности рекомендуется обзавестись программным или аппаратным RAID'ом или использовать более быстрые диски. Как вариант - можно реорганизовать размещение программ и данных, распределив их по разным разделам, или просто запустить дефрагментатор.

PhysicalDisk: % Disk Time

Время занятости диска, в течение которого он обрабатывал запросы на чтение/запись, в процентах. Если загруженность диска достигает 100%, то образуется конкретный затор, требующий перехода на RAID-массивы, использования более быстродействующих винчестеров или дефрагментации. Загрузка менее 80% считается вполне допустимой.

LogicalDisk: % Free Space

Объем свободного дискового пространства в процентах. Если диск заполняется на 80% и более, файловая система NTFS в силу своих конструктивных особенностей начинает конкретно тормозить, а если свободного пространства остается менее 10%, происходит необратимая фрагментация $MTF-файла, хранящего данные обо всех остальных файлах на диске. То есть если диск хотя бы однажды окажется заполненным более чем на 90%, рекомендуется скопировать данные на другой носитель, отформатировать его и вернуть данные обратно. Или, как вариант, установить в «Мониторе производительности» Alert на этот счетчик и при заполнении диска на 80% начать удалять временные файлы, кэш или оправлять sms с уведомлением.

Network Interface: Bytes Total/sec

Загруженность сетевого интерфейса в байтах в секунду. Чем ближе она подбирается к его пропускной способности, тем хуже для пользователей. К сожалению, в такой ситуации очень мало что можно предпринять (переход со 100-мегабитного Ethernet'a на гигабитный не предлагать). Разве что пересмотреть политику документооборота, например перенести часть файлов с сервера на рабочие станции или установить еще один сервер, но это уже требует серьезных вложений.

Network Interface: Output Queue Length

Длина очереди запросов к сетевому интерфейсу. В идеале, никакой очереди быть не должно, но 1-2 запроса считаются вполне приемлемыми, а вот дальнейший рост очереди вызывает ощутимое падение производительности. Причиной может быть и недостаточная пропускная способность сетевых каналов, и медленная обработка запросов на сервере, обусловленная тормознутостью процессора, нехваткой памяти и т.д. Так что универсальных решений тут нет, и нужно смотреть на остальные счетчики производительности, описанные выше.

Заключение

Работа со счетчиками производительности требует глубоких знаний в области устройства операционной системы, и слепое следование рекомендациям обычно приводит к неоправданному наращиванию аппаратных мощностей, а сервер все равно продолжает тормозить. Обидно? Обидно! Но что поделаешь. Интерпретация показаний счетчиков производительности редко бывает однозначна, и, прежде чем принимать какое-то решение, рекомендуется проштудировать «Внутреннее устройство Windows» Руссиновича и «Современные операционные системы» Таненбаума.

Содержание
ttfb: 7.7369213104248 ms