何时应将分布式 PostgreSQL 用于 Gen AI 应用程序?
扫描二维码
随时随地手机看文章
Postgres 继续推动数据库格局的发展,超越传统的关系数据库用例。其丰富的扩展和派生解决方案生态系统使 Postgres 成为一股强大的力量,尤其是在时间序列和地理空间等领域,以及最近的生成式 AI 工作负载。
Pgvector已成为希望使用 Postgres 作为矢量数据库的新一代 AI 应用的基础扩展。简而言之,pgvector 添加了新的数据类型、运算符和索引类型,以处理 Postgres 中的矢量化数据(嵌入)。这允许您使用数据库对嵌入进行相似性搜索。
Pgvector 在 2023 年开始腾飞,GitHub 星星数量激增:
纯向量数据库,例如 Pinecone,不得不承认 pgvector 的存在并开始发布竞争性材料。我认为这对 Postgres 来说是一个好兆头。
为什么这是个好兆头?正如我的 Postgres 社区成员Rob Treat 所说,“一开始他们会忽略你。然后他们会嘲笑你。然后他们会创建基准测试。最后你就赢了!”
那么,这与分布式 Postgres 主题有何关系?
Postgres 用于新一代 AI 工作负载的频率越高,你就会越频繁地听到(来自其他解决方案背后的供应商)基于 Postgres 构建的新一代 AI 应用程序将具有以下特点:
可扩展性和性能问题
数据隐私面临的挑战
高可用性的艰难时期
如果确实遇到了列出的问题,则不应立即放弃 Postgres 并迁移到更具可扩展性、高度可用、安全的矢量数据库,至少在您尝试在分布式配置中运行 Postgres 之前不要这样做!
让我们讨论何时以及如何使用分布式 Postgres 来处理 gen AI 工作负载。
什么是分布式 Postgres?
Postgres 专为单服务器部署而设计。这意味着单个主实例存储所有应用程序数据的一致副本并处理读取和写入请求。
如何让单服务器数据库分布式?您可以利用 Postgres 生态系统!
在 Postgres 生态系统中,人们通常对分布式 Postgres 做出以下假设之一:
具有多主异步复制和冲突解决功能的多个独立 PostgreSQL 实例(如 EDB Postgres Distributed)
与协调器 (如 CitusData) 一起分片的 Postgres
无共享的分布式 Postgres(如 YugabyteDB)
有关每个部署选项的更多信息,请查看以下指南。至于本文,让我们研究何时以及如何将分布式 Postgres 用于您的 gen AI 工作负载。
问题 1:嵌入使用所有可用的内存和存储空间
如果您曾经使用过将文本、图像或其他类型的数据转换为矢量化表示的嵌入模型,您可能已经注意到生成的嵌入是相当大的浮点数数组。
例如,您可以使用 OpenAI 嵌入模型将文本值转换为 1536 维浮点数数组。考虑到数组中的每个项目都是 4 字节浮点数,单个嵌入的大小约为 6KB — 这是相当大数量的数据。
现在,如果您有 1000 万条记录,则仅这些嵌入就需要分配大约 57 GB 的存储空间和内存。此外,您还需要考虑索引(例如 HNSW、IVFFlat 等)占用的空间,许多人会创建这些索引来加快向量相似性搜索。
总体而言,嵌入的数量越多,Postgres 需要的内存和存储空间就越多,以有效地存储和管理它们。
您可以通过切换到生成维度较少的向量的嵌入模型或使用量化技术来减少存储和内存使用量。但是,假设我需要这些 1536 维向量,并且我不想应用任何量化技术。在这种情况下,如果嵌入的数量继续增加,我的数据库实例的内存和存储容量可能会超出承受范围。
这是一个可以利用分布式 Postgres 的明显领域。例如,通过运行分片版本 (CitusData) 或无共享版本 (YugabyteDB) 的 PostgreSQL,您可以让数据库在整个节点集群中均匀分布您的嵌入。
使用这种方法,您不再受单个节点的内存和存储容量的限制。如果您的应用程序继续生成更多嵌入,您可以随时通过添加更多节点来扩展集群。
问题 2:相似性搜索是一项计算密集型操作
这个问题与上一个问题密切相关,但重点是 CPU 和 GPU 的利用率。
当我们说“只需对存储在数据库中的嵌入执行向量相似性搜索”时,这项任务对我们人类来说听起来很简单明了。然而,从数据库服务器的角度来看,这是一项计算密集型操作,需要大量的 CPU 周期。
例如,这是用于计算两个向量之间余弦相似度的公式。我们通常使用余弦相似度来查找给定用户提示的最相关数据。
想象一下,A是新提供的用户提示的向量或嵌入,B是存储在 Postgres 中的独特业务数据的向量或嵌入。如果您从事医疗保健行业,B可能是特定疾病的药物和治疗方法的矢量化表示。
为了找到与所提供用户症状(向量 A)最相关的治疗方法(向量 B),数据库必须计算A和B的每个组合的点积和幅度。对比较嵌入中的每个维度(公式中的“i”)重复此过程。如果您的数据库包含一百万个 1536 维向量(治疗方法和药物),Postgres 必须针对每个用户提示对这些多维向量执行一百万次计算。
近似最近邻搜索 (ANN) 允许我们通过为矢量化数据创建专用索引来减少 CPU 和 GPU 的使用。但是,使用 ANN 会牺牲一些准确性;由于数据库不会比较所有矢量,您可能无法始终获得最相关的治疗或药物。此外,这些索引也有成本:它们需要时间来构建和维护,并且需要专用的内存和存储空间。
如果您不想受到单个数据库服务器的 CPU 和 GPU 资源的限制,可以考虑使用分布式版本的 Postgres。每当计算资源成为瓶颈时,您都可以通过添加新节点来扩展数据库集群。一旦新节点加入集群,像YugabyteDB这样的分布式数据库就会自动重新平衡嵌入并立即开始利用新节点的资源。
问题3:数据隐私
每当我演示 LLM 和 Postgres 的组合可以实现什么时,开发人员都会受到启发。他们会立即尝试将这些 AI 功能匹配并应用到他们开发的应用程序上。
然而,总是有一个与数据隐私相关的后续问题:“如何在不损害数据隐私的情况下利用 LLM 和嵌入模型?”答案有两个方面。
首先,如果您不信任特定的 LLM 或嵌入模型提供商,您可以选择使用私有或开源模型。例如,使用 Mistral、LLaMA 或 Hugging Face 的其他模型,您可以从自己的数据中心或云环境中安装和运行这些模型。
其次,一些应用程序需要遵守数据驻留要求,以确保私有 LLM 和嵌入模型使用或生成的所有数据永远不会离开特定位置(数据中心、云区域或区域)。
在这种情况下,您可以运行多个独立的 Postgres 实例,每个实例都使用来自特定位置的数据,并允许应用程序层协调跨多个数据库服务器的访问。
另一种选择是使用分布式 Postgres 部署的地理分区功能,它可以自动在多个位置分发和访问数据,从而简化应用程序逻辑。
让我们继续讨论医疗保健用例,看看地理分区如何让我们能够根据数据监管机构的要求跨地区分发有关药物和治疗的信息。在这里,我使用 YugabyteDB 作为分布式 Postgres 部署的示例。
假设有三家医院,一家在旧金山,另外两家分别在芝加哥和纽约。我们部署一个分布式 YugabyteDB 集群,每个医院附近的区域(或私有数据中心)都有多个节点。
为了遵守数据隐私和监管要求,我们必须确保这些医院的医疗数据永远不会离开各自的数据中心。
通过地理分区,我们可以实现如下目标:
创建 Postgres 表空间并将其映射到美国西部、中部和东部的云区域。每个区域至少有一个 YugabyteDB 节点。
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}]}'
);
创建一个治疗表,用于保存有关治疗和药物的信息。每种治疗方法都有一个关联的多维向量——description_vector该向量是使用嵌入模型为治疗描述生成的。最后,该表按列进行分区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);
分区定义如下,例如hospital3旧金山的 数据会自动映射到usa_west_ts美国西部数据库节点的 。
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;
部署地理分区数据库集群并定义所需的表空间和分区后,让应用程序连接到它并允许 LLM 访问数据。例如,LLM 可以使用以下命令直接查询治疗表:
SQL
select name, description from treatment where
1 - (description_vector ⇔ $user_prompt_vector) > 0.8
and hospital_location = $location
分布式 Postgres 数据库会自动将请求路由到存储指定 数据的节点hospital_location。这同样适用于INSERTs 和UPDATEs;对治疗表的更改将始终存储在属于该医院位置的分区->表空间->节点中。这些更改永远不会复制到其他位置。
问题#4:高可用性
尽管 Postgres 被设计为在单服务器配置中运行,但这并不意味着它不能在高可用性设置中运行。根据您所需的恢复点目标 (RPO) 和恢复时间目标 (RTO),有几种选择。
那么,分布式 Postgres 有什么用呢?借助分布式 PostgreSQL,您的 gen AI 应用程序即使在区域、数据中心或区域中断期间也能保持运行。
例如,使用 YugabyteDB,您只需部署一个多节点分布式 Postgres 集群,让节点处理容错和高可用性。节点直接通信。如果一个节点发生故障,其他节点将检测到中断。由于其余节点具有冗余、一致的数据副本,因此它们可以立即开始处理先前发送到故障节点的应用程序请求。YugabyteDB 提供 RPO = 0(无数据丢失)和 3-15 秒范围内的 RTO(取决于数据库和 TCP/IP 配置默认值)。
通过这种方式,您可以构建永远不会失败的新一代人工智能应用程序和自主代理,即使在区域级事故和其他灾难性事件中也是如此。
总结
得益于 pgvector 等扩展,PostgreSQL 已超越了传统的关系数据库用例,现在已成为生成式 AI 应用程序的有力竞争者。然而,使用嵌入可能会带来一些挑战,包括大量内存和存储消耗、计算密集型相似性搜索、数据隐私问题以及对高可用性的需求。
分布式 PostgreSQL 部署提供可扩展性、负载平衡和地理分区,确保数据驻留合规性和不间断运行。通过利用这些分布式系统,您可以构建可扩展且永不失败的可扩展 Gene AI 应用程序。