← Hyperdrive (Postgres & MySQL) / hyperdrive / concepts
Кеширование запросов
Когда кэширование запросов включено, Hyperdrive автоматически кэширует те запросы на чтение от вашего Worker, которые допускают кэширование. Это снижает нагрузку на базу данных и избавляет от сетевого round trip к базе данных при популярных запросах. Кэширование запросов включено по умолчанию.
Что кэширует Hyperdrive?
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) и запросы, использующие функции, обозначенные как volatile ↗ или stable ↗ в PostgreSQL, не кэшируются:
-- 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 | Нет |
Только функции, обозначенные как IMMUTABLE в PostgreSQL (функции, результат которых не меняется при одинаковых входных данных) совместимы с кэшированием 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 кэширует только ответы на подходящие запросы на чтение.
Это значит, что стратегию кеширования следует выбирать исходя из того, насколько актуальными должны быть данные при каждом чтении:
- Используйте кэширование запросов для чтения данных, которые допускают небольшую задержку актуальности. Хорошими примерами являются публичный контент, дашборды, результаты поиска, каталоги товаров и другие сценарии с интенсивным чтением данных, где небольшая задержка после записи допустима.
- Ниже
max_ageиstale_while_revalidateкогда подходит короткое окно устаревания. Это оставляет кэширование запросов включённым, но сокращает время, в течение которого Hyperdrive может отдавать устаревший результат. - Используйте конфигурацию Hyperdrive с отключённым кэшированием для запросов на чтение, которым нужны только актуальные данные. Создайте вторую конфигурацию Hyperdrive с
--caching-disabled, привяжите его вместе с вашей кешируемой конфигурацией и направляйте эти операции чтения через привязку с отключенным кешем. Хорошими примерами являются аутентификация, сессии, права доступа, статус биллинга, настройки администратора и чтение сразу после записи. См. Отключить кеширование для примера. - Отключайте кэширование запросов повсеместно только тогда, когда большинству операций чтения нужны исключительно свежие данные. Даже при отключённом кэшировании вы по-прежнему получаете пул соединений Hyperdrive и быструю установку соединения.
Если SQL-запросы формирует библиотека объектно-реляционного отображения (ORM) или библиотека аутентификации, создайте отдельные клиенты базы данных для привязок Hyperdrive с включенным и отключенным кешированием. Передайте клиент с отключенным кешированием библиотеке или модулю, которым нужны актуальные данные при чтении, а клиент с включенным кешированием используйте для чтений, допускающих настроенное окно устаревания данных.
Отключить кеширование
Отключите кэширование для отдельной конфигурации Hyperdrive с помощью Wrangler CLI, чтобы задать --caching-disabled опцию.
Чтобы создать для той же базы данных отдельную конфигурацию 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>;Конфигурация Wrangler остаётся одинаковой как для PostgreSQL, так и для MySQL.
{
"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.
- Рекомендации по устранению неполадок см. в Диагностика и отладка.