พารามิเตอร์ประสิทธิภาพเครือข่ายของ Linux
(github.com/leandromoreira)- บทช่วยสอนสั้น ๆ ที่แสดงให้เห็นว่า พารามิเตอร์ sysctl/network ที่ใช้บ่อยในโฟลว์เครือข่ายของ Linux อยู่ตรงไหน
- ค่าแบบ cargo cult ที่ให้ทั้ง throughput สูงและ latency ต่ำพร้อมกันในทุกสถานการณ์นั้นไม่สมจริง โดยเคอร์เนลเวอร์ชันใหม่ ๆ ได้ปรับค่าดีฟอลต์มาอย่างเหมาะสมอยู่แล้ว และการเปลี่ยนค่าดีฟอลต์อาจทำให้ประสิทธิภาพแย่ลงได้
- เส้นทางรับข้อมูลถูกสรุปเป็นลำดับตั้งแต่การตรวจสอบ MAC/FCS ของ NIC, DMA, ring buffer ฝั่งรับ, hard IRQ, NAPI, soft IRQ, ingress qdisc, netfilter, state machine ของ TCP, บัฟเฟอร์รับที่อิงกับ
tcp_rmem, ไปจนถึงการที่แอปพลิเคชันอ่านข้อมูล - เส้นทางส่งข้อมูลถูกสรุปเป็นลำดับตั้งแต่
sendmsgของแอปพลิเคชัน, การจัดสรรskb_buff, บัฟเฟอร์เขียนของซ็อกเก็ตที่อิงกับtcp_wmem, การประมวลผลส่วนหัว TCP/IP, netfilter, output qdisc ที่อิงกับtxqueuelen, transmit ring buffer, DMA, ไปจนถึง IRQ เมื่อ NIC ส่งข้อมูลเสร็จ - หัวข้อการปรับแต่งหลักเชื่อมโยงกับการจัดการ burst, การใช้ CPU, latency และการสังเกต drop
rx,txring buffer คือคิวสำหรับรับ burst ของการเชื่อมต่อโดยไม่ให้เกิด drop และเมื่อเพิ่มขนาดอาจทำให้ latency สูงขึ้นrx-usecs,tx-usecs,rx-frames,tx-framesคือเวลารอและจำนวนเฟรมก่อนเกิด hard IRQ ซึ่งช่วยลดการใช้ CPU และ hard IRQ และสามารถเพิ่ม throughput ได้โดยแลกกับ latencynetdev_budget_usecs,netdev_budget,dev_weight,netdev_max_backlogเกี่ยวข้องกับ NAPI polling cycle และ throughput ของ ingress qdisctxqueuelenและdefault_qdiscเกี่ยวข้องกับคิวฝั่ง OUTPUT และ queuing discipline ดีฟอลต์
- การตรวจสอบ การเปลี่ยนค่า และการมอนิเตอร์ เน้นไปที่
ethtool,sysctl,ip,tc, และไฟล์ใน/proc- ตัวอย่าง: ตรวจสอบ ring buffer ด้วย
ethtool -g ethX, เปลี่ยนค่าด้วยethtool -G ethX rx value tx value - ตัวอย่าง: ตรวจสอบ
net.core.netdev_budget_usecsด้วยsysctl net.core.netdev_budget_usecs, เปลี่ยนค่าด้วยsysctl -w net.core.netdev_budget_usecs value - ตัวอย่าง: ตรวจสอบ
default_qdiscด้วยsysctl net.core.default_qdisc, มอนิเตอร์ด้วยtc -s qdisc ls dev ethX
- ตัวอย่าง: ตรวจสอบ ring buffer ด้วย
- หัวข้อบัฟเฟอร์ของ TCP ครอบคลุม
tcp_rmem,tcp_wmem,tcp_moderate_rcvbufโดยหากตั้งค่าtcp_moderate_rcvbufไว้ TCP จะพยายามปรับขนาดบัฟเฟอร์รับโดยอัตโนมัติ - หัวข้อที่เกี่ยวกับสถานะ TCP และการควบคุมความแออัด ถูกรวบรวมไว้ร่วมกัน ได้แก่
net.core.somaxconn,tcp_fin_timeout,tcp_available_congestion_control,tcp_congestion_control,tcp_max_syn_backlog,tcp_syncookies,tcp_slow_start_after_idle - การติดตามเครือข่ายภายในของ Linux สามารถตรวจสอบได้ด้วย perf โดยคำสั่งตัวอย่างมีรูปแบบเป็น
perf trace --no-syscalls --event 'net:*' ping globo.com -c1 > /dev/null - เครื่องมือสำหรับทดสอบและมอนิเตอร์ที่แนะนำ ได้แก่ iperf3, vegeta, netdata, และชุด prometheus + grafana + node exporter full dashboard
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
ในค่าเริ่มต้นของ Ubuntu Linux ค่า net.ipv4.tcp_rmem อยู่ที่ประมาณ 6MB ส่วน net.core.rmem_max อยู่ที่ประมาณ 1MB จึงเกิดสถานการณ์แปลก ๆ
ซ็อกเก็ต TCP ปกติหากจำเป็น หน้าต่างรับของ TCP จะเพิ่มได้ถึง 6MB แต่ถ้าแอปใน user space เรียก
setsockopt SO_RCVBUFซ็อกเก็ตที่เดิมรองรับได้ถึง 6MB ก็จะถูกจำกัดสูงสุดไว้ที่ 1MBแม้พยายามลดจาก 6MB เหลือ 4MB ผลลัพธ์กลับกลายเป็น 1MB ซึ่งดูแปลกมาก และกรณีเดียวกันนี้ก็ใช้กับ
SO_SNDBUF/wmemด้วยดูเหมือน Linux จะสับสนเรื่องลำดับความสำคัญของตัวเลือกเหล่านี้ จึงสงสัยว่าทำไมไม่ตั้ง
core.rmem_maxให้ใหญ่กว่าและใช้เป็นค่ากำหนดที่มีอำนาจกว่า หรือมีเหตุผลทางประวัติศาสตร์หรือไม่SO_SNDBUF/wmemก็สามารถลดค่า TCP_NOTSENT_LOWAT ได้ค่านี้จำกัดปริมาณข้อมูลเพิ่มเติมที่ถูกบัฟเฟอร์ไว้เกินกว่าปริมาณที่จำเป็นตามผลคูณแบนด์วิดท์-ดีเลย์ (BDP)
ทันทีที่ตั้งค่า
SO_RCVBUFซ็อกเก็ตนั้นจะไม่อยู่ภายใต้การจูนอัตโนมัติอีกต่อไป และnet.core.rmem_maxจะกลายเป็นค่าสูงสุดมีเอกสารอธิบายไว้ค่อนข้างชัดเจนใน
Documentation/networking/ip-sysctl.rstยอดเยี่ยมตรงที่แสดงทุกขั้นตอนตั้งแต่แพ็กเก็ตเข้ามาที่ NIC จนถึง user space
หากจะเสริมอีกเรื่องเกี่ยวกับประสิทธิภาพเครือข่าย สำหรับระบบที่มี CPU หลายตัว ควรตรวจสอบ NUMA allocation ซึ่งพบได้บ่อยในเซิร์ฟเวอร์ขนาดใหญ่
หากการ์ดเครือข่ายอยู่ฝั่ง CPU หนึ่ง แต่แอปพลิเคชันรันบน CPU อีกฝั่ง ก็อาจส่งผลต่อประสิทธิภาพได้
ถ้าอยากเรียนรู้เรื่องการรับส่งข้อมูลเครือข่ายจริง ๆ ก็ควรอ่านบทความเหล่านี้
https://blog.packagecloud.io/monitoring-tuning-linux-network...
https://blog.packagecloud.io/monitoring-tuning-linux-network...
https://packagecloud.io/blog/illustrated-guide-monitoring-tu...
แค่เปลี่ยน congestion control เริ่มต้นของ Linux คือ
net.ipv4.tcp_congestion_controlเป็น bbr ในบางสถานการณ์ก็สร้างความแตกต่างได้มหาศาลน่าจะโดยเฉพาะกรณีที่มีระยะทางไกล มี packet loss และ jitter เป็นระยะ ๆ รวมถึงมีการ encapsulation
ตลอดปีที่ผ่านมาเคยดีบักปัญหาใน flow แบบ
client host <-- HTTP --> reverse proxy host <-- HTTP over Wireguard --> service hostโดยโดยเฉลี่ยแล้วทำ throughput ได้ยากเกิน 20% ของค่าสูงสุดตามทฤษฎี และเมื่อเวลาผ่านไปการเชื่อมต่อก็ช้าลงจนแทบหยุดหลังใช้วิธีแก้ขัดด้วยการบังคับปิดการเชื่อมต่อบ่อย ๆ แล้วเปลี่ยน congestion control เป็น
bbrก็ได้ throughput ใกล้ค่าสูงสุดตามทฤษฎีและการเชื่อมต่อที่เสถียร โดยต้องเปลี่ยนทั้งสองฝั่งของ WireguardTCP stack ส่วนใหญ่เมื่อเห็น packet loss ครั้งแรกจะลด send window ลงครึ่งหนึ่งหรือลดลงอย่างมาก ดังนั้นถ้าเป็น VPN ที่มี loss หรือส่ง burst ใหญ่ด้วย 1Gb/s เข้า uplink VPN 10Mb/s เมื่อ TCP เห็น loss ก็จะถอยลงอย่างหนัก
BBR พยายามหาแบนด์วิดท์คอขวด โดยวัด round-trip time และเพิ่มอัตราการส่งจนกว่า RTT จะเพิ่มขึ้น
เมื่อ RTT เพิ่มขึ้น จะถือว่ามีคิวสะสมที่ช่วงที่แคบที่สุดของเส้นทาง จากนั้นลดอัตราการส่งลงจนคิวระบายออกและ RTT กลับสู่ปกติ แล้วส่งด้วยความเร็วนั้นต่อไปพักหนึ่ง ก่อนจะลองเพิ่มขึ้นเล็กน้อยอีกครั้ง
หลายปีก่อน แม้เปลี่ยนจาก uplink เคเบิล 10Mb/s เป็นไฟเบอร์สมมาตร 1Gb/s แล้ว แต่การอัปโหลดผ่าน VPN ของบริษัทยังติดอยู่ราว 5Mb/s จนน่าหงุดหงิด และเมื่อเปลี่ยนเป็น RACK TCP หรือ BBR บน FreeBSD ก็เพิ่มขึ้นราว 8 เท่าจนถึงขีดจำกัดของ VPN ที่ประมาณ 40Mb/s
การจูนประสิทธิภาพแบบ cargo cult จากการคัดลอกวางที่คิดว่าแค่ตั้งค่ามหัศจรรย์ค่าเดียวแล้วจะดีขึ้นนั้นตรงข้ามกับสิ่งที่บทความต้นฉบับต้องการสื่อโดยสิ้นเชิง
โชคดีที่ Google กำลัง upstream BBRv3 อยู่ ดังนั้นก็น่าจะดีขึ้นในไม่ช้า
หากต้องการปรับปรุงประสิทธิภาพเพียงทิศทางเดียว ก็ไม่จำเป็นต้องเปลี่ยนทั้งสองฝั่งของ Wireguard
สำหรับ BBRv1 เห็นด้วยกับความเห็นอื่น ๆ และ cubic implementation ของเคอร์เนล Linux ก็ทำงานได้ค่อนข้างดีสำหรับแอปพลิเคชันส่วนใหญ่
สงสัยว่าการปรับจูนประสิทธิภาพมีความหมายกับ อะแดปเตอร์ Wi‑Fi ด้วยหรือไม่
สำหรับเดสก์ท็อป ก็สงสัยด้วยว่านอกจากการปิดฟีเจอร์แล้ว มีวิธีแก้ปัญหาอีเทอร์เน็ต i210 และ i225 หรือไม่
ช่วงนี้ NIC ที่พบบ่อยที่สุดน่าจะเป็นสองตัวนี้ แต่ไม่ค่อยเข้าใจว่าทำไมฮาร์ดแวร์เครือข่ายและไดรเวอร์ที่ใช้กันทั่วไปถึงมีข้อบกพร่องเยอะขนาดนี้
สนใจ RISC-V มากอยู่แล้ว เลยคิดว่าถ้าเริ่มจาก NIC ที่เปิดเผยทั้งหมดและทำมาอย่างถูกต้องจะเป็นอย่างไร
ถ้าถูกกว่า i210 สุดท้ายก็คงมีคนใส่มาให้ แต่บางทีอาจเป็นเรื่องที่เป็นไปไม่ได้ก็ได้
อย่างไรก็ตาม ใน Wi‑Fi การพุ่งขึ้นของ ping แบบสุ่มยังคงเกิดขึ้นอยู่
มีเธรดใหญ่ที่พูดถึงการเปิดใช้และปรับจูน AQM รวมถึง trade-off ระหว่าง throughput กับ latency ที่ https://forum.openwrt.org/t/aql-and-the-ath10k-is-lovely/590...
บน CPU รุ่นเดียวกัน 1Gb ก็ไม่ได้ยากอะไรนัก และ i210 มีคิวให้ 4 คิว
สงสัยว่าคุณไม่พอใจอะไรใน i210
ภาพรวมของ คิวเครือข่าย Linux ที่สรุปเป็นภาพทำได้ยอดเยี่ยม จนอยากเอาไปแปะไว้บนผนังที่ไหนสักแห่ง
หนังสือ Systems Performance ของ Brendan ก็อธิบายประสิทธิภาพเครือข่าย Linux และเรื่องอื่น ๆ ได้ดี และตอนนี้ออกมาถึงฉบับที่ 2 แล้ว
ทั้งสองฉบับยอดเยี่ยม แต่ฉบับที่ 2 เน้น Linux เป็นหลัก ส่วนฉบับที่ 1 มี Solaris ด้วย
ล่าสุดกว่านั้น ยังมีหนังสือ BPF Performance Tools จากผู้เขียนคนเดียวกันด้วย
[1] Systems Performance: Enterprise and the Cloud, 2nd Edition (2020)
https://www.brendangregg.com/systems-performance-2nd-edition...
[2] BPF Performance Tools:
https://www.brendangregg.com/bpf-performance-tools-book.html
แค่ไล่อ่านบทความคร่าว ๆ ก็สนุกแล้ว งานค้นคว้าและการจัดวางเนื้อหาดีมาก
แต่ก็สงสัยว่าในความเป็นจริง ใครคือคนที่ปรับจูน พารามิเตอร์เครือข่ายของ Linux เป็นประจำกันแน่
เอกสารนี้น่าจะระบุคำว่า TCP ไว้ที่ไหนสักแห่งอย่างชัดเจน
เนื้อหาโฟกัสไปที่ประเด็นที่เกี่ยวกับ TCP มาก และก็มีประโยชน์เพราะคนส่วนใหญ่ใช้ TCP
แต่ค่าปรับจูนเริ่มต้นของ UDP ต่ำจนน่าแย่ และส่วนนั้นหายไปอย่างเห็นได้ชัด
อยากได้คำแนะนำ วิดีโอหรือซีรีส์ ที่พูดถึงเนื้อหาคล้าย ๆ กัน
แหล่งข้อมูลด้าน networking ทั่วไปมีเยอะ แต่หาข้อมูลที่ลงรายละเอียดการ implement เฉพาะของ Linux ได้ยาก
อยากลองทำ TCP echo server ง่าย ๆ สำหรับไมโครคอนโทรลเลอร์ แต่ตัวอย่างส่วนใหญ่แค่ใช้ไลบรารี TCP ของผู้ขายเอง และแทบไม่อธิบายกระบวนการเชื่อมต่อและสร้างการเชื่อมต่อกับเราเตอร์โดยตรง