
Я пытаюсь определить причину низкой производительности nfs между двумя виртуальными машинами Xen (клиент и сервер), работающими на одном хосте. В частности, скорость, с которой я могу последовательно читать файл размером 1 ГБ на клиенте, намного ниже ожидаемой на основе измеренной скорости сетевого соединения между двумя виртуальными машинами и измеренной скорости чтения файла непосредственно на сервере. Виртуальные машины работают под управлением Ubuntu 9.04, а сервер использует пакет nfs-kernel-server.
Согласно различным ресурсам по настройке NFS, изменение количества потоков nfsd (в моем случае потоков ядра) может повлиять на производительность. Обычно этот совет формулируется в терминах увеличения количества с 8 по умолчанию на интенсивно используемых серверах. Что я обнаружил в своей текущей конфигурации:
RPCNFSDCOUNT=8
: (по умолчанию): 13,5–30 секунд для загрузки файла размером 1 ГБ на клиенте, т.е. 35–80 МБ/сек
RPCNFSDCOUNT=16
: 18 сек., чтобы загрузить файл 60 МБ/с
RPCNFSDCOUNT=1
: 8-9 секунддля cat файла (!!?!) 125MB/s
RPCNFSDCOUNT=2
: 87s для cat файла 12MB/s
Я должен упомянуть, что экспортируемый мной файл находится на RevoDrive SSD, смонтированном на сервере с использованием Xen PCI-passthrough; на сервере я могу обработать файл менее чем за секунды (> 250 МБ/с). Я сбрасываю кэши на клиенте перед каждым тестом.
Я не хочу оставлять сервер настроенным только на один поток, так как предполагаю, что это не будет работать так хорошо, когда есть несколько клиентов, но я могу неправильно понимать, как это работает. Я повторил тесты несколько раз (изменяя конфигурацию сервера между ними), и результаты довольно последовательны. Поэтому мой вопрос:почему лучшая производительность при использовании 1 потока?
Вот еще несколько вещей, которые я пытался изменить, но это не дало никакого эффекта:
увеличение значений /proc/sys/net/ipv4/ipfrag_low_thresh и /proc/sys/net/ipv4/ipfrag_high_thresh до 512K, 1M со значений по умолчанию 192K, 256K
увеличение значений /proc/sys/net/core/rmem_default и /proc/sys/net/core/rmem_max до 1M со значения по умолчанию 128K
монтирование с параметрами клиента rsize=32768, wsize=32768
Из вывода sar -d я понимаю, что фактический размер считываемых данных, отправляемых на базовое устройство, довольно мал (<100 байт), но это не вызывает проблем при локальном чтении файла на клиенте.
RevoDrive на самом деле предоставляет два устройства "SATA" /dev/sda и /dev/sdb, затем dmraid выбирает фальшивый RAID-0, чередующийся между ними, который я смонтировал в /mnt/ssd, а затем привязал к /export/ssd. Я провел локальные тесты на своем файле, используя оба расположения, и увидел хорошую производительность, упомянутую выше. Если в ответах/комментариях будут запрошены дополнительные подробности, я их добавлю.
решение1
Когда поступает клиентский запрос, он передается одному из потоков, а остальным потокам предлагается выполнить операции опережающего чтения. Самый быстрый способ прочитать файл — это заставить один поток делать это последовательно... Так что для одного файла это излишне, и потоки, по сути, делают больше работы для себя. Но то, что верно для 1 клиента, читающего 1 файл, не обязательно будет верно при развертывании в реальном мире, поэтому придерживайтесь формулы для расчета количества потоков и количества опережающих чтений на основе спецификаций пропускной способности/процессора.