『開源』大半夜除錯TCP延遲問題

InkFx發表於2024-03-30

背景

公司有個專案,需要一個高可用快取服務。
之前通訊技術選型時,測試過 UDP TCP HTTP QUIC gRPC 效能。

初步結論:
1、UDP 很快,CPU 很低,但無法超過 64K (大於12K 甚至都開始內網丟包)

2、HTTP 傳統的 WebApi (中規中矩的技術選型,延遲都還好,但真想完善還得每次增加 WebApi 安全驗證 —— 就開始損失效能了)

3、傳說中的 Quic,說是用UDP實現了一套類似 TCP 的重發機制(實測 CPU 增加,吞吐降低 —— 真就和本機TCP一樣了)

4、本來自己心目中最想用的是 TCP(有一套成熟的TCP庫,實戰從未失望),只需建立連線時只需一次安全驗證(目前很多資料庫、Redis、MQTT、RabbtMQ 底層都是TCP,也都是連線時安全驗證)—— 但不知道為啥,區域網跨機部署 一來一回一次互動 延遲達到到 100ms(經驗中:同步的 一來一回 TCP 本機可以達到 5000/s ~ 7000/s)。

TCP讓我很氣餒

印象中的 TCP:

  • 單核同步速度 5000/s ~ 7000/s
  • 四核非同步速度 可以把CPU跑滿,30000/s 都只是小意思

但這次跨機部署,每次互動 100ms 延遲(摺合 10/s 的速度 —— 這還玩毛線)

雖然多核非同步,依然能把頻寬跑滿,互動也能達到 30000/s 吞吐量 —— 但每次互動的延遲 100ms 就很不合適。

難道是我之前的專案,都只在乎吞吐量,卻沒有關注延遲的緣故 ?

TCP 減少延遲調優

最佳化前的現狀

本機互動 0ms,吞吐量 7000/s
image

虛擬機器互動 85ms,吞吐量 20/s
image

虛擬機器ping延遲 1ms —— ping 一來一回也就 1ms, 沒理由 TCP 一來一回 85ms 啊
image

使用非同步程式碼最佳化後(沒啥用)

本機互動 0ms,吞吐量 7000/s
image

虛擬機器互動 85ms,吞吐量 20/s
image

會不會是 Linux 的問題?換成 Win10 和 Win10 互動還是鳥樣
image

找到關鍵最佳化程式碼

虛擬機器互動 0ms
image

最終吞吐量 800/s
image

至此,執念已消,總結:

最終最佳化後的程式碼,依然選用回撥非同步
image

真正其決定性作用的引數是這個 NoDelay
image

TCP的 吞吐量 和 延遲 區別

  • 延遲,比如一個單車道,路面坑坑窪窪 一輛車一來一回 100秒,路面平整 一輛車一來一回 10秒 (這就是延遲)
  • 吞吐量,比如一個 100車道,雖然路面坑坑窪窪,延遲雖高,但吞吐量依然可以很大
  • 降低了延遲後,原本100個車道的吞吐量,只需要 10個車道即可
  • 本文只記錄了如何降低延遲,沒有測試多併發時的吞吐量 —— 不用測,30000/s + 一定是了

小INK
2023-03-30 01:17
晚安,各位。

相關文章