首頁 > 後端開發 > Golang > 主體

ThrottleX:毫不費力地擴展到每秒一百萬個請求

Patricia Arquette
發布: 2024-10-22 14:59:03
原創
594 人瀏覽過

如果你想親自測試一下,請向下滾動! !

簡介:

每秒處理數百萬個請求?這可能嗎? ?

當我們談論大規模分散式系統時,事情可能會變得…複雜。您知道該怎麼做:速率限制對於防止濫用至關重要,但它經常成為瓶頸。如果我告訴您我們設計了一個可以順利處理每秒 100 萬個請求的系統怎麼辦?來認識一下 ThrottleX,我用 Go 寫的開源分散式速率限制函式庫。

在這篇文章中,我將拉開帷幕,向您展示我們如何實現這令人驚嘆的規模。我將帶您了解高級優化、使這一切成為可能的 Go 並發模型,甚至是我們在過程中遇到的一些令人驚訝的瓶頸。但這不僅僅是理論——我將分享我們達到的真實基準。繫好安全帶,因為我們即將突破一些限制! ?


第 1 部分:挑戰 – 為什麼規模很重要

縮放速率限制是看似簡單的事情之一,直到您嘗試以極端的規模進行操作。大多數系統每秒處理數百或數千個請求都沒有問題。但當你達到數百萬個請求時,事情很快就會崩潰:

  • 記憶體管理問題 ?
  • 網路瓶頸 ?
  • 併發惡夢 ?

技巧不僅僅是限制速率 - 它可以在多個節點上高效地,確保以閃電般的速度處理每個請求,而不消耗所有可用資源。這就是 ThrottleX 的用武之地。專為速度而生,為規模而設計,它結合使用速率限制演算法和即時優化來保持領先地位。

但是為什麼這很重要呢?讓我們來看看一些現實世界的場景:

  • 重負載下的API:您的API 是應用程式的支柱,當流量激增時(您好,病毒式傳播時刻!?),您需要一種方法來處理流量湧入,而又不影響所有內容。
  • 分散式微服務:當服務依賴外部 API 時,確保數百萬個請求的一致性能可以維持整個系統的穩定。
  • 雲端規模應用程式:使用雲端基礎設施,您需要在管理不可預測的工作負載的同時優化成本 - 這就是有效的速率限制可以節省時間(以及您的雲端帳單?)的地方。

ThrottleX 不僅僅是任何速率限制器 - 它專為極端條件而設計,我將向您展示我們如何將其推向極限。


第 2 部分:分解 – ThrottleX 的架構

ThrottleX 的核心是智慧速率限制演算法和高度最佳化的並發模型的組合。但這不僅僅是演算法——而是它們的實作方式以及我們如何使它們在分散式環境中可擴展。讓我們深入研究使這一切順利進行的核心架構。

1.魔法背後的演算法

說到速率限制,你可能聽過經典的:

  • 令牌桶:允許突發流量,但以穩定的速率重新填充令牌。
  • 滑動視窗:隨著時間的推移平滑流量,在滑動時間間隔內計算請求。
  • 漏桶:把它想像成一個有洞的桶子-請求以穩定的速率「洩漏」。

ThrottleX 不會重新發明輪子,但我們採用了這些久經考驗的演算法,並使它們更聰明。方法如下:

  • 動態速率限制:我們實現了一個靈活的系統,速率限制可以根據流量狀況即時調整。如果流量突然激增,ThrottleX 可以在不過度節流的情況下處理負載,從而實現最佳吞吐量。
  • 併發處理:處理並發請求時,速率限制可能特別棘手。我們使用互斥鎖來確保不會發生競爭條件,同時仍允許最大並發性。

2. Go 並發模型 – 秘密武器

ThrottleX 內建於Go 中的原因之一是它的goroutineschannels,它們以最小的開銷為我們提供了瘋狂的並發性。這就是為什麼 Go 的並發模型改變了我們的遊戲規則:

  • Goroutines 很便宜:與傳統線程不同,Goroutine 的記憶體佔用很小。這意味著我們可以在不破壞系統資源的情況下產生數百萬個它們。
  • 非同步處理:透過非同步處理請求,我們避免了阻塞操作。這是在高流量下維持 ThrottleX 反應能力的關鍵。每個請求都在自己的 goroutine 中處理,通道促進它們之間的通信以實現順利協調。

通俗地說,這就像擁有一條超高效的裝配線——每個工人(goroutine)都在做自己的工作,而不需要等待其他人完成。

3.使用 Redis 進行分散式儲存最佳化

分散式速率限制器需要共享狀態,這就是 Redis 發揮作用的地方。但我們不能只是插入 Redis 就結束了——我們必須優化它:

  • 金鑰過期策略:Redis 為每個速率受限的用戶端儲存鍵值對,但為這些金鑰設定有效的過期時間至關重要。如果密鑰過期的速度不夠快,就會浪費記憶體;太快了,您就會忘記速率限制。我們微調了TTL(生存時間),以確保我們達到記憶體效率和準確性之間的最佳平衡點。
  • 最小化Redis延遲:Redis已經很快,但在重負載下,延遲峰值仍然可能出現。我們透過調整管道複製設定進行最佳化。這讓我們每秒推送更多請求,同時控制資料庫延遲。

4.批量請求以提高效能

我們用來擴充的另一個技巧是批次請求。 ThrottleX 不是單獨處理每個請求,而是在後台將它們批次在一起。這減少了存取 Redis 後端的操作數量,從而減少了往返次數並提高了吞吐量。

將其想像為透過郵件寄送包裹。您不必每次都去郵局取信,而是等到收到一堆信後再一次將它們全部發送出去 - 節省時間和精力。


這種架構建立在 Go 的強大功能和最佳化的 Redis 配置之上,使 ThrottleX 能夠高效處理海量流量負載。最好的部分是什麼?這一切都旨在透過最少的調整進行擴展,因此無論您是處理數千還是數百萬個請求,ThrottleX 都能滿足您的需求。


第 3 部分:百萬請求秘密 - 關鍵最佳化

那麼我們如何真正推動ThrottleX來處理每秒一百萬個請求而不導致系統崩潰或破壞基礎設施?這歸結為一系列精心設計的最佳化,包括速率限制演算法和底層系統架構。這是秘密醬汁:

1.批次請求以實現高吞吐量

最大的遊戲規則改變者之一是批次請求。我們沒有單獨處理每個請求,而是將它們分組。這大大減少了存取後端 (Redis) 的操作數量,從而減少了往返次數、降低了延遲並提高了吞吐量。

換句話說,這就像在通常處理十個請求的時間內處理一百個請求一樣。在我們的基準測試中,僅此最佳化就使吞吐量增加了 50%。

2.防止過載的斷路器

當您處理如此規模的流量時,事情可能而且一定會出錯。為了防止 ThrottleX 在流量高峰期間被淹沒,我們實施了 斷路器模式

工作原理如下:

  • 如果下游服務(如 Redis 或客戶端服務)開始延遲或失敗,斷路器將跳脫,立即停止對該服務的請求。
  • 這可以防止過載,讓系統正常復原而不會崩潰。
  • 問題解決後,斷路器將“重置”,交通將再次正常流動。

這種設計有助於保持高可用性,即使在系統的高負載或臨時故障下也是如此。如果沒有它,當 Redis 複製滯後或流量意外激增時,ThrottleX 就會崩潰。

3.記憶體效率 – 最佳化 Goroutine 與池化

並發是一把雙面刃。雖然 Go 的 goroutine 是輕量級的,但它們仍然需要記憶體管理。隨著我們的擴展,垃圾收集 (GC) 過程成為了瓶頸 - 侵蝕了我們的效能,尤其是在重負載下。

我們的解決方案? 池化資源:

  • 我們盡可能重複使用 goroutine,減少記憶體佔用並最大限度地減少 GC 開銷。
  • 我們也為常用的資料結構實作了自訂記憶體池,以防止不斷的記憶體分配和釋放。

結果呢? 記憶體使用量減少 30%,並且在流量爆發期間表現更加流暢。

4. Redis 管道最佳化

為了確保 Redis 能夠跟上海量請求負載,我們對管道化功能進行了微調。我們沒有一次將每個命令發送到 Redis(這會引入延遲),而是將多個命令捆綁在一起形成一個單一請求。這使得 Redis 能夠並行處理批次命令,從而大大縮短回應時間。

Redis 管道的神奇之處在於它最大限度地減少網路 I/O 並提高吞吐量。透過此最佳化,Redis 能夠以亞毫秒延遲每秒處理數百萬個請求。

5.自適應速率限制

我們透過使其自適應將速率限制提升到了一個新的水平。 ThrottleX 不是一律使用固定速率,而是可以根據即時流量狀況動態調整速率限制。

想像一下:在正常流量期間,系統允許一致的請求流。但在突然高峰期間(例如,電子商務網站上的限時搶購或病毒式應用程式時刻),ThrottleX 將暫時放寬限制,允許更多流量通過,而不會過度限制。一旦峰值消退,它會自動將速率調低。

這種自適應方法可確保合法用戶在流量高峰期間不會受到限制,同時仍保護您的後端免受濫用。

6.即時指標與監控

我們想要超越速率限制 - 我們想要可見性大規模發生的事情。為此,我們將即時監控PrometheusGrafana等工具整合。這使我們能夠追蹤關鍵指標:

  • 請求吞吐量(RPS – 每秒請求數)
  • 錯誤率
  • Redis 延遲
  • Goroutine 使用

這些見解使我們能夠儘早發現效能瓶頸,並在問題出現之前對系統進行微調。透過顯示即時流量和系統運作狀況的儀表板,我們甚至可以在尖峰負載期間監控 ThrottleX 的效能。


這些最佳化共同作用,解鎖了處理每秒 100 萬個請求的能力。從批次和管線到記憶體優化和自適應速率限制的每項調整,都將 ThrottleX 進一步推向超大規模領域。 ?


第 4 部分:真實基準 – 證明它或失去它

說實話:談論最佳化很容易,但證據總是在數字中。經過多輪壓力測試、基準測試和微調後,以下是我們透過 ThrottleX 實現的真實指標

基準設定

我們使用以下設定來執行測試:

  • 環境:具有 5 個節點的分散式系統設置,每個節點運行在具有 16GB RAM 的 4 核 CPU 上。
  • 後端:用於跨節點共享狀態的 Redis,透過管道和最佳化金鑰過期進行微調。
  • 流量負載:我們模擬了高達每秒 100 萬個請求,包括常規流量模式和突發流量模式。
  • 工具:用於監控的 Prometheus 和用於指標即時視覺化的 Grafana。

現在,進入有趣的部分。以下是結果

1.吞吐量 – 每秒 100 萬個請求

  • 每秒請求數 (RPS):我們在多個節點上始終處理 100 萬個 RPS
  • 峰值流量:在突發情況下,ThrottleX 處理了高達 120 萬 RPS 的流量峰值,而性能沒有任何顯著下降。

ThrottleX 處理此負載,同時保持低延遲和全面最小的資源消耗。

2.延遲 – 亞毫秒反應時間

處理分散式系統時,尤其是在這種規模下,延遲始終是一個問題。然而,ThrottleX 始終如一地提供亞毫秒級響應時間,即使在極端流量下也是如此。

  • 平均 Redis 延遲0.7 毫秒
  • 平均請求延遲0.8 毫秒

得益於 Redis 管道和批次請求等優化,我們最大限度地減少了資料庫的往返次數,將延遲保持在 1 毫秒以下。

3.記憶體效率 – 記憶體使用率降低 30%

透過最佳化協程記憶體池,與傳統的速率限制器相比,我們實現了記憶體使用量減少30%。詳細介紹如下:

  • Goroutine Pooling:減少產生數百萬個並發請求的開銷。
  • 自訂記憶體池:大幅減少流量突發期間的分配數量,從而實現更穩定的效能和更少的垃圾收集暫停。

即使系統中有數百萬個請求,ThrottleX 仍然保持記憶體高效,保持較低的資源消耗。

4.錯誤率 – 低於 0.001%

如果系統到處拋出錯誤,那麼處理海量流量還有什麼意義呢?幸運的是,ThrottleX 提供了堅如磐石的可靠性:

  • 錯誤率:即使在尖峰負載條件下,失敗或不必要的限制的請求也少於 0.001%

這種可靠性證明了我們的自適應速率限制斷路器模式的有效性,這有助於防止系統過載和級聯故障。


這些基準測試不僅在紙面上令人印象深刻,它們還得到了現實世界壓力測試的支持,並表明ThrottleX能夠在不影響性能的情況下處理極端流量負載。

這是最好的部分:你可以自己嘗試! ?


自己試試看

我用於這些基準測試的所有程式碼和配置都可以在 ThrottleX 儲存庫 中找到。分叉它,運行您自己的測試,看看是否可以進一步推動它。這個專案是開源的,我總是很高興看到社群可以帶來什麼。無論是改進演算法還是優化以獲得更高的吞吐量,我都歡迎貢獻和想法。

連結到此範例應用程序,監控程式碼:https://github.com/neelp03/ThrottleX-Test

ThrottleX: Scaling to a Million Requests Per Second Without Breaking a Sweat


第 5 部分:經驗教訓 - 令我們驚訝的事情

建構能夠處理每秒100 萬個請求的過程是一次瘋狂的旅程,在此過程中,我們遇到了一些意想不到的挑戰,這些挑戰給我們帶來了寶貴的經驗教訓。以下是最讓我們驚訝的事情以及我們如何解決這些障礙。

1. Go 的垃圾收集 – 一個無聲的瓶頸

當我們第一次開始擴大規模時,我們注意到在流量繁忙期間回應時間會出現隨機峰值。深入研究這個問題後,我們意識到 Go 的垃圾收集 (GC) 正在默默地導致效能問題。

  • 問題:隨著數以百萬計的 goroutine 飛來飛去,GC 被頻繁觸發,導致暫停,影響延遲。
  • 修正:我們透過在可能的情況下實作自訂記憶體池重複使用物件來最佳化記憶體分配方式。這減少了 GC 週期的頻率並平滑了流量高峰期間的性能。

經驗教訓:儘管 Go 的記憶體管理在規模上是高效的,但您需要微觀管理記憶體以避免效能瓶頸。

2. Redis 複製延遲 – 隱藏的定時炸彈

雖然 Redis 速度很快,但在每秒處理數百萬個請求時,我們遇到了複製滯後。在大流量下,Redis 跨節點複製資料的能力跟不上寫入負載。

  • 問題:Redis 複製延遲導致主節點和副本節點之間的資料同步延遲,從而導致分散式系統之間的速率限制不一致。
  • 修復:我們降低了複製頻率並微調了 Redis,以在某些情況下支援高可用性而不是一致性。這為我們提供了更好的效能,但代價是偶爾出現過時的數據,但對於速率限制,這種權衡是可以接受的。

經驗教訓:Redis 是個野獸,但在大規模時,一致性和可用性之間的權衡對於保持高性能是必要的。

3.網路延遲 – 隱形殺手

在跨分散式節點進行測試時,我們發現網路延遲迅速增加,尤其是當請求必須跨區域傳輸時。從規模上看,即使幾毫秒的延遲乘以數百萬個請求也會導致嚴重的效能下降。

  • 問題:分散式速率限制涉及節點之間和返回到 Redis 的持續通信,甚至會增加微小的網路延遲。
  • 修復:我們透過本地化盡可能多的速率限制邏輯來優化系統,最大限度地減少訪問 Redis 的次數。透過首先在本地處理請求並且僅定期同步狀態,我們減少了對網路呼叫的整體依賴。

經驗教訓:最小化網路呼叫對於分散式系統至關重要。您對外部通訊的依賴越少,您的系統的彈性和速度就越快。

4.自適應速率限制 – 找到平衡

雖然自適應速率限制改變了遊戲規則,但在允許流量激增和維持保護之間取得平衡比預期更棘手。

  • 問題:一開始,速率限制調整得太激進,在峰值期間允許過多流量,從而導致暫時過載
  • 修正:我們調整了演算法以考慮長期流量趨勢,隨著時間的推移平滑速率調整。這防止了流量的劇烈波動,並在持續的流量激增期間為系統提供了更多的喘息空間。

經驗教訓:適應很強大,但需要微調以避免過度修正。調整太多和調整太少一樣危險。


建置與擴充 ThrottleX 告訴我們,大規模效能就是找到正確的平衡:平衡記憶體使用、網路延遲、複製和速率限制。每一次優化都涉及權衡,但每一次挑戰都促使我們建立一個更有彈性、更快的系統。


結論 – 輪到你了:進一步推動 ThrottleX

ThrottleX 現在是一款經過實戰考驗的分散式速率限制器,能夠處理極端的流量負載。但總有更多空間!無論您是想貢獻新功能、在不同條件下測試它還是調整它以獲得更好的性能,ThrottleX 存儲庫 都已開放並等待著您。

讓我們一起挑戰極限,看看我們能走多遠。

以上是ThrottleX:毫不費力地擴展到每秒一百萬個請求的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板