Databricks Databricks ★ 91 6 min

Sizing Lakebase Search: lessons from a real app and 4 million passages

Lakebase

🔗 https://www.databricks.com/blog/sizing-lakebase-search-lessons-real-app-and-4-million-passages

📌 400 萬筆資料實測:Lakebase Search 的資料庫規格該怎麼挑

TL;DR:Databricks 用內部搜尋工具 Slide Hub 與 400 萬筆 MIRACL 段落,實測 Lakebase Postgres 在不同規格下的效能極限。

多加運算資源不一定會變快——Databricks 的實測發現,Lakebase Postgres 的規模一旦衝過某個門檻,瓶頸就會從資料庫轉移到應用程式本身,而這個轉折點比許多人想像得更早出現。

🤔 Slide Hub:一個真實的內部搜尋應用

Slide Hub 是 Databricks 內部工具,讓 field engineer 從約 700 份內部簡報(活動演講、產品與架構簡報)中找到並重用單張投影片,同時透過 MCP(Model Context Protocol)server 把同一套搜尋能力提供給 AI agent 使用。投影片、投票、搜尋紀錄與變更歷史全部存在同一個 Lakebase Postgres 資料庫,這個真實使用案例也成為本次 benchmark 的基準。

🧩 架構:搜尋就長在資料庫裡

Lakebase Search 於九月正式 GA,本質是一組 Postgres extension,資料不需要搬到獨立的搜尋系統。lakebase_vector 負責儲存 embedding 並支援 lakebase_ann 索引做近似最近鄰(ANN)搜尋,索引用 IVF partitioning 分組向量,再用 RaBitQ quantization 把每個向量壓縮到約 1 bit/維度;lakebase_text 則支援 lakebase_bm25 索引,用 <@> 運算子做 BM25 關鍵字排序。

Slide Hub 採用 hybrid search:向量搜尋與 BM25 關鍵字搜尋各取 200 個候選,用 Reciprocal Rank Fusion(RRF,k=60)把兩份排名融合,再套用 0.70 的相似度門檻過濾掉太不相關的向量結果、對標題命中加權、notes 權重設為 0.5,最後套用權限過濾並接上投票資料——這整套排序邏輯只用一條 SQL 完成,與應用邏輯共用同一條連線、同一組權限與同一次 commit。

計算資源分兩層:Lakebase Postgres 以 Compute Unit(CU)計費,1 CU 約配置 2GB 記憶體與對應的 CPU/本地 SSD,可在 0.5~64 CU 之間自動擴縮(上限最多比下限多 16),固定規格最高到 112 CU,32 CU 以下可以 scale to zero。資料庫會用 Local File Cache(LFC)保留近期讀取的頁面,快取隨 CU 增長,最多使用 75% 的記憶體。應用層的 Databricks Apps 則是固定規格:MEDIUM 最多 2 vCPU/6GB,LARGE 最多 4 vCPU/12GB,每個 worker process 持有 8 條資料庫連線。

📊 CU 規模與效能的關係

規格平均延遲File Cache備註
1 CU146 ms1.5 GB需從 storage 讀取 14.9M 頁
8 CU34 ms12 GBthroughput 較 1 CU 提升約 50%
16 CU(搭配 MEDIUM app)僅再提升 4%—資料庫連線多半閒置
16 CU + LARGE app(4 workers)——至少達 662 req/s,此時瓶頸是負載產生器本身

結論很直接:8 CU 以下,資料庫是瓶頸,該加 CU;8 CU 之後,瓶頸轉移到應用層,該加 app worker。連線池同樣關鍵——在 50 個使用者的情境下,沒有連線池時只有 45 req/s、p95 延遲 2.4 秒,加上連線池後提升到 85 req/s、p95 降到 0.7 秒;而 embedding 快取在負載測試下沒有觀察到明顯差異。

候選數量(candidate limit)也值得注意:Slide Hub 原先出貨設定是每種方法各取 1,000 個候選,官方文件範例則用 40。實測把候選數降到 200 時,前 10 筆結果中有 90.5% 與 1,000 候選的結果一致,命中總數則是 1,000 候選情況下的 81%,考慮到使用者很少翻到第 200 筆以後,Slide Hub 最終改用 200 候選,冷啟動(compute 從 scale to zero 甦醒後的第一次查詢)延遲從原本更高的水準降到 2.9 秒,重複查詢只要 40 毫秒。冷啟動的延遲主要來自連線喚醒端點(約 1 秒)與頁面逐步從 storage 讀入直到快取熱機,第一次查詢還要額外付出約 75 毫秒的查詢規劃時間。

規模測試使用 MIRACL English(完整語料 32,893,221 筆段落)切出 1M、2M、4M 三個子集,用 1024 維的開源模型 gte-large-en-v1.5 做 embedding,自架在單張 A10G GPU 上跑出 379 passages/秒,整個語料耗時 2.95 GPU 小時,相較於用模型服務端點跑同樣工作要花 $48.87;兩種方式產出的向量幾乎一致(平均 cosine 相似度 1.0000,最低 0.9978)。lakebase_ann 索引隨語料增長:1M 時 5.8GB,2M 時 11.5GB,4M 時 23.0GB,而用 binary COPY 在 8 CU 下載入全部 400 萬筆只花 19 分鐘。由於 Lakebase Postgres 每 CU 大約只能提供 1.6GB 的 file cache,當索引大小超過快取容量時會發生什麼事,是素材本身留下、尚待後續驗證的開放問題。

⚠️ 規模持續成長後的行為仍待觀察

素材明確指出「索引大於快取時會發生什�麼」這個問題尚未在文中給出具體答案,這裡不做過度延伸推測。

🎯 實務啟示

如果你要在自己的 Lakebase Postgres 上加搜尋功能,可以照這個順序排優先序:先精簡 candidate limit(不必無腦設大),再把 CU 調到資料庫不再是瓶頸,最後才是增加應用層 worker 數與資料庫連線池大小;同時別忘了連線池本身就能帶來接近兩倍的吞吐量提升。

🔗 來源

#Databricks #Lakebase #PostgreSQL #VectorSearch #BM25 #HybridSearch #DatabasePerformance #RAG #MCP #Benchmarking

原始資料 Databricks · 收集於 2026-10-14
來源原標題
Sizing Lakebase Search: lessons from a real app and 4 million passages
機構
Databricks
原始標籤
Lakebase
原始連結
https://www.databricks.com/blog/sizing-lakebase-search-lessons-real-app-and-4-million-passages

摘要原文

Slide Hub is an internal Databricks app. Field engineers use it to find and reuse slides from about 700 internal presentations: event talks, product decks, and architecture decks. A search bar finds single slides by meaning and by keyword, and a Model Context Protocol (MCP) server gives AI agents the same search. The app stores its slides, votes, search telemetry, and change history in Lakebase Postgres . We use Slide Hub as the baseline to benchmark Lakebase Postgres. It is a real app with a real use case and real users, so its numbers show how the database behaves under an actual workload. This post is for developers and architects who build apps on Databricks and want search inside the app's own Lakebase Postgres database. It assumes that you know SQL and the basics of PostgreSQL. If you plan a search bar or an agent tool on Lakebase Postgres, the numbers below help you choose the compute size before you go to production. This post shows how Slide Hub runs search inside Lakebase Postgres, what limits it under load, what it costs, and how Lakebase Search behaves from 1M to 4M rows of a public corpus. Lakebase Search became generally available in September. It is a set of Postgres extensions , so it runs next to the application tables. The app does not copy data to a separate search system. The developer does not maintain a second transaction path. Two CREATE EXTENSION statements enable the components. lakebase_vector stores embeddings , vectors of numbers that represent the meaning of a text, and supports the lakebase_ann index for approximate nearest neighbor (ANN) search. lakebase_text supports the lakebase_bm25 index for BM25, a standard method that ranks text by the query words it contains. lakebase_tokenizer is optional. The ANN index uses IVF partitioning, which groups similar vectors so a query reads only a few groups, and RaBitQ quantization, which compresses each vector to about 1 bit per dimension. BM25 scores text with the <@> operator. Slide Hub’s 23k slide rows sit in the same serverless Lakebase Postgres instance as the votes, telemetry, change history, previews, and both indexes. The app reads the data and the indexes inside one connection and one permission model. Slide Hub runs hybrid search . It combines vector search , which finds slides with a similar meaning to the query, and BM25 keyword search , which finds slides that contain the query words. Each method returns a short list of its best matches, the candidates . One SQL statement carries the whole ranking policy. It ranks each candidate list, fuses the two rankings, applies the app filters, and joins the votes. Search and app logic share one connection, one set of grants, and one commit. Slide Hub takes 200 candidates from each method. It fuses the two lists with Reciprocal Rank Fusion (RRF) at k=60: a slide scores 1/(60 + its rank) in each list, and the two scores add. A similarity gate of 0.70 rejects vector matches that are too far from the query to be useful for this embedding model. Title tiers add weight when the query matches a slide title. Notes receive weight 0.5. Scope filters restrict the result to assets the user has permission to see. A search request uses two separate computes, and either one can set the limit. Lakebase Postgres compute runs the database. Lakebase Postgres sizes it in Compute Units (CU) . One CU allocates about 2 GB of RAM to the database, with its share of CPU and local SSD. A compute autoscales between a minimum and a maximum size from 0.5 CU to 64 CU, and the maximum can be at most 16 CU above the minimum. Fixed-size computes go up to 112 CU, and computes up to 32 CU can scale to zero .Postgres stores tables and indexes in 8 KB pages . Lakebase Postgres keeps recently read pages in a Local File Cache (LFC) on the compute. The cache grows with the CU size and can use up to 75% of the compute's memory. A page that is not in the cache comes from storage, which takes longer. Databricks Apps compute runs the Slide Hub web server. Its size is fixed per app. A MEDIUM app has up to 2 vCPU and 6 GB of memory, and a LARGE app has up to 4 vCPU and 12 GB. Slide Hub runs one app instance. Each Python worker process in it holds a pool of 8 database connections, so 2 workers open at most 16 connections and 4 workers open at most 32. For each request, the app embeds the query text, sends one SQL statement to Lakebase Postgrse, and returns the result. To find the limit, the test changes one side at a time. It pins Lakebase Postgres at one CU size and changes the app, or it keeps the app and changes the CU size. A load generator simulates users that send search requests, and it raises the number of users in steps. The list shows requests per second and the median latency (p50) at 500 users for each Lakebase Postgres size and app size. Up to 4 CU, Lakebase is the limit. A LARGE app with twice the workers and connections adds nothing at 1 CU. At 1 CU the search statement averaged 146 ms and read 14.9M pages from storage, with a file cache of 1.5 GB. At 8 CU it averaged 34 ms, with a cache of 12 GB, and throughput rose about 50%. From 8 CU, the app is the limit. 16 CU with the same MEDIUM app adds only 4%, and its database connections sit mostly idle. A LARGE app with 4 workers at 16 CU reaches at least 662 req/s, and there the load generator was the limit. Size the query first. Then scale Lakebase Postgres until the app workers are the limit, and then scale the app. Takeaway: Find the limit before you scale. Below 8 CU, add Lakebase Postgres CU. From 8 CU, give the app more workers. The connection pool is still necessary. At 50 users the app reached 45 req/s and 2.4 s p95 without the pool, and 85 req/s and 0.7 s p95 with it. The embedding cache made no measurable difference under load. The candidate limit sets the number of pages a query touches. On a cold cache, that number sets the latency. Slide Hub shipped with 1,000 candidates per method. The docs pattern uses 40. The candidate-limit experiment changed only candidate_limit and measured 20 public queries in three states. Cold is the first query after the compute scaled to zero, with an empty cache. First-touch is the first run of a query on an awake compute. Repeat is the same query run again, with its pages in the cache. Pages touched counts the pages a query reads from any source. Top-10 overlap is the share of the top 10 results that match the result at 1,000 candidates. At 200 candidates, 90.5% of the top 10 stays the same, and the reported number of matches is 81% of the number at 1,000 candidates. Users rarely page past 200 results, so Slide Hub now ships 200. Measured end to end from a job in the same cloud region as the app, a cold search at 200 candidates took 2.9 s, and a repeat search took 40 ms. The cold time has two parts. The connection waits about 1 s while the endpoint wakes up. Then each query reads its pages from storage until the cache warms. The first query on a new connection also pays about 75 ms of planning. Takeaway: Keep the candidate pool small. 200 candidates keep 90.5% of the top 10 results, read about a third of the pages of 1,000 candidates, and halve the cold latency. The scale tests use MIRACL English , a passage corpus built from Wikipedia. The full corpus has 32,893,221 passages. We embedded it with gte-large-en-v1.5 , a 1024-dimension open model, the same size as the Slide Hub embeddings. We self-hosted the model on one A10G GPU at 379 passages per second. The whole corpus took 2.95 GPU-hours, against $48.87 for the same work on a model-serving endpoint. The GPU vectors matched the endpoint vectors (mean cosine 1.0000, minimum 0.9978). We built three subsets: 1M, 2M, and 4M passages. The lakebase_ann index grew with the corpus: 5.8 GB at 1M, 11.5 GB at 2M, 23.0 GB at 4M. A binary COPY loaded all 4M rows in 19 minutes at 8 CU. Lakebase Postgres holds about 1.6 GB of file cache per CU. Scale raises one question: what happens when the index is larger than the cache?

由 claude-code/sonnet 自動生成