Поток Java не запускается - низкая загрузка процессора, но высокая IO-ожидание

Ubuntu 12.04 LTS

Java -версия
Java -версия "1.6.0_38"
Java (TM) SE Runtime Environment (сборка 1.6.0_38-b05)
Java HotSpot (TM) 64-разрядная серверная виртуальная машина (сборка 20.13-b02, смешанный режим)

4-х ядерный процессор - немного серверного оборудования Dell

10 потоков время от времени выполняют "тяжелую" работу в течение нескольких минут. В другие периоды они ничего не делают.
Предполагается, что 1 поток просыпается каждые 5 (или около того) секунд и отправляет быстрый пинг по сети другому процессу. Это работает хорошо, пока остальные 10 потоков ничего не делают, но когда остальные 10 потоков выполняют "тяжелую" работу, он никогда (или очень редко) не запускается и не отправляет свой пинг.

Я мог бы понять это, если бы эта "тяжелая" работа требовала значительных ресурсов процессора. Но во время такой "тяжелой" работы топ говорит что-то вроде 50-100% IO-ожидания, но около 1% загрузки процессора. Профилирование показывает, что большая часть времени, потраченного 10 потоками, тратится (я думаю, на ожидание) в каком-то вызове NIO. Все это складывается, и это отчасти ожидаемо, потому что большая часть работы заключается в чтении файлов с диска.

Что я не понимаю, так это то, что во время такой "тяжелой" работы 1 поток, выполняющий эхо-запросы, не запускается. Как это можно объяснить, когда top показывает 1% загрузки ЦП и кажется (профилирование и топ), что 10 потоков тратят большую часть своего времени в ожидании ввода-вывода. Разве 1-нить ping не должен получать время выполнения, когда другие потоки ожидают ввода-вывода?

Приоритет потока Java одинаков для всех 11 потоков.

Распространение нескольких выходов здесь и там в 10 потоках, кажется, решает (или понижает) проблему, но я просто не понимаю, почему поток ping не может работать без выходов, когда другие потоки не делают много, но ждут для IO.

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ 05.03.2014

Я воспроизвел проблему в более простой настройке - хотя и не очень простой (вам нужно будет узнать, как установить сервер Apache Zookeeper, но она довольно проста - я могу предоставить информацию позже)

Найти проект Eclipse Kepler можно здесь (maven - сборка по "пакету mvn"): https://dl.dropboxusercontent.com/u/25718039/io-test.zip
Найти бинарный файл здесь: https://dl.dropboxusercontent.com/u/25718039/io-test-1.0-SNAPSHOT-jar-with-dependencies.jar

Запустите на компьютере сервер Apache ZooKeeper 3.4.5 (на порту 2181). На другом отдельном компьютере (здесь у меня Ubuntu 12.04 LTS и т. Д., Как описано выше), запустите двоичный файл следующим образом (сначала создайте папку io-test-files - требуется 50 ГБ свободного места)

nohup java -cp io-test-1.0-SNAPSHOT-jar-with-dependencies.jar dk.designware.io_test.ZKIOTest ./io-test-files 10 1024 5000000 IP-of-ZooKeeper-server:2181 > ./io-test-files/stdouterr.txt 2>&1 &

Сначала он создает 10 5 ГБ файлов (50 ГБ - это намного больше, чем ОЗУ компьютера, поэтому не особо помогает файловый кеш ОС), затем запускает клиент ZooKeeper (который должен поддерживать соединение с сервером ZooKeeper, регулярно отправляя пинг / тактовые импульсы) Затем 10 потоков делают произвольный доступ к 10 файлам, создавая много дискового ввода-вывода, но на самом деле не используют процессор. Я вижу, что клиент ZooKeeper в конечном итоге теряет свое соединение ("состояние Zk" перестает говорить "CONNECTED" - в stdouterr.txt), и это в основном то, чего я не понимаю. Клиентский поток ZooKeeper только хочет послать крошечное сердцебиение с интервалом в несколько секунд, и только если он не сможет сделать это в течение 20 секунд, он потеряет соединение. Я ожидаю, что у него будет легкий доступ к процессору, потому что все остальные потоки в основном только ожидают дискового ввода-вывода.

Во время теста я вижу следующее, используя "top"

  • Очень высокая "Средняя нагрузка". Выше 10, что я не понимаю, потому что в основном только 10 потоков делают что-то. Я также подумал, что "Средняя нагрузка" подсчитывает только потоки, которые действительно хотят делать реальные вещи на процессоре (не включая ожидание ввода-вывода), но согласно http://en.wikipedia.org/wiki/Load_%28computing%29 Linux также учитывает "непрерывный сон", включая потоки, ожидающие ввода-вывода. Но я действительно не надеюсь / не думаю, что это помешает другим потокам, у которых есть реальные дела, получить доступ к процессору
  • Очень высокий% wa, но почти нет% sy и% us на процессорах

Вот вывод одного из моих прогонов: https://dl.dropboxusercontent.com/u/25718039/io-test-output.txt

0 ответов

Другие вопросы по тегам