TECHNOLOGY / TENANT FAIRNESS
每條連線都很公平,為什麼同一個 Tenant 拿走八成頻寬?
假設公司只有一台咖啡機,兩個部門都要用。
A 部門派一個人排隊。
B 部門派四個人排隊。
如果每個人每輪都能接一杯,A 部門就拿到約兩成,B 部門拿到約八成。
A 部門問:
「不是說兩個部門公平分配嗎?」
管理員回答:
「每個排隊的人,機會都一樣。」
大家都在談公平。
只是公平的單位,沒有寫在同一份規格裡。

Connection 與 Tenant,是兩種分配單位
最近我完成了一個小專案:
tiny-fair-proxy
一個用 Rust 寫的實驗性 TCP Relay,加入有容量上限的資料緩衝區、背壓,以及 Tenant 加權位元組排程。
想研究的問題很具體:
同一個 Tenant 多開幾條 Connection,應不應該因此取得更多頻寬?
Connection 與 Tenant,是兩個不同的分配單位。
如果按每條 Connection 輪流給傳輸額度,多開連線的 Tenant,就可能取得較多份額。
這不代表排程器算錯了。
它可能非常認真地,執行了另一種公平。
共同觀察時窗中的份額
這次受控實驗中,A 開一條連線,B 開四條連線,每條連線各傳送 512 KiB 資料。
環境是 macOS ARM64 loopback,每個傳輸方向各自設定 512 KiB/s 的共同限速。
實驗涵蓋上傳、下載,以及 1:1、1:3 兩組 Tenant 權重。每種條件都比較兩種排程模式,保留三個隨機配對區塊,共 24 次試驗。
先看等權重的結果。
在開始後 0.4–1.4 秒的共同觀察時窗中,A 在接收端收到的位元組占比,中位數約為:
按 Connection 輪流排程:20%。
按 Tenant 加權排程:50%。
這裡比較的是競爭頻寬時的接收份額,不是整輪總資料量的占比。
五條連線各自要傳的資料量相同,所以整輪完成後,A 的總資料量仍占兩成。
至於包含最後尾段、直到所有連線完成的整體吞吐量,兩種模式則大致相近。
它沒有讓頻寬突然增加。
改變的是:競爭期間,既有頻寬分給了誰。
B 開四條連線,仍然是同一個 Tenant。
連線可以開四條,資源配額不會因此自動升職。
但公平,不一定代表平均。
所以實作也支援不同的 Tenant 權重。
權重相同,在雙方都有資料、目的端也能接收的競爭情境下,目標接近各半。
權重不同,就按設定比例分配。
如果某個 Tenant 暫時沒有資料,或目的端無法接收,不會讓它囤積未用的服務額度;其他 Tenant 可以使用空出的頻寬。
今天不喝咖啡,咖啡機也不用陪你休假。
先確認連線屬於誰
這裡還有一個關鍵問題:
排程器怎麼知道誰是哪個 Tenant?
這個小實作利用不同的監聽入口(listener),把連線分到指定的 Tenant,並轉送至固定 backend。
這是在受信任的本機實驗環境中,辨識連線歸屬的方式;它本身不驗證使用者身分。
它沒有解決「同一個人申請四個帳號」,也沒有防止別人冒用 Tenant。
如果分類本身不可信,再漂亮的排程比例,也保護不了原本想保護的對象。
緩衝、背壓與關閉期限
除了分配比例,實作還得處理資源與連線的生命週期。
Buffer 滿了,要暫停讀取並施加背壓。
接收端太慢,不能讓資料緩衝無限增加。
某一方向讀到 EOF,要先送完該方向的緩衝資料,再通知另一端;反方向仍可繼續傳輸。
連線量超出容量,要明確拒絕。
服務關閉時,則停止接受新連線,讓既有連線在期限內嘗試排空;到期仍可能中止,不保證全部交付。
畢竟,Graceful Shutdown 不是對所有工作說:
「你們慢慢來,我永遠等你們。」
Graceful 也需要截止時間。
量測範圍與資源承諾
這次量測有明確範圍。
它是在刻意限速的 loopback 瓶頸下,觀察位元組份額;不是在量測真實網際網路環境下的效能,也不是要和 NGINX、Envoy 或 HAProxy 比速度。
共同觀察時窗中的接收占比,不代表任意瞬間都精準符合權重,更不是應用程式請求的延遲保證。
記憶體量的是 Proxy 程序的取樣 RSS,排除 peer 程序與 kernel socket buffers,也可能漏掉短暫峰值。
Payload buffers 有界,不等於整套系統的所有記憶體成本都已被量到。
對我來說,這個實驗最有價值的地方,是讓「公平」變成可以檢查的問題:
我們要保護的是每條 Connection、每個 Tenant,還是每個 Request?
Tenant 分類是否可信?
權重由誰決定,什麼時候調整?
一方閒置時,其他人能不能使用剩餘資源?
過載時,拒絕與等待是否仍符合服務要求?
這些不是排程器能替管理者決定的事。
排程器負責執行規則。
我們負責確認,那套規則是否符合真正的資源承諾。
按 Connection 分配,不一定錯。
按 Tenant 分配,也不會自動解決所有公平問題。
先說清楚分配單位、權重與身分邊界,才有辦法判斷結果是否公平。
否則,系統可能每條規則都遵守了。
只是它分配資源的方式,和我們原本的承諾,沒有對上。