何時(shí)應(yīng)將分布式 PostgreSQL 用于 Gen AI 應(yīng)用程序?
Postgres 繼續(xù)推動(dòng)數(shù)據(jù)庫(kù)格局的發(fā)展,超越傳統(tǒng)的關(guān)系數(shù)據(jù)庫(kù)用例。其豐富的擴(kuò)展和派生解決方案生態(tài)系統(tǒng)使 Postgres 成為一股強(qiáng)大的力量,尤其是在時(shí)間序列和地理空間等領(lǐng)域,以及最近的生成式 AI 工作負(fù)載。
Pgvector已成為希望使用 Postgres 作為矢量數(shù)據(jù)庫(kù)的新一代 AI 應(yīng)用的基礎(chǔ)擴(kuò)展。簡(jiǎn)而言之,pgvector 添加了新的數(shù)據(jù)類型、運(yùn)算符和索引類型,以處理 Postgres 中的矢量化數(shù)據(jù)(嵌入)。這允許您使用數(shù)據(jù)庫(kù)對(duì)嵌入進(jìn)行相似性搜索。
Pgvector 在 2023 年開(kāi)始騰飛,GitHub 星星數(shù)量激增:
純向量數(shù)據(jù)庫(kù),例如 Pinecone,不得不承認(rèn) pgvector 的存在并開(kāi)始發(fā)布競(jìng)爭(zhēng)性材料。我認(rèn)為這對(duì) Postgres 來(lái)說(shuō)是一個(gè)好兆頭。
為什么這是個(gè)好兆頭?正如我的 Postgres 社區(qū)成員Rob Treat 所說(shuō),“一開(kāi)始他們會(huì)忽略你。然后他們會(huì)嘲笑你。然后他們會(huì)創(chuàng)建基準(zhǔn)測(cè)試。最后你就贏了!”
那么,這與分布式 Postgres 主題有何關(guān)系?
Postgres 用于新一代 AI 工作負(fù)載的頻率越高,你就會(huì)越頻繁地聽(tīng)到(來(lái)自其他解決方案背后的供應(yīng)商)基于 Postgres 構(gòu)建的新一代 AI 應(yīng)用程序?qū)⒕哂幸韵绿攸c(diǎn):
可擴(kuò)展性和性能問(wèn)題
數(shù)據(jù)隱私面臨的挑戰(zhàn)
高可用性的艱難時(shí)期
如果確實(shí)遇到了列出的問(wèn)題,則不應(yīng)立即放棄 Postgres 并遷移到更具可擴(kuò)展性、高度可用、安全的矢量數(shù)據(jù)庫(kù),至少在您嘗試在分布式配置中運(yùn)行 Postgres 之前不要這樣做!
讓我們討論何時(shí)以及如何使用分布式 Postgres 來(lái)處理 gen AI 工作負(fù)載。
什么是分布式 Postgres?
Postgres 專為單服務(wù)器部署而設(shè)計(jì)。這意味著單個(gè)主實(shí)例存儲(chǔ)所有應(yīng)用程序數(shù)據(jù)的一致副本并處理讀取和寫入請(qǐng)求。
如何讓單服務(wù)器數(shù)據(jù)庫(kù)分布式?您可以利用 Postgres 生態(tài)系統(tǒng)!
在 Postgres 生態(tài)系統(tǒng)中,人們通常對(duì)分布式 Postgres 做出以下假設(shè)之一:
具有多主異步復(fù)制和沖突解決功能的多個(gè)獨(dú)立 PostgreSQL 實(shí)例(如 EDB Postgres Distributed)
與協(xié)調(diào)器 (如 CitusData) 一起分片的 Postgres
無(wú)共享的分布式 Postgres(如 YugabyteDB)
有關(guān)每個(gè)部署選項(xiàng)的更多信息,請(qǐng)查看以下指南。至于本文,讓我們研究何時(shí)以及如何將分布式 Postgres 用于您的 gen AI 工作負(fù)載。
問(wèn)題 1:嵌入使用所有可用的內(nèi)存和存儲(chǔ)空間
如果您曾經(jīng)使用過(guò)將文本、圖像或其他類型的數(shù)據(jù)轉(zhuǎn)換為矢量化表示的嵌入模型,您可能已經(jīng)注意到生成的嵌入是相當(dāng)大的浮點(diǎn)數(shù)數(shù)組。
例如,您可以使用 OpenAI 嵌入模型將文本值轉(zhuǎn)換為 1536 維浮點(diǎn)數(shù)數(shù)組??紤]到數(shù)組中的每個(gè)項(xiàng)目都是 4 字節(jié)浮點(diǎn)數(shù),單個(gè)嵌入的大小約為 6KB — 這是相當(dāng)大數(shù)量的數(shù)據(jù)。
現(xiàn)在,如果您有 1000 萬(wàn)條記錄,則僅這些嵌入就需要分配大約 57 GB 的存儲(chǔ)空間和內(nèi)存。此外,您還需要考慮索引(例如 HNSW、IVFFlat 等)占用的空間,許多人會(huì)創(chuàng)建這些索引來(lái)加快向量相似性搜索。
總體而言,嵌入的數(shù)量越多,Postgres 需要的內(nèi)存和存儲(chǔ)空間就越多,以有效地存儲(chǔ)和管理它們。
您可以通過(guò)切換到生成維度較少的向量的嵌入模型或使用量化技術(shù)來(lái)減少存儲(chǔ)和內(nèi)存使用量。但是,假設(shè)我需要這些 1536 維向量,并且我不想應(yīng)用任何量化技術(shù)。在這種情況下,如果嵌入的數(shù)量繼續(xù)增加,我的數(shù)據(jù)庫(kù)實(shí)例的內(nèi)存和存儲(chǔ)容量可能會(huì)超出承受范圍。
這是一個(gè)可以利用分布式 Postgres 的明顯領(lǐng)域。例如,通過(guò)運(yùn)行分片版本 (CitusData) 或無(wú)共享版本 (YugabyteDB) 的 PostgreSQL,您可以讓數(shù)據(jù)庫(kù)在整個(gè)節(jié)點(diǎn)集群中均勻分布您的嵌入。
使用這種方法,您不再受單個(gè)節(jié)點(diǎn)的內(nèi)存和存儲(chǔ)容量的限制。如果您的應(yīng)用程序繼續(xù)生成更多嵌入,您可以隨時(shí)通過(guò)添加更多節(jié)點(diǎn)來(lái)擴(kuò)展集群。
問(wèn)題 2:相似性搜索是一項(xiàng)計(jì)算密集型操作
這個(gè)問(wèn)題與上一個(gè)問(wèn)題密切相關(guān),但重點(diǎn)是 CPU 和 GPU 的利用率。
當(dāng)我們說(shuō)“只需對(duì)存儲(chǔ)在數(shù)據(jù)庫(kù)中的嵌入執(zhí)行向量相似性搜索”時(shí),這項(xiàng)任務(wù)對(duì)我們?nèi)祟悂?lái)說(shuō)聽(tīng)起來(lái)很簡(jiǎn)單明了。然而,從數(shù)據(jù)庫(kù)服務(wù)器的角度來(lái)看,這是一項(xiàng)計(jì)算密集型操作,需要大量的 CPU 周期。
例如,這是用于計(jì)算兩個(gè)向量之間余弦相似度的公式。我們通常使用余弦相似度來(lái)查找給定用戶提示的最相關(guān)數(shù)據(jù)。
想象一下,A是新提供的用戶提示的向量或嵌入,B是存儲(chǔ)在 Postgres 中的獨(dú)特業(yè)務(wù)數(shù)據(jù)的向量或嵌入。如果您從事醫(yī)療保健行業(yè),B可能是特定疾病的藥物和治療方法的矢量化表示。
為了找到與所提供用戶癥狀(向量 A)最相關(guān)的治療方法(向量 B),數(shù)據(jù)庫(kù)必須計(jì)算A和B的每個(gè)組合的點(diǎn)積和幅度。對(duì)比較嵌入中的每個(gè)維度(公式中的“i”)重復(fù)此過(guò)程。如果您的數(shù)據(jù)庫(kù)包含一百萬(wàn)個(gè) 1536 維向量(治療方法和藥物),Postgres 必須針對(duì)每個(gè)用戶提示對(duì)這些多維向量執(zhí)行一百萬(wàn)次計(jì)算。
近似最近鄰搜索 (ANN) 允許我們通過(guò)為矢量化數(shù)據(jù)創(chuàng)建專用索引來(lái)減少 CPU 和 GPU 的使用。但是,使用 ANN 會(huì)犧牲一些準(zhǔn)確性;由于數(shù)據(jù)庫(kù)不會(huì)比較所有矢量,您可能無(wú)法始終獲得最相關(guān)的治療或藥物。此外,這些索引也有成本:它們需要時(shí)間來(lái)構(gòu)建和維護(hù),并且需要專用的內(nèi)存和存儲(chǔ)空間。
如果您不想受到單個(gè)數(shù)據(jù)庫(kù)服務(wù)器的 CPU 和 GPU 資源的限制,可以考慮使用分布式版本的 Postgres。每當(dāng)計(jì)算資源成為瓶頸時(shí),您都可以通過(guò)添加新節(jié)點(diǎn)來(lái)擴(kuò)展數(shù)據(jù)庫(kù)集群。一旦新節(jié)點(diǎn)加入集群,像YugabyteDB這樣的分布式數(shù)據(jù)庫(kù)就會(huì)自動(dòng)重新平衡嵌入并立即開(kāi)始利用新節(jié)點(diǎn)的資源。
問(wèn)題3:數(shù)據(jù)隱私
每當(dāng)我演示 LLM 和 Postgres 的組合可以實(shí)現(xiàn)什么時(shí),開(kāi)發(fā)人員都會(huì)受到啟發(fā)。他們會(huì)立即嘗試將這些 AI 功能匹配并應(yīng)用到他們開(kāi)發(fā)的應(yīng)用程序上。
然而,總是有一個(gè)與數(shù)據(jù)隱私相關(guān)的后續(xù)問(wèn)題:“如何在不損害數(shù)據(jù)隱私的情況下利用 LLM 和嵌入模型?”答案有兩個(gè)方面。
首先,如果您不信任特定的 LLM 或嵌入模型提供商,您可以選擇使用私有或開(kāi)源模型。例如,使用 Mistral、LLaMA 或 Hugging Face 的其他模型,您可以從自己的數(shù)據(jù)中心或云環(huán)境中安裝和運(yùn)行這些模型。
其次,一些應(yīng)用程序需要遵守?cái)?shù)據(jù)駐留要求,以確保私有 LLM 和嵌入模型使用或生成的所有數(shù)據(jù)永遠(yuǎn)不會(huì)離開(kāi)特定位置(數(shù)據(jù)中心、云區(qū)域或區(qū)域)。
在這種情況下,您可以運(yùn)行多個(gè)獨(dú)立的 Postgres 實(shí)例,每個(gè)實(shí)例都使用來(lái)自特定位置的數(shù)據(jù),并允許應(yīng)用程序?qū)訁f(xié)調(diào)跨多個(gè)數(shù)據(jù)庫(kù)服務(wù)器的訪問(wèn)。
另一種選擇是使用分布式 Postgres 部署的地理分區(qū)功能,它可以自動(dòng)在多個(gè)位置分發(fā)和訪問(wèn)數(shù)據(jù),從而簡(jiǎn)化應(yīng)用程序邏輯。
讓我們繼續(xù)討論醫(yī)療保健用例,看看地理分區(qū)如何讓我們能夠根據(jù)數(shù)據(jù)監(jiān)管機(jī)構(gòu)的要求跨地區(qū)分發(fā)有關(guān)藥物和治療的信息。在這里,我使用 YugabyteDB 作為分布式 Postgres 部署的示例。
假設(shè)有三家醫(yī)院,一家在舊金山,另外兩家分別在芝加哥和紐約。我們部署一個(gè)分布式 YugabyteDB 集群,每個(gè)醫(yī)院附近的區(qū)域(或私有數(shù)據(jù)中心)都有多個(gè)節(jié)點(diǎn)。
為了遵守?cái)?shù)據(jù)隱私和監(jiān)管要求,我們必須確保這些醫(yī)院的醫(yī)療數(shù)據(jù)永遠(yuǎn)不會(huì)離開(kāi)各自的數(shù)據(jù)中心。
通過(guò)地理分區(qū),我們可以實(shí)現(xiàn)如下目標(biāo):
創(chuàng)建 Postgres 表空間并將其映射到美國(guó)西部、中部和東部的云區(qū)域。每個(gè)區(qū)域至少有一個(gè) YugabyteDB 節(jié)點(diǎn)。
SQL
CREATE TABLESPACE usa_east_ts WITH (
replica_placement = '{"num_replicas": 1, "placement_blocks":
[{"cloud":"gcp","region":"us-east4","zone":"us-east4-a","min_num_replicas":1}]}'
);
CREATE TABLESPACE usa_central_ts WITH (
replica_placement = '{"num_replicas": 1, "placement_blocks":
[{"cloud":"gcp","region":"us-central1","zone":"us-central1-a","min_num_replicas":1}]}'
);
CREATE TABLESPACE usa_west_ts WITH (
replica_placement = '{"num_replicas": 1, "placement_blocks":
[{"cloud":"gcp","region":"us-west1","zone":"us-west1-a","min_num_replicas":1}]}'
);
創(chuàng)建一個(gè)治療表,用于保存有關(guān)治療和藥物的信息。每種治療方法都有一個(gè)關(guān)聯(lián)的多維向量——description_vector該向量是使用嵌入模型為治療描述生成的。最后,該表按列進(jìn)行分區(qū)hospital_location。
SQL
CREATE TABLE treatment (
id int,
name text,
description text,
description_vector vector(1536),
hospital_location text NOT NULL
)
PARTITION BY LIST (hospital_location);
分區(qū)定義如下,例如hospital3舊金山的 數(shù)據(jù)會(huì)自動(dòng)映射到usa_west_ts美國(guó)西部數(shù)據(jù)庫(kù)節(jié)點(diǎn)的 。
SQL
CREATE TABLE treatments_hospital1 PARTITION OF treatment(id, name, description, description_vector, PRIMARY KEY (id, hospital_location))
FOR VALUES IN ('New York') TABLESPACE usa_east_ts;
CREATE TABLE treatments_hospital2 PARTITION OF treatment(id, name, description, description_vector, PRIMARY KEY (id, hospital_location))
FOR VALUES IN ('Chicago') TABLESPACE usa_central_ts;
CREATE TABLE treatments_hospital3 PARTITION OF treatment(id, name, description, description_vector, PRIMARY KEY (id, hospital_location))
FOR VALUES IN ('San Francisco') TABLESPACE usa_west_ts;
部署地理分區(qū)數(shù)據(jù)庫(kù)集群并定義所需的表空間和分區(qū)后,讓應(yīng)用程序連接到它并允許 LLM 訪問(wèn)數(shù)據(jù)。例如,LLM 可以使用以下命令直接查詢治療表:
SQL
select name, description from treatment where
1 - (description_vector ? $user_prompt_vector) > 0.8
and hospital_location = $location
分布式 Postgres 數(shù)據(jù)庫(kù)會(huì)自動(dòng)將請(qǐng)求路由到存儲(chǔ)指定 數(shù)據(jù)的節(jié)點(diǎn)hospital_location。這同樣適用于INSERTs 和UPDATEs;對(duì)治療表的更改將始終存儲(chǔ)在屬于該醫(yī)院位置的分區(qū)->表空間->節(jié)點(diǎn)中。這些更改永遠(yuǎn)不會(huì)復(fù)制到其他位置。
問(wèn)題#4:高可用性
盡管 Postgres 被設(shè)計(jì)為在單服務(wù)器配置中運(yùn)行,但這并不意味著它不能在高可用性設(shè)置中運(yùn)行。根據(jù)您所需的恢復(fù)點(diǎn)目標(biāo) (RPO) 和恢復(fù)時(shí)間目標(biāo) (RTO),有幾種選擇。
那么,分布式 Postgres 有什么用呢?借助分布式 PostgreSQL,您的 gen AI 應(yīng)用程序即使在區(qū)域、數(shù)據(jù)中心或區(qū)域中斷期間也能保持運(yùn)行。
例如,使用 YugabyteDB,您只需部署一個(gè)多節(jié)點(diǎn)分布式 Postgres 集群,讓節(jié)點(diǎn)處理容錯(cuò)和高可用性。節(jié)點(diǎn)直接通信。如果一個(gè)節(jié)點(diǎn)發(fā)生故障,其他節(jié)點(diǎn)將檢測(cè)到中斷。由于其余節(jié)點(diǎn)具有冗余、一致的數(shù)據(jù)副本,因此它們可以立即開(kāi)始處理先前發(fā)送到故障節(jié)點(diǎn)的應(yīng)用程序請(qǐng)求。YugabyteDB 提供 RPO = 0(無(wú)數(shù)據(jù)丟失)和 3-15 秒范圍內(nèi)的 RTO(取決于數(shù)據(jù)庫(kù)和 TCP/IP 配置默認(rèn)值)。
通過(guò)這種方式,您可以構(gòu)建永遠(yuǎn)不會(huì)失敗的新一代人工智能應(yīng)用程序和自主代理,即使在區(qū)域級(jí)事故和其他災(zāi)難性事件中也是如此。
總結(jié)
得益于 pgvector 等擴(kuò)展,PostgreSQL 已超越了傳統(tǒng)的關(guān)系數(shù)據(jù)庫(kù)用例,現(xiàn)在已成為生成式 AI 應(yīng)用程序的有力競(jìng)爭(zhēng)者。然而,使用嵌入可能會(huì)帶來(lái)一些挑戰(zhàn),包括大量?jī)?nèi)存和存儲(chǔ)消耗、計(jì)算密集型相似性搜索、數(shù)據(jù)隱私問(wèn)題以及對(duì)高可用性的需求。
分布式 PostgreSQL 部署提供可擴(kuò)展性、負(fù)載平衡和地理分區(qū),確保數(shù)據(jù)駐留合規(guī)性和不間斷運(yùn)行。通過(guò)利用這些分布式系統(tǒng),您可以構(gòu)建可擴(kuò)展且永不失敗的可擴(kuò)展 Gene AI 應(yīng)用程序。