OpenResty 高併發訪問 Redis:控制連線數,降低 P99 延遲
流量高峰期,經常會出現這樣的尷尬局面:業務平時在大流量下執行得非常絲滑,Redis 例項的 CPU 和記憶體也明明還有不少餘量,但在整點促銷或突發洪峰的關鍵時刻,閘道器到 Redis 的連線數卻突然暴增幾十上百倍,瞬間打滿配額甚至引發全鏈路“雪崩”;或者後端的訂單服務還能處理更多請求,使用者卻因為閘道器側的會話查詢變慢,遲遲刷不出頁面。對於依賴 Redis 做身份鑑權、高頻限流和實時狀態校驗的業務來說,這兩類瓶頸會直接轉化為系統穩定性風險、雲資源成本和使用者體驗問題。
技術團隊往往需要權衡:能否在不盲目升配 Redis 例項的前提下,徹底消除突發流量下的“連線風暴”,同時讓更多使用者在高峰期順暢地完成操作? 要解決這個矛盾,既要看客戶端在流量洪峰下如何控制連線規模,也要看高併發下查詢的吞吐量與尾延遲(P99)。
為此,OpenResty 提供了兩個高效能 Redis 私有庫,分別針對單例項和叢集部署:
| 部署方式 | 客戶端 | 核心價值 |
|---|---|---|
| 單例項 Redis | lua-resty-redis-fast | 連線數不隨業務併發增長,避免突發連線雪崩與配額耗盡,大幅提升讀取效能 |
| Redis Cluster | lua-resty-redis-cluster-fast | GET 吞吐達到開源客戶端的 7.14 倍,P99 延遲降至 1 毫秒內 |
平時執行絲滑、關鍵時刻卻“雪崩”?斬斷連線暴增與配額焦慮
先看最容易在關鍵時刻“掉鏈子”的連線數問題。
不少團隊都踩過這樣的坑:業務日常訪問量已經很大,閘道器與 Redis 配合得十分順暢;可一旦遇到秒殺、突發流量,或者網路出現輕微抖動,整個服務就會在短短几秒內迅速癱瘓。
這背後的根源,在於傳統客戶端採用了“單請求獨佔連線、用完歸還連線池”的模式。平時請求快去快回,幾十個長連線不斷輪轉複用就能扛住很高的 QPS;但在關鍵時刻,一旦併發流量突然放大,或者某次響應稍有延遲,在途請求沒來得及把連線還回池中,後續湧入的請求就會瞬間觸發高達幾十上百倍的“新建連線風暴”,進而引發連鎖雪崩:
- 本地埠耗盡,連不上服務端:瞬時爆發的海量新建連線,會迅速耗盡閘道器機器的本地可用埠(Ephemeral Ports),導致後續請求直接報錯、無法連線 Redis。
- 服務端忙於建連,整體響應變慢:Redis 服務端瞬間湧入大量新建連線請求,處理連線接入的開銷劇增,直接拖慢了正常讀寫命令的響應速度。
- 失去長連線複用,單次請求變慢:相比直接複用已有的長連線,新建連線必須經歷完整的 TCP 握手與鑑權流程,完成單次 Redis 請求的耗時大幅增加。
- 超時重試疊加,最終導致雪崩:由於不能及時回覆客戶端請求,上游或使用者端等待超時後提前斷開,並立即發起新的重試請求;重試流量進一步推高併發與新建連線數,形成惡性迴圈,最終導致業務徹底雪崩。
除了引發單點雪崩,這種不可控的連線數激增在多業務共用 Redis 的架構中還會帶來嚴峻的配額與成本焦慮。為了防範閘道器在高峰期突然吸乾連線數、波及同例項的核心交易服務,團隊要麼在跨部門協調連線配額時捉襟見肘,要麼只能趕在大促前加錢升配 Redis 例項——哪怕此時 Redis 的算力和記憶體根本沒用完,僅僅是被峰值連線數卡住了脖子。
在鑑權、限流、會話校驗等常規讀寫場景中,使用 lua-resty-redis-fast 可以從根源上斬斷這一雪崩鏈條——其佔用的連線數不會隨業務併發量的增加而增長。 只要閘道器自身的部署規模(機器數與 Worker 數)不變,哪怕突發線上請求翻倍,連線數也保持穩定,不會觸發海量新建連線。
這意味著,面對突發洪峰,閘道器既不會因為瘋狂新建連線而耗盡本地埠、拖垮 Redis 響應,也不會在關鍵時刻打爆連線配額。如果現有 Redis 例項的 CPU 和記憶體仍有餘量,換用單例項私有庫後,團隊便有望在現有的連線配額內穩穩承接峰值流量,省下單純為了“買連線數上限”而升配例項的預算。(注:這裡需區分“業務併發增長”與“閘道器擴容”——若後續增加了閘道器節點或 Worker 數量,總連線數需求仍需按新規模重新計算。)
此外,lua-resty-redis-fast 沿用了開源 lua-resty-redis 的常用 Lua 介面,方便存量業務平滑評估與遷移;具體支援範圍參見單例項版接入文件。
前置查詢變慢,使用者等的是頁面和操作結果
控制住連線數規模,解決的是關鍵時刻“不因建連風暴而雪崩”和“不超配額”的問題;而在日常高峰期,每一次查詢“能不能瞬間完成”,則直接決定了使用者的等待時間。這一點對單例項和叢集部署同樣關鍵。
以閘道器層的登入態或令牌(Token)校驗為例。當使用者開啟訂單頁或提交操作時,閘道器必須先從 Redis 讀取會話或配額狀態,校驗透過後才能將請求轉發給後端服務。哪怕後端的訂單服務很空閒,只要閘道器這一步卡住了,請求就只能乾等。
使用者感知不到內部的鏈路細節,他們看到的只是頁面一直在轉圈、點選提交遲遲沒有響應。如果前置的 Redis 查詢耗時過長,擠佔了整條鏈路的超時預算,請求就會直接超時失敗,迫使使用者不斷重新整理重試。因此,最佳化閘道器側的 Redis 查詢,重點不僅在於讓單個介面跑出好看的分數,更在於保障核心業務流程的完成率。
在這裡,高吞吐和**低尾延遲(P99)**直接對應著兩個實際的業務收益:
- 吞吐量提上去,解決的是“進得來”:當閘道器查庫成為瓶頸而後端服務仍有餘量時,每秒處理更多查詢,就能消除入口處的擁堵,讓高峰期更多有效請求順暢地流向後端業務。
- P99 延遲降下來,解決的是“不超時”:壓縮慢查詢的耗時,能為後續的訂單處理等核心邏輯留出更充裕的時間視窗,減少因前置校驗過慢而拖垮整個請求的風險,讓使用者少一些漫長等待與重複嘗試。
兩組 GET 測試:吞吐大幅提升,P99 均壓至 1 毫秒內
當會話或狀態資料以鍵值(Key-Value)形式儲存時,閘道器最核心的操作就是高頻 GET。下面透過併發 GET 基準測試來觀察兩個私有庫的讀取表現(完整的請求耗時還包含網路與後續業務邏輯,需結合實際鏈路評估)。
我們將兩個私有庫分別與對應的開源客戶端進行同臺對比,下表列出了各組測試結果的中位值:
單例項版:GET 吞吐達到開源客戶端的 3.47 倍,P99 延遲降低過半。(對比基線為開源 lua-resty-redis v0.34)
| 指標 | lua-resty-redis-fast | 開源 lua-resty-redis |
|---|---|---|
| GET 吞吐 | 214,314 commands/s | 61,778 commands/s |
| GET P99 延遲 | 0.785 ms | 1.793 ms |
叢集版:GET 吞吐達到開源客戶端的 7.14 倍,P99 延遲從 6.8ms 降至 1ms 以內。(對比基線為開源 lua-resty-redis-cluster,保持相同的 Lua 併發數)
| 指標 | lua-resty-redis-cluster-fast | 開源 lua-resty-redis-cluster |
|---|---|---|
| GET 吞吐 | 192,848 commands/s | 27,019 commands/s |
| GET P99 延遲 | 0.972 ms | 6.821 ms |
兩組資料表明,私有庫在大幅拉昇 GET 吞吐量的同時,顯著削平了長尾延遲。這正好呼應了前文的兩個業務目標:為高峰流量拓寬入口通道,為後端業務處理留出充足時間。
測試說明:以上資料基於純 GET 基準測試,旨在反映客戶端自身的效能差異,未直接測量連線數節省比例。實際業務中的最終收益,還會受具體 Redis 命令、網路環境、讀取策略以及閘道器外其他鏈路瓶頸的影響。
使用叢集版時,還可根據業務對資料一致性的要求選擇讀取策略,具體配置見叢集版接入文件。
如果你的團隊正因為連線數配額見底而考慮升配 Redis,或者希望改善高峰期因前置查詢變慢導致的請求等待與超時,歡迎聯絡我們申請試用,在真實業務流量下評估它們能為您節省多少資源成本、提升多少響應體驗。
瞭解更多:同一條請求鏈路上的其他開銷
Redis 查詢只是閘道器處理請求的一環。當 Redis 查詢已經足夠快,但整體介面響應或伺服器負載仍不理想時,不妨排查一下時間和 CPU 是否消耗在了同一鏈路的其他環節上。在 OpenResty 私有庫總覽中,還有幾個常與 Redis 配合最佳化的方向:
- 會話資料或介面報文需要高頻解析 JSON:從 Redis 取出 JSON 格式的會話或配置資料後,閘道器通常需要立即解碼。如果火焰圖顯示 JSON 編解碼佔用了大量 CPU,可以延伸閱讀 jit.cjson:當 JSON 成為 OpenResty 服務的隱形瓶頸,透過加速解析為閘道器例項騰出更多處理業務流量的算力。
- 閘道器需同時向 Kafka 非同步上報日誌或業務事件:如果閘道器在轉發請求的同時還要承擔風控事件、訪問日誌的採集上報,就必須防止上報抖動拖慢主鏈路。lua-resty-kafka-fast 針對 OpenResty 寫入 Kafka 的場景進行了深度最佳化,可在保障高吞吐資料採集的同時,嚴格控制對使用者請求響應的影響。
- 突發流量已逼近閘道器自身的 CPU 極限:當內部查詢與解析都已最佳化到位,但外部洪峰流量依然超出當前機器的承載上限時,可以關注 lua-resty-limit-traffic-dynamic。它支援根據 CPU 利用率目標動態調整 HTTP 限流閾值,在流量洪峰下保護系統水位,確保已放行的請求能夠順利完成。
這些私有庫分別針對序列化處理、訊息上報與動態流控,團隊可結合自身的效能瓶頸按需選配。完整的元件列表與接入指南可查閱私有庫文件。
關於作者
章亦春是開源 OpenResty® 專案創始人兼 OpenResty Inc. 公司 CEO 和創始人。
章亦春(GitHub ID: agentzh),生於中國江蘇,現定居美國灣區。他是中國早期開源技術和文化的倡導者和領軍人物,曾供職於多家國際知名的高科技企業,如 Cloudflare、雅虎、阿里巴巴,是“邊緣計算”、“動態追蹤”和“機器程式設計”的先驅,擁有二十餘年的程式設計及深厚的開源經驗。作為擁有超過 4000 萬全球域名使用者的開源專案的領導者,他基於其 OpenResty® 開源專案打造的高科技企業 OpenResty Inc. 位於美國矽谷中心。其主打的兩個產品 OpenResty XRay(利用動態追蹤技術的非侵入式的故障剖析和排除工具)和 OpenResty Edge(最適合微服務和分散式流量的全能型閘道器軟體),廣受全球眾多上市及大型企業青睞。在 OpenResty 以外,章亦春為多個開源專案貢獻了累計超過百萬行程式碼,其中包括 Linux 核心、Nginx、LuaJIT、GDB、SystemTap、LLVM、Perl 等,並編寫過 60 多個開源軟體庫。
關注我們
如果您喜歡本文,歡迎關注我們 OpenResty Inc. 公司的部落格網站。也歡迎掃碼關注我們的微信公眾號:















