J'ai eu du mal à résoudre un problème de performances avec un partage SMB / CIFS lors de l'exécution de petites écritures.
Tout d'abord, permettez-moi de décrire ma configuration réseau actuelle:
Serveur
- Synology DS215j (avec prise en charge SMB3 activée)
Clients (même ordinateur Gig-E câblé à double démarrage)
- Ubuntu 14.04.5 LTS, Trusty Tahr
- 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
Je teste actuellement les petites performances d'écriture avec le programme suivant écrit en C ++ (sur GitHub ici ):
#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;
}
Configuration de montage Linux:
//192.168.1.10/nas-main on /mnt/nas-main type cifs (rw,noexec,nodev)
Exécution du programme sur Linux (sortie réseau maximale à ~ 100 Mbps):
$ time ./nas-write-test /mnt/nas-main/home/will/test.txt
real 0m0.965s
user 0m0.148s
sys 0m0.672s
Instantané PCAP montrant la segmentation de plusieurs lignes en un seul paquet TCP:
Exécution du programme sous Windows, mesurée par 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
Instantané PCAP sous Windows montrant une seule ligne par demande d'écriture SMB:
Ce même programme prend environ 10 minutes (~ 2,3 Mbps) sous Windows. De toute évidence, Windows PCAP affiche une conversation SMB très bruyante avec une efficacité de charge utile très faible.
Existe-t-il des paramètres sous Windows qui peuvent améliorer les performances d'écriture de petite taille? Il semble qu'en regardant les captures de paquets, Windows ne tamponne pas correctement les écritures et envoie immédiatement les données une ligne à la fois. Alors que sous Linux, les données sont fortement tamponnées et ont donc des performances bien supérieures. Faites-moi savoir si les fichiers PCAP seraient utiles et je peux trouver un moyen de les télécharger.
Mise à jour 27/10/16:
Comme mentionné par @sehafoc, j'ai réduit le max protocol
paramètre des serveurs Samba à SMB1 avec les éléments suivants:
max protocol=NT1
Le paramètre ci-dessus a entraîné exactement le même comportement.
J'ai également supprimé la variable de Samba en créant un partage sur une autre machine Windows 10, et elle présente également le même comportement que le serveur Samba, donc je commence à croire qu'il s'agit d'un bogue de mise en cache d'écriture avec les clients Windows en général.
Mise à jour: 10/06/17:
Capture de paquets Linux complète (14 Mo)
Capture de paquets Windows complète (375 Mo)
Mise à jour: 10/12/17:
J'ai également configuré un partage NFS et Windows écrit également sans tampon pour cela. Donc, c'est certainement un problème sous-jacent de client Windows pour autant que je sache, ce qui est vraiment regrettable: - /
Toute aide serait appréciée!
Je n'ai pas assez de réputation pour laisser un commentaire (ce qui je pense serait mieux vu le niveau de vérification de cette réponse).
Je remarque qu'une grande différence dans votre trace de niveau Linux vs Windows est que vous utilisez SMB1 sous Linux et SMB2 sous Windows. Peut-être que le mécanisme de verrouillage par lots fonctionne mieux dans SMB1 samba que l'implémentation de bail exclusif SMB2. Dans les deux cas, cela devrait permettre une certaine mise en cache côté client.
1) Essayez peut-être de définir un niveau de protocole max inférieur dans Samba pour essayer des fenêtres avec SMB1 2) Validez que des oplocks ou des baux exclusifs sont supprimés
J'espère que cela t'aides :)
la source
Les performances des opérations de fichiers distants, telles que la lecture / écriture, à l'aide du protocole SMB peuvent être affectées par la taille des tampons alloués par les serveurs et les clients. La taille de la mémoire tampon détermine le nombre d'aller-retour nécessaires pour envoyer une quantité fixe de données. Chaque fois que des demandes et des réponses sont envoyées entre le client et le serveur, le temps nécessaire est au moins égal à la latence entre les deux côtés, ce qui pourrait être très important dans le cas d'un réseau étendu (WAN).
Tampon SMB - Le MaxBufferSize peut être configuré via le paramètre de registre suivant:
Type de données:
REG_DWORD
Plage: 1024 à 65535 (choisissez une valeur selon vos besoins au-dessus de 5000)
MAIS SMB SIGNING affecte la taille de tampon maximale autorisée. Par conséquent, nous devons également désactiver la signature SMB pour atteindre notre objectif. Le registre suivant doit être créé à la fois côté serveur et si possible côté client également.
Nom de la valeur:
EnableSecuritySignature
Type de données:
REG_DWORD
Données: 0 (désactiver), 1 (activer)
la source
Phénomène intéressant. Voici ce que j'essaierais - je ne sais pas si cela aide vraiment. Si c'était ma machine, je regarderais longuement les compteurs SMB. L' un d'eux va montrer la cause.
Plus de choses à essayer
Ajouter plus de fils de travail
Dans le cas où le SMB_RDR obens une demande d'E / S d'écriture par ligne (ce qui ne devrait pas se produire ici), il peut être utile d'ajouter des threads au moteur d'exécution.
Définissez "AdditionalCriticalWorkerThreads" sur 2, puis sur 4.
La valeur par défaut est 0, ce qui signifie qu'aucun thread de travail critique supplémentaire n'est ajouté. Ce qui est généralement correct. Cette valeur affecte le nombre de threads que le cache du système de fichiers utilise pour les demandes en lecture anticipée et en écriture différée. Augmenter cette valeur peut permettre plus d'E / S en file d'attente dans le sous-système de stockage (ce qui est bien, lorsque vous voulez écrire ligne par ligne), mais c'est plus coûteux en CPU.
Ajouter plus de longueur de file d'attente
L'augmentation de la valeur "AdditionalCriticalWorkerThreads" augmente le nombre de threads que le serveur de fichiers peut utiliser pour traiter les demandes simultanées .
La valeur par défaut est 20. Une indication que la valeur peut devoir être augmentée est si les files d'attente de travail SMB2 deviennent très grandes (perfcounter 'Server Work Queues \ Queue Length \ SMB2 *'. Doit être <100).
la source