背景
公司有個專案,需要一個高可用快取服務。
之前通訊技術選型時,測試過 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
虛擬機器互動 85ms,吞吐量 20/s
虛擬機器ping延遲 1ms —— ping 一來一回也就 1ms, 沒理由 TCP 一來一回 85ms 啊
使用非同步程式碼最佳化後(沒啥用)
本機互動 0ms,吞吐量 7000/s
虛擬機器互動 85ms,吞吐量 20/s
會不會是 Linux 的問題?換成 Win10 和 Win10 互動還是鳥樣
找到關鍵最佳化程式碼
虛擬機器互動 0ms
最終吞吐量 800/s
至此,執念已消,總結:
最終最佳化後的程式碼,依然選用回撥非同步
真正其決定性作用的引數是這個 NoDelay
TCP的 吞吐量 和 延遲 區別
- 延遲,比如一個單車道,路面坑坑窪窪 一輛車一來一回 100秒,路面平整 一輛車一來一回 10秒 (這就是延遲)
- 吞吐量,比如一個 100車道,雖然路面坑坑窪窪,延遲雖高,但吞吐量依然可以很大
- 降低了延遲後,原本100個車道的吞吐量,只需要 10個車道即可
- 本文只記錄了如何降低延遲,沒有測試多併發時的吞吐量 —— 不用測,30000/s + 一定是了
小INK
2023-03-30 01:17
晚安,各位。