启用查询缓存时,Hyperdrive 会自动缓存 Worker 发往数据库的可缓存读查询。这可减轻数据库负载,并避免热门查询到数据库的网络往返。查询缓存默认开启。
Hyperdrive 使用数据库协议区分变更查询(写入数据库)与非变更查询(只读)。Hyperdrive 缓存符合条件的只读查询响应,不缓存写入。
除区分 SELECT 与 INSERT 外,Hyperdrive 还会解析数据库 wire 协议以判断查询是变更还是非变更。
例如,填充新闻网站首页的读查询会被缓存:
-- Cacheable: uses a parameterized date value instead of CURRENT_DATE
SELECT * FROM articles WHERE DATE(published_time) = $1
ORDER BY published_time DESC LIMIT 50-- Cacheable: uses a parameterized date value instead of CURDATE()
SELECT * FROM articles WHERE DATE(published_time) = ?
ORDER BY published_time DESC LIMIT 50变更查询(包括 INSERT、UPSERT 或 CREATE TABLE)以及使用 PostgreSQL 标记为 volatile ↗ 或 stable ↗ 的函数的查询不会被缓存:
-- Not cached: mutating queries
INSERT INTO users(id, name, email) VALUES(555, 'Matt', '[email protected]');
-- Not cached: LASTVAL() is a volatile function
SELECT LASTVAL(), * FROM articles LIMIT 50;
-- Not cached: NOW() is a stable function
SELECT * FROM events WHERE created_at > NOW() - INTERVAL '1 hour';-- Not cached: mutating queries
INSERT INTO users(id, name, email) VALUES(555, 'Thomas', '[email protected]');
-- Not cached: LAST_INSERT_ID() is a volatile function
SELECT LAST_INSERT_ID(), * FROM articles LIMIT 50;
-- Not cached: NOW() returns a non-deterministic value
SELECT * FROM events WHERE created_at > NOW() - INTERVAL 1 HOUR;常见不可缓存的 PostgreSQL 函数包括:
| 函数 | PostgreSQL 易变性类别 | 是否缓存 |
|---|---|---|
NOW() |
STABLE | 否 |
CURRENT_TIMESTAMP |
STABLE | 否 |
CURRENT_DATE |
STABLE | 否 |
CURRENT_TIME |
STABLE | 否 |
LOCALTIME |
STABLE | 否 |
LOCALTIMESTAMP |
STABLE | 否 |
TIMEOFDAY() |
VOLATILE | 否 |
RANDOM() |
VOLATILE | 否 |
LASTVAL() |
VOLATILE | 否 |
TXID_CURRENT() |
STABLE | 否 |
仅 PostgreSQL 标记为 IMMUTABLE(相同输入返回值不变)的函数与 Hyperdrive 缓存兼容。若查询使用 STABLE 或 VOLATILE 函数,将函数调用移到应用代码,并将结果值作为查询参数传入。
Hyperdrive 的默认缓存行为:
max_age= 60 秒(1 分钟)stale_while_revalidate= 15 秒
max_age 决定查询响应从缓存提供的最长生命周期。很少使用的缓存响应可能在此时间之前被驱逐。
stale_while_revalidate 允许 Hyperdrive 在重新验证缓存期间继续提供过期缓存结果。大多数情况下,重新验证会很快完成。
max_age 最大可设为 1 小时。
应用写入数据库时,Hyperdrive 不会清除或使已缓存的读查询结果失效。后续匹配的 SELECT 可能返回缓存结果,直到配置的 max_age 过期。Hyperdrive 还可在 stale_while_revalidate 窗口内提供结果,同时在后台刷新缓存。
写入仍会到达数据库。Hyperdrive 仅缓存符合条件的读查询响应。
因此应根据每次读操作对新鲜度的要求选择缓存策略:
- 对可容忍短暂 stale 的读使用查询缓存。 适用场景包括公开内容、仪表板、搜索结果、产品目录等高流量读,写入后短延迟可接受。
- 当短 stale 窗口可接受时,降低
max_age和stale_while_revalidate。 保持查询缓存开启,同时缩短 Hyperdrive 可提供旧结果的时间。 - 对必须最新的读使用禁用缓存的 Hyperdrive 配置。 创建第二个带
--caching-disabled的 Hyperdrive 配置,与缓存配置一起绑定,将这些读路由到禁用缓存的绑定。适用场景包括认证、会话、权限、账单状态、管理设置以及写入后立即读。示例请参阅禁用缓存。 - 仅当大多数读必须最新时,才全局禁用查询缓存。 禁用缓存时仍可获得 Hyperdrive 的连接池和快速连接建立。
若对象关系映射(ORM)库或认证库拥有 SQL,为缓存和禁用缓存的 Hyperdrive 绑定创建独立的数据库客户端。将禁用缓存的客户端传给需要最新读的库或模块,缓存客户端用于可容忍配置 stale 窗口的读。
使用 Wrangler CLI 的 --caching-disabled 选项,按 Hyperdrive 配置禁用缓存。
对同一数据库创建单独的禁用缓存 Hyperdrive 配置:
npx wrangler hyperdrive create my-database-fresh --connection-string="<DATABASE_CONNECTION_STRING>" --caching-disabled关闭现有 Hyperdrive 配置的缓存:
npx wrangler hyperdrive update <HYPERDRIVE_CONFIG_ID> --caching-disabled单个应用可配置多个 Hyperdrive 连接:一个为热门查询启用缓存,第二个用于不应使用查询缓存的最新读。
对同一数据库使用多个 Hyperdrive 配置时,需考虑所有配置到源数据库的总连接数。请参阅调整连接池。
例如,使用数据库驱动:
export default {
async fetch(request, env, ctx): Promise<Response> {
// Create clients inside your handler — not in global scope
const client = postgres(env.HYPERDRIVE.connectionString);
// Use the cache-disabled binding for auth, permissions, and reads after writes.
const clientNoCache = postgres(env.HYPERDRIVE_CACHE_DISABLED.connectionString);
// ...
},
} satisfies ExportedHandler<Env>;export default {
async fetch(request, env, ctx): Promise<Response> {
// Create connections inside your handler — not in global scope
const connection = await createConnection({
host: env.HYPERDRIVE.host,
user: env.HYPERDRIVE.user,
password: env.HYPERDRIVE.password,
database: env.HYPERDRIVE.database,
port: env.HYPERDRIVE.port,
});
// Use the cache-disabled binding for auth, permissions, and reads after writes.
const connectionNoCache = await createConnection({
host: env.HYPERDRIVE_CACHE_DISABLED.host,
user: env.HYPERDRIVE_CACHE_DISABLED.user,
password: env.HYPERDRIVE_CACHE_DISABLED.password,
database: env.HYPERDRIVE_CACHE_DISABLED.database,
port: env.HYPERDRIVE_CACHE_DISABLED.port,
});
// ...
},
} satisfies ExportedHandler<Env>;PostgreSQL 和 MySQL 的 Wrangler 配置相同。
{
"hyperdrive": [
{
"binding": "HYPERDRIVE",
"id": "<YOUR_HYPERDRIVE_CACHE_ENABLED_CONFIGURATION_ID>",
},
{
"binding": "HYPERDRIVE_CACHE_DISABLED",
"id": "<YOUR_HYPERDRIVE_CACHE_DISABLED_CONFIGURATION_ID>",
},
],
}[[hyperdrive]]
binding = "HYPERDRIVE"
id = "<YOUR_HYPERDRIVE_CACHE_ENABLED_CONFIGURATION_ID>"
[[hyperdrive]]
binding = "HYPERDRIVE_CACHE_DISABLED"
id = "<YOUR_HYPERDRIVE_CACHE_DISABLED_CONFIGURATION_ID>"- 更多信息请参阅 Hyperdrive 工作原理。
- 连接 PostgreSQL 请参阅 连接 PostgreSQL。
- 故障排除请参阅 故障排除与调试。