Có phải là một ý tưởng tốt để chặn nhiều luồng vào kết nối TCP không?


13

Tôi cần một số kênh song công giữa hai máy chủ. Có một số lợi thế khi chỉ thiết lập một kết nối TCP. Nhưng tôi nghi ngờ ghép kênh sẽ gây ra một số vấn đề không thể tránh khỏi. Nó sẽ làm hại hiệu suất hoặc tăng độ trễ đáng kể? Và những gì về việc sử dụng bộ nhớ và sử dụng CPU? Có gợi ý hay cảnh báo nào bạn muốn đưa ra không?

Câu trả lời:


10

TLDR: Hạn chế lớn mà bạn có thể nhận thấy khi ghép nhiều kênh trên đầu TCP (nếu bạn làm đúng) là độ trễ tăng do chặn đầu dòng giữa các kênh.

Hệ quả: Nếu bạn không quan tâm đến độ trễ, bạn sẽ ổn thôi.

Mặt khác, sử dụng một kết nối TCP duy nhất có nghĩa là ít cạnh tranh với các luồng khác và các kết nối có thời gian tồn tại lâu hơn, điều này dẫn đến việc sử dụng tốt hơn dung lượng mạng có sẵn .

Chặn chặn đầu dòng trên TCP

Nếu bạn ghép nhiều kênh trên cùng một luồng TCP, các kênh có thể bị chặn đầu dòng :

Chặn đầu dòng (HOL) có thể xảy ra khi các giao thức vận chuyển cung cấp dịch vụ được đặt hàng hoặc đặt hàng một phần: Nếu các phân đoạn bị mất, các tin nhắn tiếp theo phải chờ truyền lại thành công trong hàng đợi người nhận và do đó bị trì hoãn.

Khi bạn ghép nhiều luồng trên đầu TCP, bạn sẽ nhận được HOL giữa các kênh .

Nếu kênh A đã lấp đầy bộ đệm gửi TCP, bạn sẽ phải đợi trước khi nhận được tất cả dữ liệu này trước khi bất kỳ dữ liệu mới nào của kênh B có thể được truyền đến lớp ứng dụng từ xa một cách hiệu quả.

Xem "Ghép kênh trên đầu TCP" để biết thêm chi tiết về các kênh ghép kênh trên đầu TCP và thảo luận về hackernews .

Ví dụ về ghép kênh qua TCP

Ghép kênh qua SSH (qua TCP)

Một ví dụ điển hình của việc này là SSH. SSH có thể ghép nhiều kênh (xem ControlMaster, ControlPathControlPersisttrong OpenSSH). Sử dụng điều này giúp giảm chi phí khởi tạo phiên SSH mới (độ trễ ban đầu) nhưng chuyển mạnh trên một kênh thường làm tăng độ trễ / tương tác của các kênh khác (điều này không xảy ra nếu bạn sử dụng nhiều luồng TCP): nếu bạn đang sử dụng một tương tác các phiên và bắt đầu chuyển giao một tập tin nặng trên cùng một kênh, phiên của bạn sẽ bắt đầu ít tương tác hơn.

HTTP / 2 ghép kênh qua TCP

HTTP / 2 sử dụng ghép kênh các yêu cầu / phản hồi qua TCP để sửa lỗi chặn HOL. Tính năng này được quảng cáo trong nhiều bài viết và bài báo về HTTP / 2. Yêu cầu RFC HTTP / 2 :

HTTP / 1.1 đã thêm đường dẫn yêu cầu, nhưng điều này chỉ giải quyết một phần đồng thời yêu cầu và vẫn bị chặn đầu dòng.

[...]

Giao thức kết quả thân thiện hơn với mạng vì có thể sử dụng ít kết nối TCP hơn so với HTTP / 1.x. Điều này có nghĩa là ít cạnh tranh hơn với các luồng khác và kết nối lâu hơn, từ đó dẫn đến việc sử dụng tốt hơn dung lượng mạng khả dụng.

Tuy nhiên, điều không được thảo luận là việc chặn HOL không được giải quyết hoàn toàn. HTTP / 2 qua TCP vẫn bị ) do chặn HOL cấp TCP .

Điều này được thảo luận trong bài viết này của LWN về QUIC:

HTTP / 2 được thiết kế để giải quyết vấn đề này bằng nhiều "luồng" được tích hợp trong một kết nối . [...] nó tạo ra một vấn đề mới: việc mất một gói sẽ ngăn chặn việc truyền tất cả các luồng cùng một lúc, tạo ra các vấn đề về độ trễ mới. Biến thể này trong vấn đề chặn đầu dòng được tích hợp vào chính TCP và không thể sửa được với nhiều điều chỉnh hơn ở cấp HTTP.

Chiến lược ghép kênh khác

SCTP

Đó là một trong những tính năng nổi bật của SCTP (đa luồng), bạn có thể có nhiều luồng độc lập trong cùng một liên kết SCTP và mỗi luồng không chặn các luồng khác.

Xem SSH qua SCTP - Tối ưu hóa giao thức đa kênh bằng cách điều chỉnh nó thành SCTP để biết hiệu quả của việc sử dụng SCTP để tránh chặn HOL kênh chéo trong SSH:

SCTP chỉ duy trì thứ tự của các tin nhắn trong một luồng duy nhất để giảm thiểu hiệu ứng được gọi là chặn đầu dòng. Nếu một tin nhắn bị mất, các tin nhắn tiếp theo phải bị trì hoãn cho đến khi tin nhắn bị mất được truyền lại để giữ trật tự. Vì chỉ các tin nhắn của cùng một luồng phải bị trì hoãn, nên số lượng tin nhắn bị ảnh hưởng sau khi bị mất sẽ giảm.

[...]

Bằng cách ánh xạ các kênh của SSH lên các luồng của SCTP, lợi ích của đa luồng được cung cấp cho SSH, đó là giảm thiểu việc chặn đầu dòng .

SCTP không nhất thiết phải dễ triển khai (vì có sẵn hệ điều hành, tương tác giữa hộp, v.v.). Một khả năng là triển khai nó trên UDP trong không gian người dùng .

QUIC (ghép kênh trên UDP)

Một ví dụ khác, là giao thức QUIC thử nghiệm được sử dụng để ghép kênh HTTP qua UDP (vì việc ghép nhiều luồng trên đầu TCP khi HTTP / 2 không bị chặn HOL ):

QUIC là một phương tiện giao thông mới giúp giảm độ trễ so với TCP. Nhìn bề ngoài, QUIC rất giống với TCP + TLS + HTTP / 2 được triển khai trên UDP.

[...]

Ghép kênh mà không có đầu chặn

Giao thức QUIC của Google: chuyển web từ TCP sang UDP trình bày tổng quan tốt về chặn QUIC và HOL khi ghép kênh trên đầu TCP.

Một bài thuyết trình gần đây tuyên bố rằng HTTP trên QUIC cải thiện độ trễ nhưng cải tiến chặn HOL là một lợi ích nhỏ hơn của YouTube:

0-RTT, hơn 50% cải thiện độ trễ

[Càng]

Thời gian truyền lại dựa trên thời gian chờ ít hơn sẽ cải thiện độ trễ của đuôi [Mạnh]

Khác, lợi ích nhỏ hơn, ví dụ như chặn đường

Lưu ý rằng mặc dù QUIC được mô tả là rất giống với TCP + TLS + HTTP / 2 được triển khai trên UDP, nhưng thực tế nó là một phương tiện vận chuyểnmục đích chung có thể được sử dụng độc lập với HTTP / 2 và có thể phù hợp với nhu cầu của bạn.

Lưu ý: si HTTP / QUIC sẽ được chuẩn hóa thành HTTP / 3 .


Tôi không nghĩ HOL là một vấn đề thực sự, nếu có một cơ chế kiểm soát dòng chảy. Mở nhiều kết nối TCP cũng tạo ra nhiều bộ đệm cửa sổ, có thể không hiệu quả hơn về bộ nhớ.
Sherwood Wang

Tôi đã xem xét SCTP. Nhưng có vẻ như SCTP vẫn chưa thể di động và các thiết bị NAT xử lý nó không tốt.
Sherwood Wang

@SherwoodWang, Có cơ chế luồng điều khiển trong giao thức ghép kênh của bạn sẽ không ngăn chặn HOL xảy ra.
ysdx

Khi không có dữ liệu có sẵn tại người gửi, người gửi có thể gửi khung điều khiển luồng để báo cho người nhận chuyển sang kênh ghép kênh tiếp theo và tiếp tục gửi khung dữ liệu của kênh này. Khi nhận được đầy đủ, cơ chế tương tự cũng có thể được sử dụng. Nó chắc chắn ngăn chặn HOL chặn chỉ với một nửa độ trễ chuyến đi khứ hồi.
Sherwood Wang

@SherwoodWang, vấn đề TCP HOL thực sự nằm ở phía nhận. Nếu một số gói bị mất trong quá trình truyền, người nhận không thể cung cấp các gói sau cho không gian người dùng. Nó phải chờ gói tin được truyền lại và nhận. Tất cả các dữ liệu phát lại (sự kiện từ luồng đa kênh khác) bị chặn cho đến khi nhận được gói này.
ysdx

3

Tôi muốn nói rằng bạn cần đọc Hướng dẫn ZeroMQ , các mẫu mà nó đưa ra với lý do và nhược điểm là cách đọc cần thiết.

Nhưng nếu không, không có vấn đề gì với việc ngắt kết nối kênh mạng khỏi việc phân phối dữ liệu ứng dụng của bạn. Bạn sẽ phải thực hiện việc chuyển đổi và giải mã các gói dữ liệu được gửi (và tôi muốn giới thiệu một kiến ​​trúc dựa trên gói ở đây, không truyền dữ liệu theo luồng liên tục) và đệm chúng ở mỗi đầu.

Sẽ có ít tác động khác, bạn có thể cần thêm bộ nhớ - nhưng chỉ một chút - để đệm dữ liệu và thêm một chút CPU khi bạn đang xử lý nhiều mã hơn để khóa và phân tích các gói, nhưng không có gì đáng kể. (trừ khi bạn đang viết một cái gì đó chuyên gia đòi hỏi một thông lượng lớn và hiệu suất là rất quan trọng).


2

Có, tôi đã xây dựng một hệ thống cơ sở dữ liệu máy khách-máy chủ bằng cách sử dụng chính xác nguyên tắc này.

Các kênh được ghép vào một kết nối TCP, mỗi gói gửi các gói dữ liệu, sau đó được chia ra cho người nhận tương ứng ở đầu kia.

Việc ngắt kết nối bằng một kênh thông minh được thực hiện bởi người gửi kết nối TCP thực hiện lựa chọn vòng tròn trong đó gói tin nào được truyền từ giữa các kênh có dữ liệu sẵn sàng gửi.

Để xử lý trường hợp một kênh quyết định gửi gói 1GB và khóa mọi người khác, người gửi có thể chọn chia gói thành nhiều phần và chỉ gửi một đoạn trước khi chuyển kênh khác. Ở đầu nhận, việc lắp lại các khối vào một gói được thực hiện trước khi người nhận nhìn thấy gói.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.