跳到正文
Hacker News (official RSS)(lavik.dev)·· 5 天前精選AI 評分79

將 300 節點 Redis 叢集縮減至 3 節點 Lavik:成本節省與效能提升

Migrate Your 300-Node Redis Cluster to Just 3 Lavik Nodes

AI 導讀
  • Lavik 0.1.0 透過 NVMe SSD 供應資料,單節點 1.14M GET/s,超過 Redis 8.10.2 的 1.02M GET/s。
推薦理由

本文詳細說明如何將 300 節點 Redis 叢集縮減至 3 節點 Lavik,並呈現成本節省與效能提升的實際資料,對於需要擴充代理狀態的工程師極具參考價值。

正文 · AI 翻譯

譯文尚未完整,完整內容請切換至原文。

記憶體已滿。CPU 還有空間。然而,下一次保留資料量的增加意味著又需要一個 Redis 分片、另一個副本,以及另一對伺服器來運作。對於容量受限的應用程式來說,這是一種昂貴的擴充方式。Lavik 改變了決定容量的資源:應用程式資料存放在 NVMe SSD 上,由一個引擎提供服務,該引擎測得每秒 1.14 百萬次 GET——比公開比較中的 DRAM 上 Redis 更快。這種組合開啟了更具吸引力的設計:將受記憶體限制的叢集集中於少數高儲存密度的主機,並為下一代代理狀態留出空間。[13][1]

300 Redis nodes in 150 primary–replica pairs, compared with a Lavik primary and follower on L16as_v4 plus an E2s_v4 Meta-only voter. The data nodes also run Meta members, giving three Meta votes and two dataset copies.
容量模型:300 臺 E2s_v4 Redis VM 與兩臺 L16as_v4 Lavik 資料 VM 以及一臺 E2s_v4 只做 Meta 投票的 VM。每臺 VM 都執行一個 Meta 成員;只有主節點和從節點持有資料集。[1][28][29]

1. 代理程式需要更多狀態——並且需要快速存取

人機介面應用程式可能會保留每位使用者的個人資料、會話以及一組功能。代理程式可以為研究助理、程式碼助理以及多個在使用者代表下執行的背景工作者保留所有這些資訊。每個代理程式會累積執行狀態、觀測結果和工作上下文。偶爾執行的代理程式在恢復時仍可能需要立即存取其狀態。容量隨代理數量、狀態大小以及其使用壽命增長;請求量不必以相同速度成長。[1]

以十億個代理為例,每個代理僅有 1 KB 的功能就會產生約 1 TB 的值。若提升至 10 KB,資料集就達到 10 TB;100 KB 時則達到 100 TB,還未考慮鍵、索引或複寫。應用程式仍需要透過熟悉的 Redis 客戶端與資料結構進行低延遲讀取與更新。將每個保留值都存放在昂貴的 DRAM 中,使得這種組合更難負擔。Lavik 的設計是為了讓 NVMe SSD 容量能實用於這些對延遲敏感的工作負載。[1][6]

一十億保留代理的值載荷 · 十進位單位
每個代理的位元組數唯一值載荷兩份副本,僅值
1 KB1 TB2 TB
10 KB10 TB20 TB
100 KB100 TB200 TB
來源與計算輸入[1]

2. 只為增加記憶體而新增伺服器

考慮 300 個 Standard_E2s_v4 Azure VM,每臺配備兩個 vCPU、16 GiB RAM,且沒有本機 SSD,配置為 150 個主節點與 150 個備援節點。此組合共購買 600 個 vCPU 和 4,800 GiB RAM,其中 2,400 GiB 位於主節點。當記憶體首先填滿時,擴充此組合會同時購買額外的 CPU、網路與作業系統,主要是為了取得更多 RAM。應用程式可能需要保留更多使用者檔案或延長會話存活時間,而不必相應增加更多計算資源。這是 Redis 成本最佳化的核心機會:獨立於處理器需求,選擇儲存密度。[1][28]

請為兩個部署使用相同的 Azure 區域與採購模式:East US 2、Linux 按使用付費,貨幣為美元。Microsoft 的零售價格為 Standard_E2s_v4 每小時 $0.126,Standard_L16as_v4 每小時 $1.376。以每月 730 小時計算,300 個 Redis VM 的費用為 $27,594。Lavik 使用兩臺 L16as_v4 資料 VM 與一臺較小的 E2s_v4 投票機,月總費用為 $2,100.94。每臺資料 VM 包含 16 個 vCPU、128 GiB RAM 以及 3.84 TB 本機 NVMe SSD;投票機不需要本機 SSD 或資料集複製。[27][28][29][1]

加入快閃記憶體並不會自動解決延遲問題。Redis 將 Flex 的快快閃記憶體取描述為毫秒級,並建議避免廣泛存取模式、大規模工作集以及頻繁在 RAM 與快閃之間移動。對於子毫秒延遲預算的應用而言,毫秒級快閃路徑太慢。頻繁重複檢視不同檔案與情境的代理工作負載使此區別具有重要意義:儲存引擎必須即使存取超出 RAM 時也能有效提供大型資料集。[25][26]

每月 VM 計費下降 $25,493.06(92.4%),年化節省為 $305,916.72。Lavik 的三臺 VM 在整個部署中提供 34 個 vCPU 和 272 GiB RAM,兩臺配備 NVMe 的節點處理資料,較小的 VM 完成故障轉移法定人數。Redis 的 300 臺 VM 提供 600 個 vCPU,對於記憶體受限的工作負載而言,許多 vCPU 可能不需要。儲存密度降低了服務艦隊,同時將投票機的角色分離可避免為額外資料大小的機器付費。表格列出兩個系統自託管 VM 的價格;作業系統磁碟、備份與流量為額外部署成本。[1][27][11][6]

Azure East US 2 · Linux 按使用付費 · 美元 · 730 小時/月。VM 小時費率識別每個 SKU;每月與每年成本涵蓋完整部署。
部署美元 / VM 小時每月美元每年美元美元 / 百萬次操作(平均 1M QPS)
Redis · 300 × Standard_E2s_v4$0.126$27,594.00$331,128.00$0.01050
Lavik · 2 × L16as_v4 + 1 × E2s_v4$1.376 (L16as_v4); $0.126 (E2s_v4)$2,100.94$25,211.28$0.00080
來源與計算輸入[27][1]

3. 以 NVMe SSD 建構容量

以兩臺 Standard_L16as_v4 VM 與一臺 Standard_E2s_v4 VM 建構 Lavik 部署。主機與追隨機各自擁有 16 個 vCPU、128 GiB RAM 以及四個 960 GB 本機 NVMe 裝置,總計每臺資料 VM 3.84 TB。每臺執行一個 Data 程式與一個 Meta 成員。E2s_v4 執行第三個 Meta 成員,使用兩個 vCPU 和 16 GiB RAM,完成三成員 Raft 法定人數以實現自動故障轉移。此僅投票機 VM 只儲存控制面元資料,非應用資料。拓撲結構包含兩份完整資料集與三個 Meta 投票機。[1]28296117

主節點和跟隨節點各自持有完整複本,因此單一複本容量基準仍為 3.84 TB。包含投票 VM 後,部署成本為每 TB 月 $547.12。Redis 的 150 個主節點提供 2,400 GiB,或約 2.577 十進位 TB,產生每 TB 月 $10,707.88。這些是容量標準化的 VM 成本,尚未包含資料庫開銷與作業空間預留。若主節點 VM 失效,跟隨節點與專用投票者保留三者之二 Meta 多數,以協調提升符合資格的跟隨節點。存活的跟隨節點持有剩餘資料複本;投票者提供控制平面參與。[1][27][11][7]

每 TB 主節點容量的每月 VM 成本(未包含資料庫開銷與運營空間)。複製容量僅計算一次。
部署單副本容量分母美元 / TB‑month
Redis · 300 × E2s_v42,400 GiB RAM(≈ 2.577 TB)$10,707.88
Lavik · 2 × L16as_v4 + 1 × E2s_v43.84 TB NVMe SSD$547.12
來源與計算輸入[1][28][29][27]

Lavik 在請求路徑中最有價值的地方使用 DRAM:鍵索引、元資料與活躍緩衝區。值則使用 NVMe SSD 容量。這將值位元組的增長與索引記憶體的增長分離,對於代理配置與保留上下文變得更大時尤其有用。RAM 的大小來自於應用程式的鍵數量與鍵長度,外加緩衝區、巨頁與複製後備。已發表的大型資料集實驗中,十億鍵佈局可容納於 125.8 GiB 主機,而其值佔據約一 TB。[9][13]

SPDK 明確化儲存路徑。Lavik 透過使用者空間的佇列對提交 NVMe 操作並輪詢完成,移除核心區塊 I/O 提交路徑及其系統呼叫與喚醒開銷。非同步請求在工作者進行其他命令時保持儲存工作在飛行。輪詢以 CPU 時間換取即時完成處理;佇列深度、完成批次與 CPU 放置決定該時間的有效利用。現代 NVMe 裝置提供平行佇列與內部併發。引擎必須提供足夠獨立工作以利用它們。[4][5][13]

Lavik 的 Bycorf 工作者使用協程、所有者本地可變狀態以及工作者之間的明確派遣。當一個命令等待儲存時,其他可執行工作可以繼續。所有權將常見操作保持在其修改的狀態附近,減少核心之間的協調。這在每秒一百萬次操作時尤為重要:少量的排程、同步或分配開銷會累積成相當大的 CPU 負荷。將執行與儲存一起設計,使 Lavik 能夠利用 SSD 並行性,而不必將每一次 I/O 轉變為停滯的請求處理執行緒。[6][8][9]

The optimizations extend through the request path. Eligible disk GETs can use an admitted index snapshot on the connection worker, avoiding owner dispatch when the fast path applies. Parsing handles batches of up to 128 commands, and small pipeline replies can coalesce into 64 KiB writes. Per-worker append streams avoid a staging-buffer allocation for every logical slot. Together, these choices reduce coordination, system calls and buffer overhead. The Redis-compatible interface stays familiar to applications; the implementation underneath is built around efficient concurrent storage access.[8][9]

Large objects receive the same attention. Lavik 0.1.0 supports grouped storage for Strings, Hashes, Sets, Lists, Sorted Sets and Streams. Large strings use 8 KiB segments, while collections use independently addressed groups. A focused operation can work on the relevant part instead of rewriting an entire large object. For an agent profile with frequently changing features and much larger retained state, that layout makes the difference between a small update and unnecessary work across the whole record. NVMe performance depends on both how I/O is scheduled and how much data each operation touches.[10]

RESP traffic enters coroutine workers, indexes remain in memory, and asynchronous SPDK queue pairs reach NVMe SSD; kernel TCP and Meta authority remain separate.
Lavik’s request path: coroutine workers, an in-memory key index and asynchronous SPDK I/O keep NVMe storage busy.[6][8][9][4]

4. Faster than Redis on DRAM—with values on SSD

The direct benchmark compares Lavik 0.1.0 SPDK with Redis 8.10.2 and Valkey 9.1.2 on the same 16-vCPU Azure server. A separate load generator issues uniform random GETs and SETs over private networking, with 1 KiB values and pipeline depth one. Redis and Valkey serve their values from DRAM; Lavik uses its NVMe storage path. The table shows throughput and client-observed latency together, so readers can choose an operating point against their application’s latency budget.[13]

At 1,280 connections, Lavik delivers 1,145,772 GET QPS and 971,950 SET QPS. GET throughput is 12.5% higher than Redis and 18.1% higher than Valkey; SET throughput is 2.2% higher than Redis. Lavik’s GET P99 at that point is 3.999 ms, compared with Redis’s 4.415 ms. This is the architectural result that makes consolidation worth considering: NVMe-backed capacity can come with higher throughput than an in-memory server, rather than forcing the application to exchange performance for lower storage cost.[16][13]

Same 1,280-connection runs · QPS rounded to whole operations; all latency columns in milliseconds
System / operationQPSAverageP50P95P99P99.9
Lavik 0.1.0 SPDK GET1,145,7721.1171.0311.5113.9997.135
Lavik 0.1.0 SPDK SET971,9501.3171.1192.7834.4797.199
Redis 8.10.2 GET1,018,7351.2561.0872.4794.4157.103
Redis 8.10.2 SET951,0531.3461.1352.9434.5117.231
Valkey 9.1.2 GET970,2881.3191.1192.5114.4157.455
Valkey 9.1.2 SET808,1031.5831.4552.5594.0477.199
Sources and calculation inputs[16][17][18][19][20][21][22]

延遲也取決於伺服器的負載程度。在十億鍵操作點、80 個連線時,Lavik 提供 385,514 GET QPS,P99.9 為 0.439 毫秒。在 640 個連線時,達到每秒超過一百萬 GET。基礎設施團隊可利用這些曲線來選擇所需的吞吐量與尾部延遲組合。為突發情況保留裕度,比僅根據吞吐量圖表最高點來規劃生產部署更為實用。[13]

十億鍵資料集包含 1.024 TB 的原始值——約為伺服器 RAM 的 7.6 倍——並達到 1,069,126 GET QPS。因此 Lavik 的效能遠超過記憶體容量資料集。較小例項的結果傳達相同的容量訊息:在兩個 vCPU 和 16 GiB 名義 RAM 下,將資料集從 100 萬個 1 KiB 值擴增至 1 億個,峰值 GET 吞吐量從 215,521 下降至 215,463 QPS。SET 仍保留較小資料集峰值的 95.2%。這對於緊湊服務與大型代理平臺皆具價值:容量可增長,而不必相應增加服務節點。[13][14]

GET and SET throughput curves for Lavik with ten million and one billion keys, and Redis and Valkey with ten million keys.
在 80–1,280 連線間執行 GET 與 SET。10M 鍵測試使用 30 秒視窗;1B 鍵測試使用 60 秒視窗並採用不同的客戶端種子。[13][16]

Agent state also needs updates. In the separate io_uring YCSB experiment, Lavik processes 529,501 operations per second for a 50/50 read/update mix and 577,373 for a 95/5 mix. These are structured-record operations: HGETALL reads and LAVIK.HREPLACE updates against 100 million records with ten 128-byte fields. They show the relevance of Lavik’s design beyond a pure GET workload, including feature records whose contents change as an agent progresses through a task.[15]

獨立的 io_uring YCSB 實驗 · 1 億個記錄,10 × 128 B 欄位,256 個工作者,無副本
Lavik 工作負載總 QPSREAD P99.9 毫秒UPDATE P99.9 毫秒
50% HGETALL / 50% HREPLACE529,5015.0832.831
95% HGETALL / 5% HREPLACE577,3731.8181.578
來源與計算輸入[15]

每秒一百萬次操作相當於持續時每天八億六千四百萬次操作。這種測量到的服務效能水平,加上 NVMe 儲存密度,強烈說明需要重新評估以記憶體為瓶頸的 fleet。先從實際流量範圍開始——指令組合、峰值需求、突發與延遲目標——並將運算資源分配到該範圍。讓 NVMe SSD 為應用程式需要記憶的一切提供容量。[1][13]

5. 節點更少意味著更少的叢集機械

記憶體驅動的增長也擴大了工程師必須操作的拓撲。Redis Cluster 將 16,384 個雜湊槽分配並使用全網狀叢集匯流排。其規格為每個節點提供 N−1 個傳出和 N−1 個傳入匯流排連線。整個叢集的連線數為 N(N−1):300 個節點時 89,700 連線,600 個節點時 359,400 連線,1,000 個節點時 999,000 連線。這些是叢集匯流排連線,與應用程式流量分開。隨著代理狀態擴大,透過更多節點增加記憶體也會擴大此協調網格的規模。[2]

叢集使用 gossip、心跳探測和失效報告來維持成員與健康。本地失效懷疑必須與其他節點的報告進行調和;故障轉移需要授權與設定時期。在網路分割槽或滾動重啟期間,工程師必須瞭解哪些主節點、複本和路徑仍可達。成員越多,診斷所需的佈局與關係也越多,即使請求處理容量足夠。車隊的營運成本包含這些工作以及 VM 付費。[2]

重新分片會增加資料移動、所有權變更和客戶端重導。維護則包含修補、重啟、監控與複本佈局。高儲存密度的 Lavik 部署減少了為容量所需的 Data 程序數量,並為每個程序提供成長空間。Lavik 的 Meta 服務管理拓撲與權威,而原生複製維護跟隨者。對於受容量限制的應用,縮減車隊可一次性降低兩項費用:為記憶體購買的伺服器與管理它們所帶來的營運工作。[3][6][11][7]

6. 移動工作負載,保持服務需求

A single logarithmic chart compares capacity-driven VM counts. At 10 TB before overhead, Redis reaches 1,166 VMs; three independent Lavik deployments total nine VMs: six data VMs and three Meta-only voters.
先考慮開銷前的對數容量模型。Redis 使用 16 GiB 主節點與每對一個複本。每個獨立的 Lavik 部署新增兩個 3.84 TB 資料 VM 以及一個較小的僅 Meta 的投票者;三個 VM 均被計算。[1][28][29]

最適合整合的候選者很容易辨識:記憶體壓力持續逼迫擴容,而 CPU 使用率與流量仍低於車隊的服務容量。挑選一個代表性工作負載,並為其指令、鍵數、值分佈及最繁忙時段調整 Lavik 的規模。若尾端延遲目標苛刻或 CPU 密集型指令組合,可能需要額外的服務容量。架構優勢保持不變:保留的資料不再僅依靠 DRAM 容量來決定節點數。[1][6]

從一開始就將可用性納入部署。將 VM 放置於適當的失效域,並將 Meta 狀態儲存在耐用磁碟上。Azure 的本地 NVMe 為臨時儲存,故需將跨 VM 的複製與外部備份配對。啟用複製、過期與回收時,測量服務延遲,接著在預定資料集大小下練習主節點失效與跟隨者重建。Lavik 的 Meta 以 Raft 管理拓撲與權威,Data 複製則為非同步。相應設定應用程式的恢復點與恢復時間目標,並透過故障轉移演練驗證。[29][11][7][1]

使用 RedisShake 從現有 Redis 部署遷移。盤點指令與鍵結構,建立受管理的 Lavik 目標,複製基線並追蹤增量變更。切換前先調和鍵數、值與過期。暫停來源寫入完成最後同步,切換客戶端,並保留考慮新寫入的回滾程式。來源分片數不必決定目標的實體佈局。連結的遷移指南提供針對發布版本的設定與步驟,將整合設計轉為可執行的遷移。[12]

7. 給代理狀態留足成長空間

當保留的狀態從 1 TB 擴增到 10 TB 甚至更高時,每增加一個 TB 的成本就成為產品的限制。 Lavik 提供不同的基礎:一個與 Redis 相容的 NVMe 鍵值儲存,測量的吞吐量超越在 DRAM 上的 Redis,且具備高效的大物件儲存與 Apache 2.0 開源授權。 先以您的應用程式使用的指令為起點,載入代表性資料集,並測量對使用者重要的延遲預算。 將 300 個 Redis 節點縮減到三個 Lavik 節點,機會在於圍繞工作負載的實際運算需求建構,並讓其資料空間得以擴充套件。 [6][10][13][1]

基準測試與規模說明

基準測試設定:Azure Standard_L16aos_v4、Japan West 區域 2、AMD EPYC 9V74、16 個邏輯 CPU(八個實體核心,啟用 SMT)、125.8 GiB RAM 與六個 1.92 TB NVMe 裝置。 F32als_v6 客戶端使用 16 個執行緒,透過私人加速的 mlx5 網路與 Linux TCP。 十萬萬鍵視窗執行 30 秒,使用相關種子;十億鍵視窗執行 60 秒,使用不同種子。 Lavik 使用 8 GiB 的 hugepages,啟用 defrag,並每次輪詢 16 次完成。 選定的 Redis I/O 執行緒數量為 GET 16、SET 16;Valkey 亦為 GET 16、SET 8。 所有測試均使用單一伺服器,未啟用資料副本;Redis 與 Valkey 皆停用 AOF 與排程快照。 [13]

測量細節:每個曲線點代表一次測量視窗。 延遲來自整個視窗的 memtier 結果;P95 由內嵌的 HDR 歷史圖解碼。 混合工作負載實驗使用 io_uring,12 個 Lavik 工作者加四個系統/IRQ CPU,256 個客戶端工作者,並以 300 秒視窗且不啟用副本。 這些報告涵蓋所示工作負載;在實際選擇時,亦應測量應用程式自身的值大小、指令組合與複製尾延遲。 [16][13][15]

規模與成本基準:Azure 的比較使用 300 臺 E2s_v4 VM 與兩臺 L16as_v4 資料 VM 加一臺 E2s_v4 只做 Meta 的投票機。 兩者皆使用 East US 2 區域的 Linux 按使用量付費價格,且每月 730 小時;年度成本為 12 個月期。 容量正規化計算一個邏輯副本:Redis 主記憶體 2,400 GiB 及 Lavik NVMe SSD 3.84 TB,均未計算額外開銷。 對數圖表隨容量增長重複獨立的三臺 VM Lavik 部署單元。 吞吐量測試使用獨立的 L16aos_v4 基準設定。 每百萬次操作的成本假設平均 1 百萬 QPS;VM 價格不包含管理磁碟、外部備份、流量、人工與稅金。 [1][27][28][29][13]