小紅書自研keyless支持HTTPs卸載

本文系統介紹了小紅書基礎技術團隊自研的 keyless 架構實現,主要涵蓋幾個方面:Intel QAT 硬件選型與性能調優、Rustls 異步化支持,高性能 keyserver 實現等,該方案已經承接了小紅書自建 IDC 公網接入層流量,在大幅提升 HTTPs 處理能力的同時,降低了服務器資源成本。方案的整體思路和技術實現,對業界有類似 HTTPs 卸載需求的場景,也具備很大的參考意義。
01、背景
隨著小紅書自建 IDC 持續建設,自建公網接入層逐漸承接了線上流量,面臨著端上數百萬級別 QPS 請求壓力。端上流量主要包含兩大類:HTTPs(基于 TLS 1.3)和 HTTP/3(基于 QUIC),都涉及私鑰簽名操作,該操作是 TLS/SSL 握手中比較慢的一個環節,需要占用較多服務端 CPU 資源。
在這樣的背景下,接入層團隊通過自研 keyless 方案,將大量消耗 CPU 的私鑰 sign 操作,遠程卸載到配置 QAT 硬件的加解密集群,該方案提供了 TLS 加速能力的同時,大幅度降低資源成本,解決了堆砌大量機器應對非對稱加解密的困境,同時保持接入層的彈性部署能力。
02、硬件基礎
2.1 QAT 介紹
Intel CPU 內置很多加速器,其中,QAT 可以用來大幅度加速 CPU 網絡處理性能,包括:編解碼、壓縮與解壓縮、對稱與非對稱加解密等,不同的 CPU 架構、QAT 加速器性能存在一定差異:


2.2 硬件選型
這里也分享一個硬件選型的經驗:并不是 QAT 設備越多、性價比越高,這里針對 4516Y+ 和 6554S 兩款 CPU 做一個對比:

Intel 4516Y 在設計上是 MCC(單 Die 架構),QAT 加速器性能在加解密性能上超過 XCC(多 Die 架構),Intel 6554S 雖然內置了 8 * QAT ,并不一定比 4516Y 的 2 * QAT 性價比更高。
QAT Engine(Quick Assist Technology Engine) 加速分為「硬件加速」和「軟件加速」兩部分,內置的加速機制會優先使用硬件加速,QAT 硬件加速滿載后自動切換到軟件加速。
在實際硬件選型中,需要綜合考慮 QAT 資源配比、硬件采購價格、整機吞吐能力等因素,從而得到性價比最好的機型選型。
2.3 性能調優
這里介紹幾個與 QAT 相關的調優選項:
- QAT Engine 開啟 HW 和 SW 加速,內置加速機制實現自動切換,提升節點資源利用率:
https://github.com/intel/QAT_Engine/blob/master/docs/config_options.md#qat_sw-options - QAT Engine 內部默認使用全局內存鎖,導致多核擴展性比較差:
https://github.com/intel/QAT_Engine/issues/138 - QAT 驅動調整 ServicesEnabled 配置,去掉不需要的模式,節省硬件資源和 CPU 占用:
https://intel.github.io/quickassist/PG/configuration_files_generalsection.html?highlight=servicesenabled - QAT Engine 支持開啟 debug 模式,可以輸出完整的日志信息,便于調試和問題定位:
https://github.com/intel/QAT_Engine/blob/master/docs/config_options.md#qat_sw-options
03、整體架構

keyless 架構整體分為兩個部分,keyclient 和 keyserver:
- keyclient 實現非對稱加解密操作的異步化:
a. keyless 協議:通過 keyless protocol 消息與 keyserver 交互;
b. TLS 異步化:借助 Rust 語言優勢,實現異步化私鑰 sign 操作。 - keyserver 實現用戶態高性能網絡服務端:
a. keyless 協議:處理 keyclient 側請求的 keyless protocol 消息;
b. 異步任務調度:充分利用 CPU 并行能力,高性能處理卸載請求;
c. 加解密計算卸載:基于 Intel QAT 卸載加解密、降低 CPU 成本。
04、實現方案
4.1 keyless 協議
keyless protocol 用于 keyclient 和 keyserver 之間通信,沿用 cloudflare 所定義的格式能夠滿足需求:

4.2 keyclient 側
keyclient 基于 Rust 語言開發,通過修改 rustls 標準庫,使其提供 TLS 異步模式,從而支持 QUIC-TLS 、TCP-TLS 協議卸載能力,具備 keyless 遠程卸載、本地卸載兜底等能力,充分保證功能高可用:

4.3 keyserver 側
4.3.1 模塊分層
考慮到 openssl async 模塊與 QAT Engine 高效交互、高性能網絡處理、異步任務調度等因素,內部在對比調研后,采用自研 keyserver 實現,最大程度做到高性能處理:

1. keyserver 層:多線程 epoll,高性能接收 RPC 消息、處理 QAT 回調事件;
2. openssl 層:借助 fiber 機制將加解密操作異步化、調用 libcrypto 計算;
3. QAT 驅動層:將加解密操作放入硬件隊列,完成后回調通知上層應用;
4. QAT 設備層:硬件加解密計算,中斷通知 QAT 驅動,進而傳遞到應用層。
4.3.2 異步框架
4.3.2.1 任務抽象
openssl 通過 ASYNC Job 提供了異步處理機制,一個 job 代表一個協程,在 SSL 卸載場景下,一個 job 代表一次調用 QAT 硬件加速卡操作,此協程可以執行開始、掛起、釋放等操作,相關接口如下:

ASYNC_start_job 和 ASYNC_pause_job 是最常使用的兩個接口:前者用于開始一個 job,或者恢復一個 job,后者用于暫停 job(該協程會被 yield,切換到其他協程)。
4.3.2.2 通知機制
某個 job 被暫停、如何觸發調度 job 重新運行,以及 job 完成,如何通知上層事件完成:
1. eventfd
常用接口如下:

- 用戶態代碼創建一個 fd,調用 ASYNC_WAIT_CTX_set_wait_fd() 將 fd 加入到 ASYNC_WAIT_CTX 的 fds 中,一般在 ASYNC_pause_start() 之后、ASYNC_pause_job() 之前調用。
- 用戶態代碼通過對應的 get 函數獲取到這個 fd,并將其加入 epoll 中,感知到 fd 上的 EPOLLIN/EPOLLOUT 事件,從而恢復被暫停的 job 。
2. callback
當 QAT 設備完成異步操作之后調用回調函數去通知用戶代碼,回調函數需要是小的且非阻塞,常用接口如下:

3. 總結
無論是通過寫event fd、還是調用 callback,都是借助 QAT 驅動進行的,卸載操作的完成通知都是從底層 QAT 設備回傳到用戶態:
- QAT設備: 中斷 -> QAT Driver/Library: Callback (write fd/callbackFn) -> keyserver (epoll輪詢事件)。
4.3.3 QAT加速
涉及到跟 openssl、QAT engine 的交互處理,libcrypto 里實現了相對完整的異步框架,對上層屏蔽了較多的 QAT 交互細節,keyserver 也基于 libcrypto async 框架實現:

單次 sign 卸載操作對應的異步處理過程,如下圖所示:

- keyserver 接收 RPC 消息,需要異步操作:
a. 啟動 ASYNC_start_job 開啟一個 job、切換到 job 執行;
b. 針對當前 job/ctx 設置 async fd,用于事件完成通知操作。 - 進入 event lop 循環,監聽 fd 上的 EPOLLIN/EPOLLOUT 事件或者 QAT 通過 callback 回調,通知應用層事件完成。
- keyserver 回復 RPC 消息,回收 async fd 資源、釋放 job。
05、性能收益
單 keyserver 節點,支持 30w+/s 的 sign 卸載操作,這里包含「硬件加速」和「軟件加速」兩部分,此時兩個 QAT 設備滿負載、CPU 加速跑滿 32 個物理核:

內部經過對比測試,與 rustls 純軟件處理 TLS 相比,轉發成本降低5倍以上。
06、總結展望
keyless 架構最初由 cloudflare 提出,在業界已經有過不少實踐,但在實際場景落地過程中,仍面臨著一些技術挑戰:傳統的 TLS 庫難以實現異步化、QAT 加速缺少成熟的開源項目作為參考等,導致 keyless 卸載落地有一定的門檻。
當前方案是基于「標準 keyless 協議」 + 「Rust 支持 TLS 異步化」 + 「QAT 卸載高性能 keyserver」,能夠給業界提供一些比較有價值的參考,后續還會對當前方案做進一步的完善和迭代:
- keyless 實現優化:優化為基于 UDP 實現,減少 TCP 鏈接帶來的通信開銷;
- keyserver 性能優化:內存以及文件描述符等資源池化、減少系統調用開銷;
- 支持 QUIC 場景:底層 QUIC-TLS 異步化、sign 操作遠程卸載到 keyserver。
未來也計劃將內部代碼開源,包括:支持 TLS 異步版本的 rustls 庫、支持 QAT 卸載的 keyserver 等。
07、作者簡介
Core Contributors
霧行
網絡系統方向
克林
網絡系統方向
小宗
網絡系統方向
軒宇
接入網關方向
露卡
接入網關方向
08、參考
QAT Engine:
https://github.com/intel/QAT_Engine
QAT manual:
https://intel.github.io/quickassist/index.html
QAT resources:

































