 | Уровень сложности: средний Амит Матюр, ведущий технический консультант и менеджер по реализации решений, IBM Сумит Чаула, сертифицированный IT-архитектор IBM и руководитель технической группы, Java Enablement, IBM
28.09.2009 В этой серии из пяти статей даются советы и описываются приемы, которые обычно используются при настройке Java™-приложений для достижения оптимальной производительности на AIX®. Эта статья посвящена ситуации, когда подсистема ввода/вывода (I/O) или сеть могут стать узким местом.
Введение
Это четвертая статья из серии статей о настройке производительности Java на AIX, состоящей из пяти частей. Прежде чем продолжить чтение этой статьи, настоятельно рекомендуется еще раз просмотреть предыдущие статьи этой серии.
В этой статье рассказывается еще о двух областях, которые могут стать узким местом в производительности:
- сеть;
- дисковый ввод/вывод (I/O).
Как правило, рассматриваемые проблемы специфичны для AIX и должны быть настроены независимо от приложения Java, поэтому в этой статье, в отличие от двух предыдущих (второй и третьей частей), основное внимание уделяется тому, как получить информацию, требующуюся для процесса настройки. В этой статье содержится всего лишь несколько советов, но общее обсуждение эффективности инструментов в сочетании с этими советами даст достаточно информации для настройки производительности.
Ввод/вывод и сеть как узкое место
В этой статье рассматриваются ситуации, когда узким местом становятся ввод/вывод или сеть.
Из предыдущих статей этой серии можно было узнать, как каждый небольшой компонент вписывается в общую картину. Была сделана попытка разбить советы по областям применения, но эта классификация ни в коей мере не является всеобъемлющей. Для сети и ввода/вывода трудно найти источники проблем, но всё же можно оценить, как они влияют на производительность приложения. Только хорошее знание приложения позволит решить проблему. Например, ранее в этой серии обсуждалась важность проверки того, что куча не разбивается на страницы. Максимальный размер кучи, устанавливаемый переключателем –Xmx, должен быть меньше общего объема физической памяти, установленной в системе (определяется с помощью bootinfo -r или lsattr -El sys0 -a realmem, см. статью AIX Commands you should not leave home without).
Инструменты (например, topas и iostat) могут отобразить активность использования различных дисков, но в большинстве случаев виновником возникновения узкого места является цикл GC или какой-либо известный фрагмент функционального кода, поэтому если вы хорошо знаете приложение, то сможете легко найти узкое место. Инструменты типа filemon подскажут, к каким файлам осуществлялся доступ, позволяя избежать настройки "вслепую". Если производительность Java-приложения упала из-за неправильной конфигурации системы, то надо оценить производительность системы в целом. Например, для устранения узкого места дисковой подсистемы может потребоваться правильно распределить данные или приобрести более быстрые диски. Эта тема, выходящая за рамки этой статьи, подробно раскрывается в книгах из серии IBM Redbooks, например, Understanding IBM eServer pSeries Performance and Sizing.
Настройка сетевых буферов и других параметров сети может существенно повлиять на приложения, активно использующие сеть. Хорошим источником информации по настройке сетевых параметров является раздел Network Tunable Parameters руководства Performance Management Guide. Часто для настройки используются thewall, socketthresh, sbmax, somaxconnect, tcp_sendspace, tcp_recvspace, rfc1323 и т. д. Выдаваемая этими инструментами информация относится не только к AIX или Java, но и к любому приложению, интенсивно использующему сеть, поэтому их использование должно быть первым шагом при настройке производительности.
Далее в этом разделе дается краткое введение в некоторые общие инструменты и в обнаружение проблем, специфичных для Java. Дополнительную информацию можно получить в справочниках AIX 5L Performance Tools Handbook и Understanding IBM eServer pSeries Performance and Sizing.
vmstat
Вы наверняка уже пользовались универсальной командой vmstat. Для информации о вводе/выводе просмотрите значение столбца wa (I/O Wait) в разделе cpu. Если это значение большое, то, скорее всего, диски являются узким местом, и для вывода подробной информации о их вводе/выводе следует запустить iostat.
iostat
Утилита iostat является идеальным инструментом для определения узкого места в подсистеме ввода/вывода. Она отображает процессы чтения и записи для всех дисков. Это прекрасный инструмент для определения ситуации, когда нужно распределить ввод/вывод между несколькими дисками. Кроме того, этот инструмент генерирует такие же отчеты об активности центрального процессора, как и vmstat.
Для начала следует выяснить, что делает система. Для этого введите простую команду iostat -s в момент, когда работает приложение. Пример вывода этой команды:
tty: tin tout avg-cpu: % user % sys % idle % iowait
0.3 232.9 13.8 19.1 27.4 39.6
Disks: % tm_act Kbps tps Kb_read Kb_wrtn
hdisk0 28.7 291.4 35.0 176503 2744795
hdisk1 0.0 0.4 0.0 3537 0
hdisk7 1.7 34.9 9.8 8920 341112
hdisk14 24.5 1206.1 36.2 1188404 10904509
hdisk18 0.0 1.2 0.1 10052 2046
hdisk8 2.1 36.8 10.5 10808 357910
|
Чтобы увидеть, долго ли система ожидает выполнения операций ввода/вывода, достаточно посмотреть на значение %iowait. Если система использует страничную подкачку файлов, то это будет видно, но одного этого значения недостаточно для определения того, что происходит с системой. Например, если приложением выполняется последовательная запись файлов, то большое значение %iowait является нормой.
%tm_act показывает процент времени активного использования диска. Трассировка, приведенная выше, показывает очень интересный сценарий – показатель %iowait был близок к 40%, но tm_acts был намного меньше 100%, находясь в районе 30%. К системе, на которой был проведен опыт, был подключен дисковый массив Fibre Channel, и узким местом оказался маршрут до системы хранения SAN. Как только были получены конкретные цифры, все это стало очевидным!
Также можно использовать # iostat -at <interval> <count> или iostat -sat ... которые выводят tps и KBps (а также скорость чтения и записи) для адаптеров. Флаг -s означает, что нужно выдавать общую статистику системы.
netstat
При настройке сети netstat является идеальным инструментом для начала исследования. Команда netstat -m может применяться для мониторинга использования памяти mbuf, что может служить индикатором использования памяти сокетами и сетью. Если используется no -o extendednetstats=1, то команда netstat -m отобразит более подробную информацию, но это может повлиять на производительность, поэтому такой вариант следует использовать только для диагностики. При использовании netstat -m наиболее ценная информация выводится в начале отчета, например:
67 mbufs in use:
64 mbuf cluster pages in use
272 Kbytes allocated to mbufs
0 requests for mbufs denied
0 calls to protocol drain routines
0 sockets not created because sockthresh was reached
|
и в конце отчета, например:
Streams mblk statistic failures:
0 high priority mblk failures
0 medium priority mblk failures
0 low priority mblk failures
|
В AIX 5L Performance Tools Handbook дается хорошее описание параметров, которые следует настроить при обнаружении сбоев в отчете netstat -m. Можно попробовать команду netstat -i x (x необходимо заменить значением интервала сбора данных), чтобы проследить за использованием сети и возможной потерей пакетов. Для приложений, интенсивно использующих сеть, это является первым шагом для проверки отсутствия сбоев.
netpmon
netpmon использует трассировку для получения подробной картины сетевой активности в течение определенного интервала времени. Он также отображает статистику процессов CPU, в которую входят:
- общее количество процессорного времени, используемого процессом;
- использование CPU процессом в виде процентной доли общего времени;
- общее время, в течение которого процесс использовал код, связанный с сетевой работой.
Для начала нужно ввести команду:
netpmon -o /tmp/netpmon.log; sleep 20; trcstop
|
Эта команда запустит netpmon на 20 секунд, затем остановит ее, используя команду trcstop, и запишет вывод в /tmp/netpmon.log. Из анализа отчета видно, что этот пример является хорошей иллюстрацией для одной из статей "Java Performance tuning":
Process CPU Usage Statistics:
-----------------------------
Network
Process (top 20) PID CPU Time CPU % CPU %
----------------------------------------------------------
java 12192 2.0277 5.061 1.370
UNKNOWN 13758 0.8588 2.144 0.000
gil 1806 0.0699 0.174 0.174
UNKNOWN 18136 0.0635 0.159 0.000
dtgreet 3678 0.0376 0.094 0.000
swapper 0 0.0138 0.034 0.000
trcstop 18460 0.0121 0.030 0.000
sleep 18458 0.0061 0.015 0.000
|
Другая полезная часть трассировки – это использование адаптера:
----------- Xmit ----------- -------- Recv ---------
Device Pkts/s Bytes/s Util QLen Pkts/s Bytes/s Demux
------------------------------------------------------------------------------
token ring 0 288.95 22678 0.0%518.498 552.84 36761 0.0222
...
DEVICE: token ring 0
recv packets: 11074
recv sizes (bytes): avg 66.5 min 52 max 1514 sdev 15.1
recv times (msec): avg 0.008 min 0.005 max 0.029 sdev 0.001
demux times (msec): avg 0.040 min 0.009 max 0.650 sdev 0.028
xmit packets: 5788
xmit sizes (bytes): avg 78.5 min 62 max 1514 sdev 32.0
xmit times (msec): avg 1794.434 min 0.083 max 6443.266 sdev 2013.966
|
Здесь слишком много информации, поэтому трудно понять конкретные детали. Попробуем следующую команду:
netpmon -O so -o /tmp/netpmon_so.txt; sleep 20; trcstop
|
Флаг "-O so" сосредоточит внимание netpmon на трафике на уровне сокета. Также можно увеличить количество информации о java-процессе:
PROCESS: java PID: 12192
reads: 2700
read sizes (bytes): avg 8192.0 min 8192 max 8192 sdev 0.0
read times (msec): avg 184.061 min 12.430 max 2137.371 sdev 259.156
writes: 3000
write sizes (bytes): avg 21.3 min 5 max 56 sdev 17.6
write times (msec): avg 0.081 min 0.054 max 11.426 sdev 0.211
|
Полезно? Сделаем шаг вперед и выясним активность на уровне потока. Для этого нужно добавить ключ "-t" к команде, например:
netpmon -O so -t -o /tmp/netpmon_so_thread.txt; sleep 20; trcstop
|
Теперь генерируемый вывод содержит информацию, специфичную для потоков:
THREAD TID: 114559
reads: 9
read sizes (bytes): avg 8192.0 min 8192 max 8192 sdev 0.0
read times (msec): avg 988.850 min 19.082 max 2106.933 sdev 810.518
writes: 10
write sizes (bytes): avg 21.3 min 5 max 56 sdev 17.6
write times (msec): avg 0.389 min 0.059 max 3.321 sdev 0.977
|
Теперь можно выполнить javadump, выяснить, что это за поток и решить, работает ли он так, как ожидалось, или нет. netpmon особенно полезен для приложений, которые имеют несколько сетевых подключений, – эта команда дает полную картину операций.
filemon
filemon может использоваться для выявления файлов, к которым обращение происходит наиболее часто. Этот инструмент дает весьма полное представление о доступе к файлам и может пригодиться для глубокого исследования после того как vmstat/iostat подтвердили наличие узких мест, связанных с дисками. Это средство также использует трассировку, поэтому оно используется подобно netpmon:
filemon -o /tmp/filemon.log; sleep 60; trcstop
|
При этом генерируется крайне много информации. Некоторыми разделами, которые могут быть полезны, являются:
Most Active Files
------------------------------------------------------------------------
#MBs #opns #rds #wrs file volume:inode
------------------------------------------------------------------------
25.7 83 6589 0 unix /dev/hd2:147514
16.3 1 4175 0 vxe102 /dev/mailv1:581
16.3 1 0 4173 .vxe102.pop /dev/poboxv:62
15.8 1 1 4044 tst1 /dev/mailt1:904
8.3 2117 2327 0 passwd /dev/hd4:8205
3.2 182 810 1 services /dev/hd4:8652
...
------------------------------------------------------------------------
Detailed File Stats
------------------------------------------------------------------------
FILE: /var/spool/mail/v/vxe102 volume: /dev/mailv1 (/var/spool2/mail/v) inode: 581
opens: 1
total bytes xfrd: 17100800
reads: 4175 (0 errs)
read sizes (bytes): avg 4096.0 min 4096 max 4096 sdev 0.0
read times (msec): avg 0.543 min 0.011 max 78.060 sdev 2.753
...
|
Этот инструмент уже упоминался ранее, а его более подробный обзор выходит за рамки этой статьи.
Советы, специфичные для Java
Общие советы для обнаружения узких мест ввода/вывода и сетевого взаимодействия в Java-приложениях сводятся к хорошему дизайну, и уже довольно хорошо были описаны в других статьях цикла. Например, можно посмотреть советы NI004 и NI005.
Советы по настройке, основанные на характеристиках приложения
Рассмотрим различные характеристики типичных приложений. Необходимо определить поведение приложения (исходя из его архитектуры или путем наблюдения) и применить соответствующие советы.
Приложения, интенсивно использующие сеть
Для приложений, интенсивно использующих сеть, нужно с помощью netstat убедиться в том, что что пакеты не отбрасываются и т. д. Разделы netstat и netpmon в AIX 5L Performance Tools Handbook описывают различные хитрости, которые можно применить, если наблюдаются сбои в ходе мониторинга, поэтому эта информация здесь не повторяется.
Если есть подозрение, что пропускная способность сети является узким местом, то можно использовать NI001 для поиска проблем. Если IPv6 не используется, то также может быть полезен NI002.
Если наблюдается разница в производительности приложения на платформе AIX и других платформах и есть подозрение, что это обусловлено некоторыми особенностями настройки сокетов, то нужно обратить внимание на NI004.
RMI-приложения
Если приложение является RMI-клиентом или сервером, можно заметить несколько строк, которые не учитываются в выводе verbosegc. Например, это часть вывода verbosegc RMI-приложения:
<GC(4057): GC cycle started Thu Apr 15 11:14:28 2004
<GC(4057): freed 254510616 bytes, 55% free (453352000/810154496), in 1189 ms>
<GC(4057): mark: 991 ms, sweep: 198 ms, compact: 0 ms>
<GC(4057): refs: soft 0 (age >= 32), weak 2, final 330, phantom 0>
<GC(4057): stop threads time: 10, start threads time: 260>
<GC(4058): GC cycle started Thu Apr 15 11:15:29 2004
<GC(4058): freed 267996504 bytes, 56% free (454445800/810154496), in 1243 ms>
<GC(4058): mark: 1041 ms, sweep: 202 ms, compact: 0 ms>
<GC(4058): refs: soft 0 (age >= 32), weak 0, final 253, phantom 0>
<GC(4059): GC cycle started Thu Apr 15 11:16:31 2004
<GC(4059): freed 248113752 bytes, 56% free (455754152/810154496), in 1386 ms>
<GC(4059): mark: 1095 ms, sweep: 291 ms, compact: 0 ms>
<GC(4059): refs: soft 0 (age >= 32), weak 0, final 263, phantom 0>
|
Циклы GC вызываются почти через каждые 60 секунд, но не вызываются из-за неправильного размещения (Allocation Failure). После того как будет установлено, что приложение не вызывает System.gc() напрямую, можно применить NI003.
Для приложений, интенсивно использующих RMI, следует рассмотреть NI005, но с учетом примечания, приведенного для этого совета.
Приложения, интенсивно использующие диски
Использование iostat и filemon дает возможность найти причины узких мест. Решение, как правило, заключается либо в изменении дизайна приложения так, чтобы оно не зависело от доступа к диску, либо в настройке системы для оптимизации доступа к диску. Поскольку оба эти приема выходят за рамки этой статьи, рекомендуется ознакомиться с инструментами iostat и filemon. Информации, содержащейся в предыдущем разделе, должно быть достаточно для начала исследования.
Общие советы
Приведенный ниже текст ссылается на аргументы командной строки Java (указываются перед именем класса или JAR-файла), известные как "ключи". Например, строка java -mx2g hello имеет один ключ, -mx2g.
NIO001 проверка скорости сетевого соединения
Иногда необходимо провести анализ скорости соединения FTP-сессии, установленной между двумя системами, поэтому можно выполнить следующие команды:
ftp> put "|dd if=/dev/zero bs=32k count=1000" /dev/null
200 PORT command successful.
150 Opening data connection for /dev/null.
1000+0 records in.
1000+0 records out.
226 Transfer complete.
32768000 bytes sent in 130.4 seconds (245.4 Kbytes/s)
local: |dd if=/dev/zero bs=32k count=1000 remote: /dev/null
|
Выше приведен пример теста скорости с попыткой передать 1000 блоков нулей, каждый размером в 32 КБ, который предоставляет простой способ определить пропускную способность соединения между двумя AIX-компьютерами. Приведенный выше пример показывает, что пропускная способность равна 245,4 Кбит/с, что указывает на проблемы с сетью, поскольку оба компьютера AIX оборудованы сетевыми адаптерами 100 Mbps Full-duplex. Если приведенный выше тест показал бы, например, скорость 1.140 E+4 Kbytes/s, то, значит, проблема узких мест в самом приложении. Размер и число блоков можно менять для более точного моделирования поведения Java-приложения.
NI002 стек IPv4
Если в приложении не используется Ipv6, можно установить свойство preferIPv4Stack в true следующим образом:
java -Djava.net.preferIPv4Stack=true <classname>
|
NIO003 удаленный GC
Если приложение является RMI-клиентом или сервером, можно использовать свойства sun.rmi.dgc.client.gcInterval и/или sun.rmi.dgc.server.gcInterval, описанные в документе http://java.sun.com/j2se/1.4.2/docs/guide/rmi/sunrmiproperties.html и доступные в реализации Java от IBM. Значение этих свойств по умолчанию равно 60 секундам, но в зависимости от потребностей программы интервал может быть увеличен до уровня, обеспечивающего снижение избыточности циклов GC.
Примечание. Предупреждение, расположенное в начале упомянутого выше документа, а также риски, связанные с неосвобожденными распределенными объектами, также применимы и к Java от IBM.
NI004 Размер буфера сокета
Если размеры исходящего и входящего буферов задаются явно, то следует помнить, что вызов setSendBufferSize(int) используется только для поиска (hint) источника проблемы. Например, если наблюдается разница в производительности между платформами, нужно добавить вызов getSendBufferSize() и убедиться в том, что hint сработал именно на данной платформе. В последнее время были зафиксированы проблемы производительности приложений на платформе AIX, в коде которых вызывается метод setSendBufferSize(4096). AIX использовала hint, и размер буфера устанавливался в запрошенном размере, в то время как другие платформы просто игнорировали этот вызов, в результате чего производительность приложения на AIX оказывалась низкой. Удаление этого вызова из кода повысила производительность более чем в 4 раза при выполнении приложения на AIX.
В общем, можно не включать вызовы, оптимизирующие стек TCP/IP в приложение, так как сетевой стек AIX прекрасно настроен изначально.
NI005 организация пула соединений
Для приложений, интенсивно использующих RMI, есть возможность объединять потоки в пул для повторного использования существующих подключений вместо создания новых для каждого вызова RMI. Для использования пула потоков нужно установить следующее свойство:
java -Dsun.rmi.transport.tcp.connectionPool=true <classname>
|
и так же можно отключить следующим образом:
java -Dsun.rmi.transport.tcp.noConnectionPool=true <classname>
|
Примечание. Желательно использовать пул потоков только для приложений, интенсивно использующих RMI. В последних версиях Java на AIX (1.3.1 SR7 и 1.4.1 SR2) по умолчанию пул потоков отключен.
Заключение
В этой статье описаны общие средства и методы устранения узких мест в сети и в дисковом вводе/выводе.
Следующая статья завершает серию общими наблюдениями и ссылками на используемые источники информации.
Ресурсы
Об авторах  | |  | Амит Матюр (Amit Mathur) работает в группе IBM Solutions Development, занимаясь в основном IBM ISV и возможностями/производительностью приложений на платформе IBM eServer, а также оказывая поддержку пользователям ISV. Пишет статьи и учебные пособия для developerWorks. Амит имеет более чем 14-летний опыт по поддержке разработчиков программного обеспечения и программирования на C/C++, Java, а также баз данных в UNIX и Linux. Он получил степень бакалавра технических наук в области электроники и телекомунникаций в Индии. Связаться с ним можно по адресу amitmat@us.ibm.com. |
 | |  | Самит Чаула (Sumit Chawla) руководит инициативной группой Java Enablement для IBM eServer (для AIX, Windows и Linux), а также работает консультантом в организации Independent Software Vendors по направлению серверов IBM. Самит имеет степень магистра в области вычислительной техники, обладает более чем 10-летним опытом работы в IT-индустрии, сертифицирован IBM по курсу Application Architect. Он часто пишет статьи для раздела developerWorks eServer. С ним можно связаться по адресу sumitc@us.ibm.com. |
Выскажите мнение об этой странице
|  |