Я изо всех сил пытался исправить проблему производительности с общим ресурсом SMB / CIFS при выполнении небольших записей.
Сначала позвольте мне описать мою текущую настройку сети:
сервер
- Synology DS215j (с включенной поддержкой SMB3)
Клиенты (тот же компьютер с двойной загрузкой проводной Gig-E)
- Ubuntu 14.04.5 LTS, Трасти Тар
- Windows 8.1
smb.conf
[global]
printcap name=cups
winbind enum groups=yes
include=/var/tmp/nginx/smb.netbios.aliases.conf
socket options=TCP_NODELAY IPTOS_LOWDELAY SO_RCVBUF=65536 SO_SNDBUF=65536
security=user
local master=no
realm=*
passdb backend=smbpasswd
printing=cups
max protocol=SMB3
winbind enum users=yes
load printers=yes
workgroup=WORKGROUP
В настоящее время я тестирую небольшую производительность записи с помощью следующей программы, написанной на C ++ (на GitHub здесь ):
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;
int main(int argc, char* argv[])
{
ofstream outFile(argv[1]);
for(int i = 0; i < 1000000; i++)
{
outFile << "Line #" << i << endl;
}
outFile.flush();
outFile.close();
return 0;
}
Конфигурация монтирования Linux:
//192.168.1.10/nas-main on /mnt/nas-main type cifs (rw,noexec,nodev)
Время выполнения программы в Linux (максимальная производительность сети составляет ~ 100 Мбит / с):
$ time ./nas-write-test /mnt/nas-main/home/will/test.txt
real 0m0.965s
user 0m0.148s
sys 0m0.672s
Снимок PCAP, показывающий разбиение множества строк на один пакет TCP:
Время выполнения программы в Windows, измеренное PowerShell:
> Measure-Command {start-process .\nas-write-test.exe -argumentlist "Z:\home\will\test-win.txt" -wait}
Days : 0
Hours : 0
Minutes : 9
Seconds : 29
Milliseconds : 316
Ticks : 5693166949
TotalDays : 0.00658931359837963
TotalHours : 0.158143526361111
TotalMinutes : 9.48861158166667
TotalSeconds : 569.3166949
TotalMilliseconds : 569316.6949
Снимок PCAP в Windows, показывающий одну строку на запрос записи SMB:
Эта же программа занимает около 10 минут (~ 2,3 Мбит / с) в Windows. Очевидно, что Windows PCAP показывает очень шумный разговор SMB с очень низкой эффективностью полезной нагрузки.
Есть ли в Windows какие-либо настройки, которые могут улучшить производительность записи при небольших объемах записи? Из анализа захвата пакетов видно, что Windows не буферизует записи должным образом и немедленно отправляет данные по одной строке за раз. Принимая во внимание, что в Linux данные сильно буферизируются и, таким образом, имеют гораздо более высокую производительность. Дайте мне знать, будут ли полезны файлы PCAP, и я найду способ загрузить их.
Обновление 27.10.16:
Как уже упоминалось @sehafoc, я сократил max protocol
настройку серверов Samba до SMB1 с помощью следующего:
max protocol=NT1
Вышеуказанная настройка привела к точно такому же поведению.
Я также удалил переменную Samba, создав общий ресурс на другом компьютере с Windows 10, и он также демонстрирует то же поведение, что и сервер Samba, поэтому я начинаю верить, что это ошибка кэширования записи для клиентов Windows в целом.
Обновление: 10/06/17:
Полный захват пакетов Linux (14 МБ)
Полный захват пакетов Windows (375 МБ)
Обновление: 10/12/17:
Я также настроил общий ресурс NFS, и Windows также пишет без буферизации для этого. Итак, насколько я могу судить, это определенно основная проблема клиента Windows, что, безусловно, вызывает сожаление: - /
Любая помощь будет оценена!
У меня недостаточно репутации, чтобы оставлять комментарии (что, я думаю, было бы лучше, учитывая уровень проверки этого ответа).
Я заметил, что одна большая разница в вашей трассировке уровня Linux и Windows заключается в том, что вы используете SMB1 в Linux и SMB2 в Windows. Возможно, механизм пакетной блокировки работает лучше в samba SMB1, чем реализация эксклюзивной аренды SMB2. В обоих случаях это должно позволить некоторое количество кэширования на стороне клиента.
1) Возможно, попробуйте установить более низкий максимальный уровень протокола в Samba, чтобы опробовать окна с SMB1. 2) Проверить, что исключены эксклюзивные блокировки или аренды.
Надеюсь это поможет :)
источник
На производительность удаленных файловых операций, таких как чтение / запись, с использованием протокола SMB, может влиять размер буферов, выделяемых серверами и клиентами. Размер буфера определяет количество циклов, необходимых для отправки фиксированного объема данных. Каждый раз, когда запросы и ответы отправляются между клиентом и сервером, время, которое требуется, равно как минимум задержке между обеими сторонами, что может быть очень значительным в случае глобальной сети (WAN).
SMB-буфер - MaxBufferSize можно настроить с помощью следующего параметра реестра:
Тип данных:
REG_DWORD
Диапазон: от 1024 до 65535 (выберите значение согласно вашему требованию выше 5000)
НО SMB SIGNING влияет на максимально допустимый размер буфера. Таким образом, нам нужно отключить подпись SMB, чтобы достичь нашей цели. Следующий реестр должен быть создан как на стороне сервера, так и, если возможно, на стороне клиента.
Имя значения:
EnableSecuritySignature
Тип данных:
REG_DWORD
Данные: 0 (отключить), 1 (включить)
источник
Интересное явление. Вот что я бы попробовал - я понятия не имею, действительно ли это помогает. Если бы это была моя машина, я бы внимательно следил за перфокастерами SMB. Один из них будет показывать причину.
Больше вещей, чтобы попробовать
Добавить больше рабочих потоков
В случае, если SMB_RDR обрабатывает один запрос ввода-вывода на строку (что не должно происходить здесь), это может помочь добавить некоторые потоки в механизм исполнения.
Установите «AdditionalCriticalWorkerThreads» на 2, затем на 4.
По умолчанию 0, что означает, что никакие дополнительные критические рабочие потоки ядра не добавляются. Что обычно нормально. Это значение влияет на количество потоков, которые кэш файловой системы использует для запросов на чтение и запись. Увеличение этого значения может позволить увеличить количество операций ввода-вывода в очереди в подсистеме хранения (что хорошо, когда вы хотите писать построчно), но это более затратно для ЦП.
Добавить больше Длина очереди
Увеличение значения AdditionalCriticalWorkerThreads увеличивает количество потоков, которые файловый сервер может использовать для обслуживания одновременных запросов.
Значение по умолчанию - 20. Указание на то, что значение может потребоваться увеличить, - это если рабочие очереди SMB2 становятся очень большими (perfcounter «Серверные рабочие очереди \ Длина очереди \ SMB2 *». Должен быть <100).
источник