Skip to content

netpoll

Netpoll ของ Go เป็นกลไก I/O multiplexing หลักที่ดำเนินการโดย Go runtime ทำให้ Go สามารถใช้บริการเครือข่ายประสิทธิภาพสูงด้วยโมเดลการเขียนโปรแกรมแบบ synchronous ที่เรียบง่าย (หนึ่ง Goroutine ต่อหนึ่งการเชื่อมต่อ) โดยพื้นฐานแล้วเป็นการรวมการเรียกระบบ I/O multiplexing ระดับล่างของระบบปฏิบัติการ (เช่น epoll ของ Linux) เข้ากับตัวจัดตาราง Goroutine ของ Go อย่างลึกซึ้ง

การเปรียบเทียบระหว่าง Netpoll กับ GoNet ดั้งเดิม

  1. จำนวน Goroutine

    • Go Net: หนึ่ง Goroutine มีหนึ่งการเชื่อมต่อ
    • NetPoll: หนึ่ง Goroutine มีหลายการเชื่อมต่อ
  2. แรงกดดันในการสลับบริบท goroutine

    • Go Net: เมื่อมีความพร้อมใช้งานสูง แรงกดดันในการสลับสูง เนื่องจาก GoNet มีการเชื่อมต่อหนึ่งตัวต่อหนึ่ง goroutine เมื่อจำนวน goroutine มากจะสลับบ่อย
    • NetPoll: เมื่อมีความพร้อมใช้งานสูง แรงกดดันในการสลับน้อย เนื่องจาก NetPoll หลายการเชื่อมต่อใช้ goroutine เดียวกัน จำนวนการสลับน้อย
  3. การใช้หน่วยความจำ

    • Go Net: การใช้หน่วยความจำสัมพันธ์เชิงบวกกับจำนวนการเชื่อมต่อ เมื่อมีความพร้อมใช้งานสูงอาจทำให้เกิดแรงกดดันหน่วยความจำเนื่องจากจำนวน Goroutine ระเบิด
    • NetPoll: จัดสรรบัฟเฟอร์ล่วงหน้า สร้างพูลบัฟเฟอร์
  4. วิธีการทริกเกอร์

    • Go Net: ใช้ Edge Triggered (ET) อ่านข้อมูลจนหมดในครั้งเดียว การดำเนินการง่าย
    • NetPoll: ใช้ Level Triggered (LT) ไม่จำเป็นต้องจัดสรรหน่วยความจำขนาดใหญ่ล่วงหน้าสำหรับบัฟเฟอร์ข้อมูล
  5. รองรับการแชร์พูลบัฟเฟอร์ระหว่างเคอร์เนลและเลเยอร์ผู้ใช้ ลดการคัดลอกข้อมูลหนึ่งครั้ง

    • Go Net: ไม่รองรับ
    • NetPoll: รองรับ จัดการพูล Buffer โดยตรงให้เลเยอร์ผู้ใช้ ลดการคัดลอกข้อมูลหนึ่งครั้ง
  6. สถานการณ์ที่เหมาะสม

    • Go Net: สถานการณ์ง่ายที่มีความพร้อมใช้งานต่ำ
    • NetPoll: สถานการณ์ที่มีความพร้อมใช้งานสูงและความหน่วงต่ำ

แนวคิดการออกแบบ netpoll

  1. สถาปัตยกรรมพื้นฐาน ไลบรารีเครือข่ายดั้งเดิมพัฒนาบนพื้นฐานของโหมด epoll lt สถาปัตยกรรมพื้นฐานแสดงดังภาพด้านล่าง: สถาปัตยกรรมพื้นฐาน netpoll

  2. การใช้ goroutine มีพูลอ็อบเจ็กต์ poll แต่ละอ็อบเจ็กต์ poll มี epoll หนึ่งตัวและสอดคล้องกับ goroutine หนึ่งตัวจำนวน goroutine สัมพันธ์กับจำนวนอ็อบเจ็กต์ poll แต่ละอ็อบเจ็กต์ poll สามารถตรวจสอบไฟล์ descriptor fd ได้หลายตัว

  3. ตรรกะการอ่าน/เขียน IO

    • แต่ละอ็อบเจ็กต์ poll เปิด goroutine เพื่อวนลูปตรวจสอบเหตุการณ์ที่อ่านได้/เขียนได้บน epoll ปัจจุบัน
    • แต่ละ epoll จะเชื่อมโยงกับ fd หลายตัว แต่ละ fd เชื่อมโยงกับ Buffer หนึ่งตัว
    • เมื่อตรวจสอบเหตุการณ์ที่อ่านได้จาก fd จะอ่านข้อมูลลงใน Buffer
    • วนลูปประมวลผลข้อมูลใน Buffer ต่อไป เมื่อพบว่าข้อมูลอ่านเสร็จแล้ว จะแจ้งให้พูล goroutine ของตรรกะการประมวลผลด้านหลัง GoPoll ดำเนินการ
    • การโต้ตอบการเรียก系统与เคอร์เนลถูกควบคุมโดย netpoll อย่างสมบูรณ์ การอ่าน/เขียน Conn ของเลเยอร์ผู้ใช้เป็นเพียงการดำเนินการกับ Buffer ที่ใช้ร่วมกันเท่านั้น
  4. ข้อดีและข้อเสีย

    ข้อดี: รองรับความสามารถความพร้อมใช้งานสูงที่แข็งแกร่งกว่า

    • (1) การวนลูปประมวลผลข้อมูลใน Buffer ไม่มีสถานการณ์ที่ข้อมูลไม่ได้รับการประมวลผล
    • (2) หนึ่ง goroutine สอดคล้องกับหลายการเชื่อมต่อ แม้ว่าการเชื่อมต่อมีจำนวนมาก ค่าใช้จ่ายในการจัดสรรทรัพยากรและการสลับก็ไม่มาก
    • (3) รองรับผู้ใช้และเคอร์เนลแชร์ buff ลดการดำเนินการคัดลอกข้อมูลหนึ่งครั้ง เพิ่มประสิทธิภาพ

    ข้อเสีย: ต้องใช้หน่วยความจำมากขึ้น

Golang by www.golangdev.cn edit