面向 AI Agent 的数据库:共享实时数据,但不与生产系统共担风险

2026-09-24 28 预计阅读时间: 1 分钟
来源: cloud.google.com AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:15 分钟

传统数据库扩展读负载时,通常会在规模、延迟和隔离之间做取舍。这个取舍过去可以接受:报表任务能够排期,副本数量可以预估,缓存也可以提前预热。但 AI Agent 生成的查询具有突发、短暂和不可预测的特点,可能在几秒内需要大量计算节点,又在一分钟后全部结束。此时,仅仅“增加只读副本”已经不够,数据库必须同时解决生产隔离、稳定低延迟和瞬时弹性三个问题。

AlloyDB 提出的新架构试图用一句话概括目标:共享数据,除此之外什么也不共享。 Agent 可以读取接近实时的生产数据,但其计算、网络路径和存储资源不应与主事务集群形成共享故障域。

三个条件必须同时成立

判断一个数据库是否真正适合 Agent 工作负载,不能只看它能启动多少副本。更有效的检查框架包含三个维度。

1. 隔离:不是限额,而是物理分离

资源配额、优先级和限流可以减轻争用,却不能消除“共享命运”。如果 Agent 副本与生产主库仍然访问同一组块服务器、缓存节点或存储带宽,那么 Agent 流量暴涨时,主库仍可能被拖慢。

这里要求的隔离贯穿整条数据路径:

  • Agent 使用独立计算节点;
  • Agent I/O 不经过生产集群使用的数据库组件;
  • 存储层也要分离服务路径或物理段;
  • 数据仍保持秒级以内的新鲜度,而不是每天同步一次的数据仓库副本。

这比“给 Agent 设置 20% 的 IOPS 配额”更严格。共享容量意味着容量耗尽时双方仍会一起受影响。

2. 延迟:冷数据也不能突然慢一个数量级

Agent 的一次回答往往包含多轮检索、过滤和推理。假设一次推理链执行 30 次数据库查询,每次查询又触发若干随机块读取,那么一次缓存未命中从亚毫秒上升到几十毫秒,最终会被放大成明显的端到端延迟。

因此,关键指标不只是缓存命中时的平均延迟,而是:

  • 远端块读取的基线延迟;
  • P95、P99 和 P99.9,而非只有平均值;
  • 数据集超过内存后,索引查询是否仍然稳定;
  • 缓存未命中是否会回落到高延迟对象存储。

Agent 还需要完整数据库引擎提供的索引、点查、全文检索、向量检索、空间查询和 SQL 优化能力。直接扫描对象存储适合部分分析任务,却不能替代低延迟的关系数据库执行路径。

3. 规模:扩展计算的同时,也要扩展 I/O

无状态计算节点可以快速启动,但如果所有节点都依赖一组预置的共享块服务器,那么新增节点只是更快地耗尽同一个 I/O 池。真正的 Agent 级弹性意味着:

  • 数秒内从零扩展到大量数据库计算节点;
  • 节点只运行几十秒或几分钟;
  • 任务结束后自动缩容到零;
  • 存储吞吐随并发一起增长,而不是停留在预置上限;
  • 整个扩缩容过程不影响生产事务。

预先准备上千个副本不仅成本高,也无法应对峰值时间和规模都不可预测的任务。

为什么常见扩展架构会卡住

架构 隔离 延迟 瞬时规模 结构性限制
独立存储的只读副本 较强 稳定 较弱 新副本需要复制或恢复大量数据,通常无法在秒级完成
计算与共享存储服务器分离 较弱 较低 部分满足 计算启动快,但生产和副本争用同一存储服务与带宽
对象存储加共享块缓存 较弱 部分满足 部分满足 缓存未命中会落到高延迟对象存储,块服务器也可能成为瓶颈

这些设计并不是“错误架构”。它们分别解决了过去几十年中的真实问题,但 Agent 把负载模型改变了:查询无法提前审核,并发规模难以预测,任务生命周期又非常短。

尤其需要警惕“副本数量等于扩展能力”这个假设。共享存储架构增加八个读取节点,并不必然得到八倍吞吐。如果后端块服务器先达到带宽上限,副本吞吐会停止增长,生产主库还可能因为资源争用而下降。

AlloyDB 如何拆开生产与 Agent 数据路径

按照发布材料描述,AlloyDB 的 Agent 架构跨存储、网络和计算三层完成隔离,而不是只在数据库进程中增加一个资源组。

存储:直接访问 Colossus

Agent 节点直接读取 Colossus 中专门划分的存储段,不通过需要预热的共享块缓存层。其设计目标是让缓存未命中的远程读取仍保持亚毫秒级基线延迟,并让 Agent I/O 与生产数据路径分开。

材料给出的系统级能力包括单个 AlloyDB 数据库最高 15 TB/s 聚合吞吐和每秒 2000 万次查询。这些数字代表特定基础设施能力,不应直接当作任意业务 SQL 的性能承诺。

网络:让节点位置不再决定存储带宽

Jupiter 数据中心网络连接计算与存储,使 Agent 节点可以在更大范围内调度,而不必围绕少量存储服务器放置。这样扩展计算节点时,网络不会立即成为新的集中式瓶颈。

计算:短生命周期的完整 PostgreSQL 引擎

Agent 通过 MCP 接入独立的 Agent 节点池。每个节点运行在隔离的 microVM 中,提供只读、秒级以内新鲜度的数据视图,同时保留 PostgreSQL 引擎能力,包括普通索引、向量搜索、全文与空间搜索、列式扫描和湖仓联邦查询。

发布材料报告,在大于可用 DRAM 的数据集上执行并发索引查询时,Agent 节点从 1 个扩展到 1000 个,聚合吞吐达到约 300 万 QPS,相对增长 773 倍,同时未观察到主集群性能下降。另一项使用 2100 个节点的全表扫描测试超过了 1 Tbps 聚合吞吐。评估这些数字时,应同时记录查询形态、数据分布、连接方式、结果集大小和成本,避免把基础设施基准直接外推到业务负载。

可以这样实践:先建立一个可重复的只读突发测试

Agent 节点池仍属于特定产品能力,但团队可以先用下面的通用 PostgreSQL 脚本建立验收基线。它不会证明底层已经做到物理隔离,却能测量扩容前后的吞吐、尾延迟和错误率。

运行前需要准备一个只读数据库账号,并将 QUERY 改成业务中有代表性的索引查询。不要使用超级用户,也不要直接对高峰期生产主库执行压力测试。

先创建最小权限角色;请把数据库名、Schema 和密码替换为自己的值:

CREATE ROLE agent_reader LOGIN PASSWORD 'replace-with-a-secret';
GRANT CONNECT ON DATABASE appdb TO agent_reader;
GRANT USAGE ON SCHEMA public TO agent_reader;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO agent_reader;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT SELECT ON TABLES TO agent_reader;
ALTER ROLE agent_reader SET default_transaction_read_only = on;
ALTER ROLE agent_reader SET statement_timeout = '2s';
ALTER ROLE agent_reader SET lock_timeout = '250ms';

然后安装驱动并保存测试脚本:

python3 -m venv .venv
source .venv/bin/activate
pip install 'psycopg[binary]==3.2.6'
# burst_read_test.py
import os
import time
import statistics
from concurrent.futures import ThreadPoolExecutor, as_completed

import psycopg

DSN = os.environ["DATABASE_URL"]
QUERY = os.getenv("QUERY", "SELECT now(), current_database()")
WORKERS = int(os.getenv("WORKERS", "20"))
REQUESTS_PER_WORKER = int(os.getenv("REQUESTS_PER_WORKER", "50"))


def run_worker(worker_id: int):
    latencies_ms = []
    errors = []

    try:
        with psycopg.connect(DSN, autocommit=False) as conn:
            for _ in range(REQUESTS_PER_WORKER):
                started = time.perf_counter()
                try:
                    with conn.transaction():
                        conn.execute("SET TRANSACTION READ ONLY")
                        conn.execute("SET LOCAL statement_timeout = '2s'")
                        with conn.cursor() as cur:
                            cur.execute(QUERY)
                            cur.fetchall()
                    latencies_ms.append((time.perf_counter() - started) * 1000)
                except Exception as exc:
                    errors.append(f"{type(exc).__name__}: {exc}")
    except Exception as exc:
        errors.append(f"connect: {type(exc).__name__}: {exc}")

    return latencies_ms, errors


def percentile(values, p):
    if not values:
        return float("nan")
    ordered = sorted(values)
    index = min(len(ordered) - 1, int((len(ordered) - 1) * p))
    return ordered[index]


started = time.perf_counter()
all_latencies = []
all_errors = []

with ThreadPoolExecutor(max_workers=WORKERS) as pool:
    futures = [pool.submit(run_worker, i) for i in range(WORKERS)]
    for future in as_completed(futures):
        latencies, errors = future.result()
        all_latencies.extend(latencies)
        all_errors.extend(errors)

elapsed = time.perf_counter() - started
completed = len(all_latencies)

print(f"workers={WORKERS}")
print(f"completed={completed} errors={len(all_errors)} elapsed_s={elapsed:.2f}")
print(f"throughput_qps={completed / elapsed:.2f}")
if all_latencies:
    print(f"mean_ms={statistics.mean(all_latencies):.2f}")
    print(f"p50_ms={percentile(all_latencies, 0.50):.2f}")
    print(f"p95_ms={percentile(all_latencies, 0.95):.2f}")
    print(f"p99_ms={percentile(all_latencies, 0.99):.2f}")
if all_errors:
    print("sample_errors:")
    for error in all_errors[:5]:
        print(f"- {error}")

使用只读端点运行:

export DATABASE_URL='postgresql://agent_reader:replace-with-a-secret@db-host:5432/appdb?sslmode=require'
export QUERY='SELECT id, status FROM orders WHERE id = 10001'
export WORKERS=50
export REQUESTS_PER_WORKER=100
python burst_read_test.py

逐步把 WORKERS 从 10、50、100 提高,并同时观察生产主库的事务吞吐、提交延迟、CPU、锁等待和存储 IOPS。如果 Agent 吞吐增加时主库 P99 延迟同步上升,那么系统仍存在共享资源路径。测试时还应让数据集大于缓存,并分别记录热缓存和冷缓存结果,否则很容易把内存命中误认为存储能力。

落地时不要只看“能否扩到 1000 节点”

采购或设计 Agent 数据库平台时,可以使用下面的验收清单:

  • 隔离边界:计算、网络、缓存和存储分别共享了什么?
  • 数据新鲜度:秒级以内是稳定目标,还是最好情况?
  • 冷读延迟:缓存未命中后的 P99 是多少?
  • 扩展曲线:节点增加 10 倍时,吞吐是否接近同比增长?
  • 生产影响:Agent 峰值期间,主库提交延迟和吞吐是否变化?
  • 缩容能力:任务结束后能否真正降到零,计费粒度是什么?
  • SQL 能力:是否保留索引、事务一致性、向量、全文和空间查询?
  • 安全治理:是否有只读角色、行级安全、审计、查询超时和敏感字段控制?
  • 成本边界:大量短查询、连接建立、数据扫描和结果传输分别如何收费?

Agent 不应该直接持有无限制的生产数据库权限。即使底层已经物理隔离,仍要使用最小权限账号、行级安全、语句超时、并发上限和审计日志。基础设施隔离解决的是稳定性问题,不能代替数据授权和业务安全。

真正重要的变化不是“数据库能跑 AI”,而是数据库开始把不可预测的机器流量当作一等公民:Agent 可以读取企业的实时事实、使用完整查询引擎并瞬时扩展,同时不把生产系统变成一次推理任务的附带风险。这也是评估所谓 Agent 数据库时最值得坚持的标准。


相关推荐