मैं सोच रहा हूं कि एनएफएस वी 4 एनएफएस वी 3 की तुलना में इतना तेज क्यों होगा और अगर वी 3 पर कोई पैरामीटर है जो कि ट्विक किया जा सकता है।
मैं एक फाइल सिस्टम माउंट करता हूं
sudo mount -o 'rw,bg,hard,nointr,rsize=1048576,wsize=1048576,vers=4' toto:/test /test
और फिर चला
dd if=/test/file of=/dev/null bs=1024k
मैं 200-400MB / s पढ़ सकता हूं, लेकिन जब मैं vers=3
dd में संस्करण बदलता हूं , रिमाउंट करता हूं और फिर से चलाता हूं तो मुझे केवल 90MB / s मिलते हैं । मैं जिस फ़ाइल से पढ़ रहा हूं वह एनएफएस सर्वर पर एक मेमोरी फाइल है। कनेक्शन के दोनों किनारे सोलारिस हैं और 10GbE NIC हैं। मैं सभी परीक्षणों के बीच रीमाउंट करके किसी भी क्लाइंट साइड कैशिंग से बचता हूं। मैं dtrace
सर्वर पर यह देखने के लिए उपयोग करता था कि एनएफएस के माध्यम से कितनी तेजी से डेटा परोसा जा रहा है। दोनों v3 और v4 के लिए मैं बदल गया:
nfs4_bsize
nfs3_bsize
डिफ़ॉल्ट 32K से 1M (v4 पर मैंने अधिकतम 150K / 32K के साथ अधिकतम किया है) मैंने ट्विक करने की कोशिश की है
- nfs3_max_threads
- clnt_max_conns
- nfs3_async_clusters
v3 के प्रदर्शन को बेहतर बनाने के लिए, लेकिन नहीं।
V3 पर अगर मैं चार समानांतर दौड़ता हूँ, तो dd
थ्रूपुट 90MB / s से 70-80MB तक नीचे चला जाता है जो मुझे विश्वास दिलाता है कि समस्या कुछ साझा संसाधन है और यदि ऐसा है, तो मैं सोच रहा हूँ कि यह क्या है और अगर मैं इसे बढ़ा सकता हूं संसाधन।
विंडो का आकार पाने के लिए dtrace कोड:
#!/usr/sbin/dtrace -s
#pragma D option quiet
#pragma D option defaultargs
inline string ADDR=$$1;
dtrace:::BEGIN
{
TITLE = 10;
title = 0;
printf("starting up ...\n");
self->start = 0;
}
tcp:::send, tcp:::receive
/ self->start == 0 /
{
walltime[args[1]->cs_cid]= timestamp;
self->start = 1;
}
tcp:::send, tcp:::receive
/ title == 0 &&
( ADDR == NULL || args[3]->tcps_raddr == ADDR ) /
{
printf("%4s %15s %6s %6s %6s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s\n",
"cid",
"ip",
"usend" ,
"urecd" ,
"delta" ,
"send" ,
"recd" ,
"ssz" ,
"sscal" ,
"rsz",
"rscal",
"congw",
"conthr",
"flags",
"retran"
);
title = TITLE ;
}
tcp:::send
/ ( ADDR == NULL || args[3]->tcps_raddr == ADDR ) /
{
nfs[args[1]->cs_cid]=1; /* this is an NFS thread */
this->delta= timestamp-walltime[args[1]->cs_cid];
walltime[args[1]->cs_cid]=timestamp;
this->flags="";
this->flags= strjoin((( args[4]->tcp_flags & TH_FIN ) ? "FIN|" : ""),this->flags);
this->flags= strjoin((( args[4]->tcp_flags & TH_SYN ) ? "SYN|" : ""),this->flags);
this->flags= strjoin((( args[4]->tcp_flags & TH_RST ) ? "RST|" : ""),this->flags);
this->flags= strjoin((( args[4]->tcp_flags & TH_PUSH ) ? "PUSH|" : ""),this->flags);
this->flags= strjoin((( args[4]->tcp_flags & TH_ACK ) ? "ACK|" : ""),this->flags);
this->flags= strjoin((( args[4]->tcp_flags & TH_URG ) ? "URG|" : ""),this->flags);
this->flags= strjoin((( args[4]->tcp_flags & TH_ECE ) ? "ECE|" : ""),this->flags);
this->flags= strjoin((( args[4]->tcp_flags & TH_CWR ) ? "CWR|" : ""),this->flags);
this->flags= strjoin((( args[4]->tcp_flags == 0 ) ? "null " : ""),this->flags);
printf("%5d %14s %6d %6d %6d %8d \ %-8s %8d %6d %8d %8d %8d %12d %s %d \n",
args[1]->cs_cid%1000,
args[3]->tcps_raddr ,
args[3]->tcps_snxt - args[3]->tcps_suna ,
args[3]->tcps_rnxt - args[3]->tcps_rack,
this->delta/1000,
args[2]->ip_plength - args[4]->tcp_offset,
"",
args[3]->tcps_swnd,
args[3]->tcps_snd_ws,
args[3]->tcps_rwnd,
args[3]->tcps_rcv_ws,
args[3]->tcps_cwnd,
args[3]->tcps_cwnd_ssthresh,
this->flags,
args[3]->tcps_retransmit
);
this->flags=0;
title--;
this->delta=0;
}
tcp:::receive
/ nfs[args[1]->cs_cid] && ( ADDR == NULL || args[3]->tcps_raddr == ADDR ) /
{
this->delta= timestamp-walltime[args[1]->cs_cid];
walltime[args[1]->cs_cid]=timestamp;
this->flags="";
this->flags= strjoin((( args[4]->tcp_flags & TH_FIN ) ? "FIN|" : ""),this->flags);
this->flags= strjoin((( args[4]->tcp_flags & TH_SYN ) ? "SYN|" : ""),this->flags);
this->flags= strjoin((( args[4]->tcp_flags & TH_RST ) ? "RST|" : ""),this->flags);
this->flags= strjoin((( args[4]->tcp_flags & TH_PUSH ) ? "PUSH|" : ""),this->flags);
this->flags= strjoin((( args[4]->tcp_flags & TH_ACK ) ? "ACK|" : ""),this->flags);
this->flags= strjoin((( args[4]->tcp_flags & TH_URG ) ? "URG|" : ""),this->flags);
this->flags= strjoin((( args[4]->tcp_flags & TH_ECE ) ? "ECE|" : ""),this->flags);
this->flags= strjoin((( args[4]->tcp_flags & TH_CWR ) ? "CWR|" : ""),this->flags);
this->flags= strjoin((( args[4]->tcp_flags == 0 ) ? "null " : ""),this->flags);
printf("%5d %14s %6d %6d %6d %8s / %-8d %8d %6d %8d %8d %8d %12d %s %d \n",
args[1]->cs_cid%1000,
args[3]->tcps_raddr ,
args[3]->tcps_snxt - args[3]->tcps_suna ,
args[3]->tcps_rnxt - args[3]->tcps_rack,
this->delta/1000,
"",
args[2]->ip_plength - args[4]->tcp_offset,
args[3]->tcps_swnd,
args[3]->tcps_snd_ws,
args[3]->tcps_rwnd,
args[3]->tcps_rcv_ws,
args[3]->tcps_cwnd,
args[3]->tcps_cwnd_ssthresh,
this->flags,
args[3]->tcps_retransmit
);
this->flags=0;
title--;
this->delta=0;
}
आउटपुट जैसा दिखता है (इस विशेष स्थिति से नहीं):
cid ip usend urecd delta send recd ssz sscal rsz rscal congw conthr flags retran
320 192.168.100.186 240 0 272 240 \ 49232 0 1049800 5 1049800 2896 ACK|PUSH| 0
320 192.168.100.186 240 0 196 / 68 49232 0 1049800 5 1049800 2896 ACK|PUSH| 0
320 192.168.100.186 0 0 27445 0 \ 49232 0 1049800 5 1049800 2896 ACK| 0
24 192.168.100.177 0 0 255562 / 52 64060 0 64240 0 91980 2920 ACK|PUSH| 0
24 192.168.100.177 52 0 301 52 \ 64060 0 64240 0 91980 2920 ACK|PUSH| 0
कुछ हेडर
usend - unacknowledged send bytes
urecd - unacknowledged received bytes
ssz - send window
rsz - receive window
congw - congestion window
dd के v3 और v4 और तुलना करने पर स्नूप की योजना बनाने पर योजना। पहले ही कर चुके हैं, लेकिन बहुत अधिक ट्रैफ़िक था और मैंने कैश्ड फ़ाइल के बजाय डिस्क फ़ाइल का उपयोग किया, जिसने समय की तुलना को व्यर्थ बना दिया। कैश्ड डेटा के साथ अन्य स्नूप चलाएगा और बक्से के बीच कोई अन्य ट्रैफ़िक नहीं होगा। TBD
इसके अतिरिक्त नेटवर्क वालों का कहना है कि कनेक्शनों पर ट्रैफिक शेपिंग या बैंडविड्थ सीमा नहीं है।