Skip to content

netpoll

Netpoll của Go là cơ chế I/O multiplexing cốt lõi được triển khai bởi runtime của ngôn ngữ Go, nó cho phép Go thực hiện các dịch vụ mạng hiệu năng cao với mô hình lập trình đồng bộ đơn giản (một Goroutine cho mỗi kết nối). Bản chất của nó là kết hợp sâu các system call I/O multiplexing底层 của hệ điều hành (như epoll của Linux) với scheduler Goroutine của Go.

So sánh giữa Netpoll và GoNet gốc

  1. Số lượng Goroutine

    • Go Net: Một Goroutine chỉ có một kết nối.
    • NetPoll: Một Goroutine có nhiều kết nối.
  2. Áp lực chuyển đổi ngữ cảnh调度 goroutine

    • Go Net: Áp lực chuyển đổi cao khi并发 cao. Vì GoNet ánh xạ một kết nối với một goroutine, khi số lượng goroutine nhiều sẽ chuyển đổi thường xuyên.
    • NetPoll: Áp lực chuyển đổi nhỏ khi并发 cao. Vì NetPoll nhiều kết nối dùng chung một goroutine, số lần chuyển đổi ít.
  3. Tiêu thụ bộ nhớ:

    • Go Net: Tiêu thụ bộ nhớ tỷ lệ thuận với số lượng kết nối, khi并发 cao có thể gây áp lực bộ nhớ do số lượng Goroutine bùng nổ.
    • NetPoll: Phân phối buffer trước, tạo pool buffer.
  4. Phương thức kích hoạt

    • Go Net: Sử dụng Edge Triggered ET. Đọc hết dữ liệu một lần, triển khai đơn giản.
    • NetPoll: Sử dụng Level Triggered LT. Không cần phân phối trước bộ nhớ đủ lớn làm buffer dữ liệu.
  5. Có hỗ trợ chia sẻ pool buff giữa kernel và user layer, giảm một lần sao chép dữ liệu không.

    • Go Net: Không hỗ trợ.
    • NetPoll: Hỗ trợ. Quản lý một pool Buffer trực tiếp giao cho user, giảm một lần sao chép.
  6. Kịch bản适用 dụng

    • Go Net: Kịch bản đơn giản并发 thấp
    • NetPoll: Kịch bản并发 cao độ trễ thấp

Ý tưởng thiết kế netpoll

  1. Kiến trúc cơ bản Thư viện mạng gốc được phát triển dựa trên chế độ epoll lt, kiến trúc cơ bản như hình dưới đây: Kiến trúc cơ bản netpoll

  2. Sử dụng goroutine Tồn tại một pool đối tượng poll, mỗi đối tượng poll mang một epoll, và tương ứng riêng với một goroutine. Số lượng goroutine nhất quán với số lượng đối tượng poll, mỗi đối tượng poll có thể监听 nhiều file descriptor fd

  3. Logic đọc ghi IO

    • Mỗi đối tượng poll mở một goroutine để liên tục轮询 các sự kiện có thể đọc/ghi trên epoll hiện tại
    • Mỗi epoll sẽ liên kết với nhiều fd, mỗi fd liên kết với một Buffer.
    • Khi监听 được sự kiện có thể đọc từ fd, sẽ đọc dữ liệu vào Buffer.
    • Liên tục轮询 xử lý dữ liệu trong Buffer, khi phát hiện dữ liệu đọc xong, sẽ thông báo cho pool goroutine xử lý logic phía sau GoPoll để thực thi
    • Tương tác system call với kernel hoàn toàn do netpoll kiểm soát, việc đọc ghi của user layer đối với Conn chỉ là thao tác trên Buffer dùng chung.
  4. Ưu nhược điểm Ưu điểm: Hỗ trợ khả năng并发 cao mạnh hơn.

    • (1) Xử lý轮询 dữ liệu trong Buffer, không tồn tại tình trạng dữ liệu không được xử lý.
    • (2) Một goroutine tương ứng với nhiều kết nối, ngay cả khi có rất nhiều kết nối, chi phí调度 chuyển đổi tài nguyên cũng không lớn.
    • (3) Hỗ trợ user và kernel chia sẻ buff, giảm một thao tác sao chép dữ liệu, nâng cao hiệu suất.

    Nhược điểm: Cần chiếm dụng nhiều bộ nhớ hơn.

Golang by www.golangdev.cn edit