https://github.com/apache/kafka/pull/17474
背景故事
這期延續之前的telemetry
題目,大家有沒有想過說既然要支援成千上萬的客戶端metrics
,伺服器端要怎麼知道哪個metrics
是哪個客戶端呢?會不會把不相關的客戶端metrics
混在一起?當然,這是一個合理的擔心,所以伺服器端其實會為每個telemetry
的使用者產生一個唯一識別碼,而這個使用者在上傳metrics
的時候就要順便說一下識別碼,好讓伺服器端不會把metrics
搞混在一起。簡單來說流程是這樣:
n
次來訪帶著識別碼和metrics,伺服器把metrics
依照識別碼分門別類等等,成千上萬的客戶端識別碼要怎麼存放?記憶體嘛?不會爆炸嘛?這個擔憂也是合理的,目前的設計簡單使用一個上限值再加上快取清除的功能,藉此不要打爆記憶體同時也能把已經沒在活耀的客戶端踢出。聽起來好像考慮的蠻周全,那麼這個題目要處理什麼呢?那就是客戶端可能因為網路的關係,導致短時間大量的重複連線,在這個狀況下會不斷的產生新的識別碼,這些識別碼就會排擠到正在使用中的識別碼,進而導致其他客戶端遇到大量的快取失誤。
解決辦法
既然已經知道要針對的問題,那自然一個直覺就是如果這個連線在識別碼返回時就斷線,我們就可以直接把他視為詭異的行為,然後馬上剛剛產生的識別碼註銷掉。這個方法很直覺但其實需要改動不少的程式碼,因此在打這篇文章的時候,小編想到另一個解法,以下就是把英文機翻回中文的內容:
我認為這個‘短暫的時間段’是由於意外的連接問題引起的,而不是由於惡意客戶端,因為防止惡意客戶端是另一個問題。導致達到緩存限制的根本原因是 ClientMetricsManager 為‘短暫的時間段’創建了許多無意義的 clientInstanceIds,因為它們的 GetTelemetrySubscriptionsRequest 沒有包含有效的 UUID。也許我們可以更新協議,要求 GetTelemetrySubscriptionsRequest 必須包含一個客戶端實例 ID?在 KIP-1082 中,我們同意客戶端能夠生成 UUID。通過這種方式,ClientMetricsManager 不再會為短暫時間段創建無意義的 clientInstanceIds,因為它們將始終使用相同的 UUID(作為一種實體標識)。
大家對於這兩個解法有什麼想法呢?你更偏好哪一種呢?歡迎上社群一起討論!
廣告
歡迎訂閱全臺最鬆散的開源社群源來適你,上面不定期會有各種開源的廢文。也歡迎參加全臺最鬆散的開源討論頻道,上面有一群網友一起在刷開源技術