Linux Slow Start: การเปลี่ยนเส้นทาง ip ไม่มีผลกระทบใด ๆ กับหน้าต่างเริ่มต้น


10

ฉันเปลี่ยนหน้าต่างเริ่มต้น tcp ในเครื่องเป็น 10 ตามที่แสดงด้านล่าง

[user@site etc]$ sudo ip route change default via 17.255.209.1 dev eth0  proto static initcwnd 10 

และเปลี่ยนไปtcp_slow_start_after_idleตามที่แสดงด้านล่าง

[user@site etc]$ sudo sysctl -a | grep tcp_slow_start_after_idle
net.ipv4.tcp_slow_start_after_idle = 0

การยืนยันการแสดงเส้นทาง IP ได้รับด้านล่าง

[user@site etc]$ ip route show
default via 17.255.209.1 dev eth0  proto static  initcwnd 10
169.254.0.0/16 dev eth0  scope link  metric 1002
17.255.209.0/24 dev eth0  proto kernel  scope link  src 17.255.209.19

ตอนนี้เมื่อฉันทำการ tcpdump บนเว็บไซต์ฉันไม่เห็นการเปลี่ยนแปลงในหน้าต่างเริ่มต้นด้วยWIN / MSS ที่เหลือ 4เป็นค่าเริ่มต้น 5840/1460 = 4

[user@site etc]$ sudo tcpdump -n -i any 'tcp[tcpflags] & (tcp-syn|tcp-ack) == tcp-syn and port 80'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
11:17:45.048174 IP 21.101.151.198.45873 > 17.255.209.19.http: Flags [S], seq 2008673341, win 5840, options [mss 1460,sackOK,TS val 1724223146 ecr 0,nop,wscale 6], length 0

ขดตีฉันไม่ไปยังหน้าเว็บที่มีการร้องขอรอบ30 KBของข้อมูล

[user@machine ~]$ curl http://www.site.com/js/main.js > /dev/null
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 88212  100 88212    0     0   179k      0 --:--:-- --:--:-- --:--:--  272k

มีอะไรผิดปกติในแนวทางของฉัน

เมล็ด

[user~]$ uname -r
3.0.4x86_64-linode21

ในการอัปเดตนี่คือผลลัพธ์เมื่อฉันลองใช้google.com

[user@site ~]$ sudo tcpdump -n -i any 'tcp[tcpflags] & (tcp-syn|tcp-ack) == tcp-syn and host www.google.com'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
17:20:28.033236 IP 17.255.209.19.42799 > 74.125.127.106.http: Flags [S], seq 3148947324, win 14600, options [mss 1460,sackOK,TS val 193695310 ecr 0,nop,wscale 4], length 0

อย่างที่คุณเห็นว่าWIN / MSS คือ 14600/1460 = 10ในกรณีนี้

ฉันพยายามกดปุ่มเว็บไซต์ของฉันจากเครื่องเซิร์ฟเวอร์ผ่าน curl และนี่คือผลลัพธ์:

[user@site ~]$ sudo tcpdump -n -i any 'tcp[tcpflags] & (tcp-syn|tcp-ack) == tcp-syn and host www.site.com'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
17:25:14.584338 IP 17.255.209.19.35008 > 17.255.209.19.http: Flags [S], seq 3894567470, win 32792, options [mss 16396,sackOK,TS val 193981861 ecr 0,nop,wscale 4], length 0

ชนะ / MSS คือ 32792/16396 = 2ในกรณีนี้


โปรดทราบว่าหากคุณกดปุ่มนี้จากเครื่อง linux คุณจะต้องอยู่ที่ 3.0 เช่นกันจะขุดผ่านซอร์ส / แท็กเพื่อยืนยันรุ่นที่แน่นอน 3 รุ่นที่เปลี่ยนแปลงการติดตั้ง
Sam Saffron

@QuintinPar คุณสามารถเพิ่ม tcpdump output ด้วยการเชื่อมต่อขาออกจากเครื่องทดสอบของคุณได้หรือไม่?
kupson

@kupson ฉันได้อัปเดตคำถามแล้ว
Quintin Par

เท่าที่ฉันรู้ว่าคุณไม่สามารถมีอิทธิพลต่อหน้าต่างเริ่มต้นในการเชื่อมต่อที่เข้ามา การเชื่อมต่อของคุณไปยัง google แสดงว่าคุณได้ตั้งค่า IW เป็น 10 ข้อด้อยของลูปแบ็คนั้นค่อนข้างพิเศษกับ MTU ขนาดใหญ่นั้นอาจมีขีด จำกัด บางอย่างบนหน้าต่างเริ่มต้นในแหล่งเคอร์เนล
kupson

โปรดทราบ 2 สิ่งที่จะกำหนด IW ไคลเอนต์หน้าต่างเริ่มต้นความแออัดสูงสุดและเซิร์ฟเวอร์ IW ชัยชนะที่เล็กกว่า เรียกใช้การทดสอบจาก 2 เครื่องเซิร์ฟเวอร์ควรมี IW ที่ตั้งค่าไว้ตามค่าเริ่มต้นในไคลเอนต์ 3.0 ... และ XP / Vista / Win7 ไม่ จำกัด IW เพื่อให้ลูกค้าดีสำหรับการทดสอบ ไคลเอนต์ Linux 3.0 ยังใช้งานได้ แต่ต้องเป็นเครื่องแยกต่างหาก
Sam Saffron

คำตอบ:


9

ฉันคิดว่าคุณเข้าใจผิดว่า TCP ทำงานอย่างไร

แต่ละแพ็คเก็ตที่ส่งจะโฆษณาหน้าต่างตัวรับสัญญาณ (aka. RWIN) เสมอและตัวเลือกการปรับสัดส่วนดูRFC 1323

ผู้ส่งไม่ได้รับอนุญาตให้ส่งเกินจำนวนข้อมูลที่ระบุใน RWIN โดยไม่ได้รับการตอบรับ ผู้ส่งอาจตัดสินใจกรอกข้อมูล RWIN หรือไม่ขึ้นอยู่กับหน้าต่างแออัด

ดังนั้นจึงมีข้อมูลสองบิตที่เป็นสาธารณะในแพ็คเก็ต TCP RWIN บนเซิร์ฟเวอร์และ RWIN บนไคลเอ็นต์ ตัวเลขทั้งสองนี้เป็นตัวกำหนดขนาดสูงสุดของหน้าต่างความแออัดที่อยู่ทั้งสองด้าน

RWIN บนเซิร์ฟเวอร์นั้นน่าสนใจเมื่อเราพยายามเพิ่มประสิทธิภาพสำหรับการอัพโหลดไฟล์

RWIN บนไคลเอนต์นั้นน่าสนใจเมื่อเราพยายามกำหนดความเร็วในการดาวน์โหลด

ค่าของตัวเลขเหล่านี้ทำให้หน้าต่างแออัดในที่สาธารณะส่วนอื่น

ดังนั้นถ้าฉันมี RWIN 64k หน้าต่างความแออัดบนเซิร์ฟเวอร์อาจเป็นจำนวนใด ๆ ที่ต่ำกว่า 64k

วิธีเดียวที่จะพิจารณาว่าหน้าต่างแออัดที่เกิดขึ้นจริงนั้นคือการนับจำนวนแพ็กเก็ต

ถ้าฉันรู้:

  1. เวลาไปกลับของฉัน (RTT) คือ ~ 200ms
  2. ฉันเพิ่งขอทรัพยากรนั่นคือ 100k
  3. ฉันมี RWIN 64k

ถ้าฉันได้รับ 2 แพ็คเก็ตกลับจากเซิร์ฟเวอร์ที่มีความยาว 1452 ไบต์ภายใน ~ 200ms ก็น่าจะเป็นเพราะหน้าต่างที่มีความแออัดของเซิร์ฟเวอร์นั้นเล็กกว่า 4356 สาเหตุถ้ามันใหญ่กว่า 3 แพ็กเก็ตก็จะถูกส่ง หาก IW ถูกตั้งค่าเป็น 10 ฉันจะเห็นการระเบิดของแพ็คเก็ต 10 รอบเครื่องหมาย 200ms

หากคุณเปลี่ยน IW ของคุณและต้องการยืนยันการเปลี่ยนแปลงคุณต้องนับจำนวนแพ็คเก็ตเพื่อรับขนาดโดยประมาณของหน้าต่างที่ติดขัดบนเซิร์ฟเวอร์

โปรดทราบว่าคุณอาจต้องการดูการสนทนาโดยตรงหลังจาก SYN, SYN-ACK, ACK เพื่อให้แน่ใจว่าคุณไม่ได้ดูบทสนทนาตรงกลาง (ที่หน้าต่างแออัดอาจโตขึ้น)


1
ความแตกต่างระหว่างหน้าต่างความคับคั่งและหน้าต่าง tcp ระบุไว้ใน 20.6 (การเริ่มต้นช้า) ของ TCP / IP Illustrated: "การเริ่มต้นช้าเพิ่มอีกหน้าต่างหนึ่งไปยัง TCP ของผู้ส่ง: หน้าต่างความแออัดที่เรียกว่า cwnd" (ตัวหนาเป็นของฉัน) มีไดอะแกรมลำดับใน 20.7 ที่แสดงสิ่งนี้ขณะเล่นในระหว่างการถ่ายโอนจำนวนมาก
Kyle Brandt

7

ขนาดของหน้าต่างจะเล็กกว่า: ขนาดหน้าต่างเริ่มต้นของเซิร์ฟเวอร์หรือไคลเอนต์ RWIN เนื่องจาก 5840 เป็น RWIN เริ่มต้นสำหรับ Linux 2.6 ดูเหมือนว่าไคลเอ็นต์ของคุณเป็นปัจจัย จำกัด ที่นี่

ลองจากกล่องหน้าต่าง Windows XP มี RWIN 64k ซึ่งเป็นเวอร์ชั่นใหม่กว่า 8k

ที่มา: http://www.cdnplanet.com/blog/tune-tcp-initcwnd-for-optimum-performance/ (ส่วนที่น่าสนใจอยู่ด้านล่างวิดีโอ)

แก้ไข: ขยายคำตอบเพื่อให้ชัดเจนยิ่งขึ้น:

  • ใน TCP handshake ไคลเอ็นต์จะส่งแพ็กเก็ต SYN ไปยังเซิร์ฟเวอร์เพื่อส่งขนาดหน้าต่างสูงสุดที่อนุญาต (เมื่อเอาต์พุต tcpdump ของคุณแสดงสิ่งเหล่านี้คือ 5840 ไบต์)
  • ตอนนี้เซิร์ฟเวอร์ตอบกลับด้วย SYN ACK และขนาดหน้าต่างที่ต้องการยอมรับ ขนาดหน้าต่างนี้สามารถเล็กกว่าที่ลูกค้าเสนอเท่านั้นไม่ใหญ่กว่า ไม่ว่าเซิร์ฟเวอร์จะถูกกำหนดค่าอย่างไรก็ไม่สามารถมีขนาดหน้าต่างใหญ่กว่า 5840 ไบต์ด้วยไคลเอ็นต์นั้น
  • ลูกค้าส่งคืน ACK และพวกเขาแลกเปลี่ยนข้อมูลอย่างมีความสุขตลอดไป

แก้ไข 2: tcpdumps ที่เพิ่มลงในคำถามจะแสดงเซิร์ฟเวอร์ที่เปิดการเชื่อมต่อไปยัง google และตัวเองทำหน้าที่เป็นลูกค้า


หน้าต่างเริ่มต้น (ที่เสนอในแพ็คเก็ต SYN) คือ 5840 มันเป็นแพ็กเก็ตแรกและเครื่องส่งไม่รู้อะไรเลยเกี่ยวกับตัวรับสัญญาณในเวลานี้ (ฉันทดสอบด้วย "ip route flush cache")
kupson

เอ่อ, 17.255.209.0 คือซับเน็ตของคุณใช่ไหม? แพ็คเก็ตที่คุณเห็นคือจาก 21.101.151.198.45873 ถึง 17.255.209.19.http ฉันไม่มีความเชี่ยวชาญในผลลัพธ์ tcpdump แต่สำหรับฉันนี้อ่าน: สวัสดีเซิร์ฟเวอร์ฉันเป็นลูกค้าของคุณฉันชอบ 5840 ไบต์ windows :) แพ็คเก็ตถัดไปจะเป็นเซิร์ฟเวอร์ที่ตอบสนองกับ ACK 5840 นั้นยอดเยี่ยม :)
คน

เพียงเพื่อเน้นฉันคิดว่าคุณมีวิธีที่ผิด: เครื่องส่งแรกคือลูกค้าที่เปิดการเชื่อมต่อไม่ใช่เซิร์ฟเวอร์ของคุณ เป็นไคลเอนต์ที่เสนอหน้าต่าง 5840 ไบต์ เซิร์ฟเวอร์ไม่สามารถเสนอขนาดหน้าต่างที่ใหญ่กว่าได้เพียงเล็กกว่านั้น
คน

1
ฉันไม่ใช่ผู้เขียนดั้งเดิมของคำถามนี้ ฉันทดสอบ (พร้อมผลลัพธ์ที่คล้ายกัน) ในสภาพแวดล้อมการทดสอบของตัวเองและไม่สามารถเปลี่ยนแปลงได้ ขนาดหน้าต่างเริ่มต้นที่ติดขัด (initcwnd) ไม่มีส่วนเกี่ยวข้องกับการเชื่อมต่ออื่น ๆ
kupson

ฉันไม่รู้การตั้งค่าของคุณ โปสเตอร์ต้นฉบับถามว่าทำไมถึงเพิ่มขนาดหน้าต่างเริ่มต้นบนเซิร์ฟเวอร์การเชื่อมต่อทดสอบของเขามีเพียงขนาดหน้าต่าง 5840 ไบต์ คำตอบคือ: เนื่องจากลูกค้าที่เขาทดสอบด้วยไม่อนุญาตให้มีขนาดหน้าต่างใหญ่ขึ้น ฉันไม่สามารถแสดงความคิดเห็นในการตั้งค่าอื่น ๆ หรืออาจมีปัญหา / ข้อบกพร่องอื่น ๆ ที่มีแนวคิดโดยทั่วไป
คน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.