Christophe Pettus 正在逐个拆解主流托管 PostgreSQL 服务——RDS、Aurora、Cloud SQL 之后,第四站落在了 Google AlloyDB。它和 Aurora 的架构思路相似(分布式存储层替代本地磁盘),但实现路径和运营细节差异足够大,不能简单当作"GCP 版 Aurora"来用。
分布式存储,但不是 Aurora 的翻版
AlloyDB 的核心设计:PostgreSQL 计算节点挂载的不是本地 SSD,而是 Google 自研的分布式存储引擎。写入先进内存日志,再异步落盘到分布式存储集群;读操作可以在存储层直接完成,不必回溯计算节点。这套逻辑和 Aurora 的"日志即数据库"理念方向一致,但底层实现完全不同——Aurora 把 redo 日志当作存储的唯一写入源,存储节点自行拼出完整数据页;AlloyDB 的存储层更像一个高可用块设备,PostgreSQL 的 checkpoint 和后台写入机制仍然在运转。
这意味着两件事:
- AlloyDB 的写入路径保留了更多传统 PG 行为,比如
full_page_writes仍然有效,checkpoint 触发的 I/O 真实存在。Aurora 则把这些逻辑下沉到存储层,计算节点几乎不做后台写。 - 故障恢复的节奏不同。Aurora 计算节点重启后,存储层已经持有最新数据页,恢复极快;AlloyDB 仍需要走 PostgreSQL 的 crash recovery 流程,从存储层拉取 WAL 重放——速度比传统 PG 快(WAL 不再从本地磁盘读),但比 Aurora 的"零恢复"多了一步。
读扩展:Columnar Engine 是真正的差异化点
Aurora 的读副本是独立计算节点,各自维护完整 buffer pool,和主节点之间通过存储层共享数据页。AlloyDB 也支持读副本,但额外加了一层 列式引擎(Columnar Engine)——它把热数据自动转化为列存格式,缓存在内存里,对分析型查询加速明显。
这不是 PostgreSQL 原生能力,而是 AlloyDB 在存储层之上的附加组件。 Pettus 的测试表明,对典型 OLAP 模式的聚合查询,列式引擎可以带来数倍到数十倍的性能提升,代价是内存占用上升,且只对特定查询模式有效。如果你的负载是纯 OLTP,这个引擎基本不参与;如果混合了报表和实时查询,它就是 AlloyDB 相比 Aurora 和 Cloud SQL 最硬的卖点。
实际操作:创建 AlloyDB 集群并验证列式引擎效果
下面用 gcloud 命令创建一个 AlloyDB 集群和主实例,再连接数据库观察列式引擎的行为。前提:你已启用 AlloyDB API,网络已配置好私有服务访问。
# 1. 创建 AlloyDB 集群(指定网络和自动备份)
gcloud alloydb clusters create my-alloydb-cluster \
--region=us-central1 \
--network=projects/YOUR_PROJECT/global/networks/default \
--enable-automated-backups
# 2. 在集群内创建主实例
gcloud alloydb instances create my-alloydb-primary \
--cluster=my-alloydb-cluster \
--region=us-central1 \
--instance-type=PRIMARY \
--machine-type=n2-standard-4 \
--database-flags=alloydb.columnar_engine.enabled=true
# 3. 创建一个读副本
gcloud alloydb instances create my-alloydb-read-pool \
--cluster=my-alloydb-cluster \
--region=us-central1 \
--instance-type=READ_POOL \
--machine-type=n2-standard-2
# 4. 获取连接信息(通过 Cloud SQL Auth Proxy 连接)
gcloud alloydb instances describe my-alloydb-primary \
--cluster=my-alloydb-cluster \
--region=us-central1 \
--format="value(ipAddress)"
连接到数据库后,可以用以下 SQL 触发列式引擎的自动优化并观察效果:
-- 创建一张足够大的测试表
CREATE TABLE orders (
id BIGSERIAL PRIMARY KEY,
customer_id INT NOT NULL,
product_id INT NOT NULL,
quantity INT NOT NULL,
unit_price NUMERIC(10,2) NOT NULL,
order_date DATE NOT NULL
);
-- 插入 100 万行模拟数据
INSERT INTO orders (customer_id, product_id, quantity, unit_price, order_date)
SELECT
(random() * 10000)::int,
(random() * 500)::int,
(random() * 20 + 1)::int,
(random() * 500 + 5)::numeric(10,2),
CURRENT_DATE - (random() * 365)::int
FROM generate_series(1, 1000000);
-- 让列式引擎学习并缓存这张表(需要运行几次查询触发)
-- 第一次:走行存,较慢
SELECT customer_id, SUM(quantity * unit_price) AS total_spent
FROM orders
WHERE order_date BETWEEN '2024-01-01' AND '2024-06-30'
GROUP BY customer_id
ORDER BY total_spent DESC
LIMIT 20;
-- 多次执行后,列式引擎自动将热数据转为列存
-- 再次执行同一查询,观察执行时间下降
-- 查看列式引擎状态
SELECT * FROM alloydb_columnar_engine_status();
注意:
alloydb_columnar_engine_status()是 AlloyDB 提供的扩展视图,具体名称以官方文档为准。列式引擎的自动缓存需要多次查询触发,不会在单次执行后立即生效。
和 Aurora 对比时容易忽略的细节
Pettus 在系列文章中反复强调一个观点:托管服务的差异不在架构图上,而在运维细节里。 AlloyDB 有几个值得注意的点:
- 版本升级节奏:AlloyDB 目前紧跟 PostgreSQL 主线版本,但 Google 对补丁的推送有自己的节奏,不像 RDS 那样几乎同步上游 minor release。如果你依赖某个特定补丁修复,需要确认 AlloyDB 是否已包含。
- 扩展兼容性:AlloyDB 支持大部分常用 PG 扩展(
pg_stat_statements、pg_bigm等),但列式引擎和某些直接操作存储层的扩展可能冲突。部署前查官方兼容列表。 - 备份与 PITR:AlloyDB 的备份在存储层完成,不经过计算节点,对运行时性能影响小。PITR 精度到秒级,和 Aurora 类似,但恢复流程需要先创建新集群再还原,不像 RDS 那样一键回滚——操作步骤更多,规划恢复演练很重要。
选择前的务实清单
在 RDS / Aurora / Cloud SQL / AlloyDB 之间做选择,Pettus 的建议可以浓缩为几条判断规则:
| 场景 | 推荐 |
|---|---|
| 纯 OLTP,不需要读扩展,追求最低运维成本 | RDS 或 Cloud SQL |
| 大量读副本,写压力中等,AWS 生态 | Aurora |
| 混合 OLTP + 实时报表,GCP 生态 | AlloyDB |
| 需要完全控制 PG 参数和扩展,托管只管硬件 | 任何方案都不够,看自建 |
AlloyDB 的列式引擎对混合负载是真实加分项,但它不是免费的——内存开销、引擎学习延迟、查询模式匹配都是实际约束。把它当作"GCP 上更好的 PG 托管"没问题,但别忽略它和 Aurora 在故障恢复、版本策略、扩展兼容上的行为差异。托管选型不是选架构图,是选你愿意接受哪些运维边界。