เรามีโครงสร้างพื้นฐานกระจายอยู่ในสถานที่สำคัญไม่กี่แห่งทั่วโลก - สิงคโปร์ลอนดอนและลอสแองเจลิส RTT ระหว่างสถานที่สองแห่งนั้นมีระยะ> มากกว่า 150 มิลลิวินาที
เมื่อเร็ว ๆ นี้เราได้อัปเกรดเซิร์ฟเวอร์ทั้งหมดเพื่อใช้ลิงก์ 1Gbps (จาก 100Mbps) เราได้ทำการทดสอบบน TCP ระหว่างเซิร์ฟเวอร์ในสถานที่ต่างกันและได้เห็นผลลัพธ์ที่น่าประหลาดใจ ผลลัพธ์เหล่านี้สามารถทำซ้ำได้อย่างสมบูรณ์
- ลอสแองเจลิส (100Mbps) ถึงลอนดอน (100Mbps): ~ 96Mbps ปริมาณงาน
- ลอสแองเจลิส (100Mbps) ถึงลอนดอน (1Gbps): ~ 96Mbps ปริมาณงาน
- ลอสแองเจลิส (1Gbps) ถึงลอนดอน (100Mbps): ความเร็ว10-40Mbps (ระเหย)
- ลอสแองเจลิส (1Gbps) ถึงลอนดอน (1Gbps): ความเร็ว10-40Mbps (ระเหย)
- ลอสแองเจลิส (1Gbps) ถึงลอสแองเจลิส (1Gbps):> อัตราความเร็ว 900Mbps
ปรากฏว่าเมื่อใดก็ตามที่ผู้ส่งทำงานที่ 1Gbps ปริมาณงานของเราจะได้รับผลกระทบอย่างมากจากลิงก์ที่ยาว
วิธีการทดสอบก่อนหน้านี้ง่ายมาก - ฉันแค่ใช้ cURL เพื่อดาวน์โหลดไบนารี่ 1GB จากเซิร์ฟเวอร์เป้าหมาย (ดังนั้นในกรณีข้างต้นไคลเอนต์ cURL ทำงานบนเซิร์ฟเวอร์ลอนดอนและดาวน์โหลดจาก LA เพื่อให้ LA เป็นผู้ส่ง) . นี่คือการใช้การเชื่อมต่อ TCP เดียวแน่นอน
ทำซ้ำการทดสอบเดียวกันผ่าน UDP โดยใช้ iperf ปัญหาจะหายไป!
- ลอสแองเจลิส (100Mbps) ถึงลอนดอน (100Mbps): ~ 96Mbps ปริมาณงาน
- ลอสแองเจลิส (100Mbps) ถึงลอนดอน (1Gbps): ~ 96Mbps ปริมาณงาน
- ลอสแองเจลิส (1Gbps) ถึงลอนดอน (100Mbps): ~ 96Mbps ปริมาณงาน
- ลอสแองเจลิส (1Gbps) ถึงลอนดอน (1Gbps):> 250Mbps ปริมาณงาน
สิ่งนี้ชี้ไปที่ปัญหาการกำหนดค่า TCP หรือ NIC / พอร์ตบางอย่างในสายตาของฉัน
เซิร์ฟเวอร์ทั้งสองกำลังเรียกใช้ CentOS 6.x ด้วย TCP ลูกบาศก์ ทั้งคู่มีหน้าต่างส่งและรับ TCP สูงสุด 8MB และมีการประทับเวลา TCP และเปิดใช้งานการตอบรับเลือก ใช้การกำหนดค่า TCP เดียวกันในทุกกรณีทดสอบ การกำหนดค่า TCP แบบเต็มด้านล่าง:
net.core.somaxconn = 128
net.core.xfrm_aevent_etime = 10
net.core.xfrm_aevent_rseqth = 2
net.core.xfrm_larval_drop = 1
net.core.xfrm_acq_expires = 30
net.core.wmem_max = 8388608
net.core.rmem_max = 8388608
net.core.wmem_default = 131072
net.core.rmem_default = 131072
net.core.dev_weight = 64
net.core.netdev_max_backlog = 1000
net.core.message_cost = 5
net.core.message_burst = 10
net.core.optmem_max = 20480
net.core.rps_sock_flow_entries = 0
net.core.netdev_budget = 300
net.core.warnings = 1
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_sack = 1
net.ipv4.tcp_retrans_collapse = 1
net.ipv4.tcp_syn_retries = 5
net.ipv4.tcp_synack_retries = 5
net.ipv4.tcp_max_orphans = 262144
net.ipv4.tcp_max_tw_buckets = 262144
net.ipv4.tcp_keepalive_time = 7200
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_intvl = 75
net.ipv4.tcp_retries1 = 3
net.ipv4.tcp_retries2 = 15
net.ipv4.tcp_fin_timeout = 60
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_abort_on_overflow = 0
net.ipv4.tcp_stdurg = 0
net.ipv4.tcp_rfc1337 = 0
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_orphan_retries = 0
net.ipv4.tcp_fack = 1
net.ipv4.tcp_reordering = 3
net.ipv4.tcp_ecn = 2
net.ipv4.tcp_dsack = 1
net.ipv4.tcp_mem = 1528512 2038016 3057024
net.ipv4.tcp_wmem = 4096 131072 8388608
net.ipv4.tcp_rmem = 4096 131072 8388608
net.ipv4.tcp_app_win = 31
net.ipv4.tcp_adv_win_scale = 2
net.ipv4.tcp_tw_reuse = 0
net.ipv4.tcp_frto = 2
net.ipv4.tcp_frto_response = 0
net.ipv4.tcp_low_latency = 0
net.ipv4.tcp_no_metrics_save = 0
net.ipv4.tcp_moderate_rcvbuf = 1
net.ipv4.tcp_tso_win_divisor = 3
net.ipv4.tcp_congestion_control = cubic
net.ipv4.tcp_abc = 0
net.ipv4.tcp_mtu_probing = 0
net.ipv4.tcp_base_mss = 512
net.ipv4.tcp_workaround_signed_windows = 0
net.ipv4.tcp_dma_copybreak = 4096
net.ipv4.tcp_slow_start_after_idle = 1
net.ipv4.tcp_available_congestion_control = cubic reno
net.ipv4.tcp_allowed_congestion_control = cubic reno
net.ipv4.tcp_max_ssthresh = 0
net.ipv4.tcp_thin_linear_timeouts = 0
net.ipv4.tcp_thin_dupack = 0
สิ่งที่แนบมามีสองภาพของกราฟ wireshark IO ของบางกรณีทดสอบ (ขออภัยฉันยังไม่สามารถโพสต์ภาพโดยตรง):
กรณีทดสอบ 1 (100Mbps -> 100Mbps) - การโอนราบรื่นดี ไม่มีการสูญเสียในการจับ - http://103.imagebam.com/download/dyNftIGh-1iCFbjfMFvBQw/25498/254976014/100m.png
กรณีทดสอบ 3 (1Gbps -> 100Mbps) - การถ่ายโอน votaile ใช้เวลานานในการรับความเร็ว - ไม่เคยเข้าใกล้ 100Mbps ยังไม่มีการสูญเสีย / retransmits ในการจับกุม! - http://101.imagebam.com/download/KMYXHrLmN6l0Z4KbUYEZnA/25498/254976007/1g.png
ดังนั้นโดยสรุปเมื่อใช้ลิงค์ยาวกับการเชื่อมต่อ 1Gbps เราจะได้รับปริมาณงาน TCP ที่ต่ำกว่าเมื่อใช้การเชื่อมต่อ 100Mbps
ฉันขอขอบคุณตัวชี้บางอย่างจากผู้เชี่ยวชาญ TCP คนใดคนหนึ่งที่นั่น!
ขอบคุณ!
อัปเดต (2013-05-29):
เราได้แก้ไขปัญหาด้วยกรณีทดสอบ # 4 ข้างต้น (ผู้ส่ง 1Gbps, ตัวรับ 1Gbps ผ่าน RTT ขนาดใหญ่) ตอนนี้เราสามารถกด ~ 970Mbps ภายในสองสามวินาทีของการถ่ายโอนเริ่ม ปัญหานี้ดูเหมือนจะเป็นสวิตช์ที่ใช้กับผู้ให้บริการโฮสต์ การย้ายไปที่อื่นจะแก้ไขได้
อย่างไรก็ตามกรณีทดสอบ # 3 ส่วนใหญ่ยังคงเป็นปัญหาอยู่ หากเรามีตัวรับสัญญาณที่ทำงานที่ 100Mbps และผู้ส่งที่ 1Gbps เราจะเห็นประมาณ 2-3 นาทีก่อนที่ตัวรับสัญญาณจะถึง 100Mbps (แต่ตอนนี้มันถึงอัตราเต็มไม่เหมือนก่อน) ทันทีที่เราส่งผู้ส่งลงไปที่ 100Mbps หรือเพิ่มผู้รับเป็น 1Gbps ปัญหาก็จะหายไปและเราสามารถเพิ่มความเร็วได้อย่างเต็มที่ในหนึ่งหรือสองวินาที
เหตุผลพื้นฐานคือเรากำลังเห็นการสูญเสียแน่นอนไม่นานหลังจากการโอนเริ่มต้น อย่างไรก็ตามนี่ไม่ใช่ความเข้าใจของฉันเกี่ยวกับการทำงานช้าเริ่มต้น ความเร็วของอินเทอร์เฟซไม่ควรมีสิ่งใดเกิดขึ้นตามที่ควรควบคุมโดย ACK จากผู้รับ
ข้อเสนอแนะที่ได้รับสุดซึ้งโปรด! ถ้าฉันสามารถเสนอเงินรางวัลที่นี่ฉันจะ!
tcp_*mem = 4096 1048576 33554432
คุณยังไม่ได้เปิดใช้งาน Jumbo Frames บนลิงค์ 1Gbps ใช่ไหม นั่นอาจทำให้เกิดการกระจายตัวของค่าใช้จ่ายที่ไหนสักแห่ง