4 คะแนน โดย GN⁺ 2023-09-07 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • บทช่วยสอนสั้น ๆ ที่แสดงให้เห็นว่า พารามิเตอร์ 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, tx ring buffer คือคิวสำหรับรับ burst ของการเชื่อมต่อโดยไม่ให้เกิด drop และเมื่อเพิ่มขนาดอาจทำให้ latency สูงขึ้น
    • rx-usecs, tx-usecs, rx-frames, tx-frames คือเวลารอและจำนวนเฟรมก่อนเกิด hard IRQ ซึ่งช่วยลดการใช้ CPU และ hard IRQ และสามารถเพิ่ม throughput ได้โดยแลกกับ latency
    • netdev_budget_usecs, netdev_budget, dev_weight, netdev_max_backlog เกี่ยวข้องกับ NAPI polling cycle และ throughput ของ ingress qdisc
    • txqueuelen และ 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
  • หัวข้อบัฟเฟอร์ของ 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 ความคิดเห็น

 
GN⁺ 2023-09-07
ความคิดเห็นจาก 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)
    • ค่าสูงสุดของ net.ipv4.tcp_rmem คือขีดจำกัดของการจูนอัตโนมัติที่เคอร์เนลดำเนินการ
      ทันทีที่ตั้งค่า SO_RCVBUF ซ็อกเก็ตนั้นจะไม่อยู่ภายใต้การจูนอัตโนมัติอีกต่อไป และ net.core.rmem_max จะกลายเป็นค่าสูงสุด
      มีเอกสารอธิบายไว้ค่อนข้างชัดเจนใน Documentation/networking/ip-sysctl.rst
  • ยอดเยี่ยมตรงที่แสดงทุกขั้นตอนตั้งแต่แพ็กเก็ตเข้ามาที่ NIC จนถึง user space
    หากจะเสริมอีกเรื่องเกี่ยวกับประสิทธิภาพเครือข่าย สำหรับระบบที่มี CPU หลายตัว ควรตรวจสอบ NUMA allocation ซึ่งพบได้บ่อยในเซิร์ฟเวอร์ขนาดใหญ่
    หากการ์ดเครือข่ายอยู่ฝั่ง CPU หนึ่ง แต่แอปพลิเคชันรันบน CPU อีกฝั่ง ก็อาจส่งผลต่อประสิทธิภาพได้

  • แค่เปลี่ยน 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 ใกล้ค่าสูงสุดตามทฤษฎีและการเชื่อมต่อที่เสถียร โดยต้องเปลี่ยนทั้งสองฝั่งของ Wireguard

    • BBR แตกต่างตรงที่ไม่ได้ใช้การสูญหายของแพ็กเก็ตเป็นสัญญาณของ congestion
      TCP 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
    • BBRv1 เสียอยู่ จึงไม่ควรใช้บนอินเทอร์เน็ตสาธารณะ
      การจูนประสิทธิภาพแบบ cargo cult จากการคัดลอกวางที่คิดว่าแค่ตั้งค่ามหัศจรรย์ค่าเดียวแล้วจะดีขึ้นนั้นตรงข้ามกับสิ่งที่บทความต้นฉบับต้องการสื่อโดยสิ้นเชิง
      โชคดีที่ Google กำลัง upstream BBRv3 อยู่ ดังนั้นก็น่าจะดีขึ้นในไม่ช้า
    • congestion control ทำงานในทิศทางจากฝั่งที่ส่งข้อมูลไปยังฝั่งที่รับข้อมูล
      หากต้องการปรับปรุงประสิทธิภาพเพียงทิศทางเดียว ก็ไม่จำเป็นต้องเปลี่ยนทั้งสองฝั่งของ Wireguard
      สำหรับ BBRv1 เห็นด้วยกับความเห็นอื่น ๆ และ cubic implementation ของเคอร์เนล Linux ก็ทำงานได้ค่อนข้างดีสำหรับแอปพลิเคชันส่วนใหญ่
  • สงสัยว่าการปรับจูนประสิทธิภาพมีความหมายกับ อะแดปเตอร์ Wi‑Fi ด้วยหรือไม่
    สำหรับเดสก์ท็อป ก็สงสัยด้วยว่านอกจากการปิดฟีเจอร์แล้ว มีวิธีแก้ปัญหาอีเทอร์เน็ต i210 และ i225 หรือไม่
    ช่วงนี้ NIC ที่พบบ่อยที่สุดน่าจะเป็นสองตัวนี้ แต่ไม่ค่อยเข้าใจว่าทำไมฮาร์ดแวร์เครือข่ายและไดรเวอร์ที่ใช้กันทั่วไปถึงมีข้อบกพร่องเยอะขนาดนี้
    สนใจ RISC-V มากอยู่แล้ว เลยคิดว่าถ้าเริ่มจาก NIC ที่เปิดเผยทั้งหมดและทำมาอย่างถูกต้องจะเป็นอย่างไร
    ถ้าถูกกว่า i210 สุดท้ายก็คงมีคนใส่มาให้ แต่บางทีอาจเป็นเรื่องที่เป็นไปไม่ได้ก็ได้

    • หากยอมแลก throughput สูงสุดของเครือข่ายภายใน 10–20% ก็สามารถเพิ่ม ความเป็นธรรมของ Wi‑Fi ได้มาก ปรับปรุงเวลา ping และลด bufferbloat ได้
      อย่างไรก็ตาม ใน Wi‑Fi การพุ่งขึ้นของ ping แบบสุ่มยังคงเกิดขึ้นอยู่
      มีเธรดใหญ่ที่พูดถึงการเปิดใช้และปรับจูน AQM รวมถึง trade-off ระหว่าง throughput กับ latency ที่ https://forum.openwrt.org/t/aql-and-the-ath10k-is-lovely/590...
    • i225 เป็นของที่พังจริง ๆ แต่ i210 ให้ประสิทธิภาพยอดเยี่ยม
      บน CPU รุ่นเดียวกัน 1Gb ก็ไม่ได้ยากอะไรนัก และ i210 มีคิวให้ 4 คิว
      สงสัยว่าคุณไม่พอใจอะไรใน i210
    • เคยใช้เมนบอร์ดที่มี i225 onboard อยู่ แล้วแก้ปัญหาด้วยการซื้อ PCIe I350
  • ภาพรวมของ คิวเครือข่าย 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 ต่ำจนน่าแย่ และส่วนนั้นหายไปอย่างเห็นได้ชัด

    • สงสัยว่ามีแหล่งข้อมูลดี ๆ สำหรับ การปรับจูน UDP หรือไม่
  • อยากได้คำแนะนำ วิดีโอหรือซีรีส์ ที่พูดถึงเนื้อหาคล้าย ๆ กัน
    แหล่งข้อมูลด้าน networking ทั่วไปมีเยอะ แต่หาข้อมูลที่ลงรายละเอียดการ implement เฉพาะของ Linux ได้ยาก

    • ต้องการแหล่งข้อมูลแบบเดียวกันจากมุมมองของไมโครคอนโทรลเลอร์ด้วย
      อยากลองทำ TCP echo server ง่าย ๆ สำหรับไมโครคอนโทรลเลอร์ แต่ตัวอย่างส่วนใหญ่แค่ใช้ไลบรารี TCP ของผู้ขายเอง และแทบไม่อธิบายกระบวนการเชื่อมต่อและสร้างการเชื่อมต่อกับเราเตอร์โดยตรง