Перейти к содержимому
Последнее обновление

Кэш данных

Data Cache ускоряет последующие запросы к одним и тем же данным, кэшируя недавно использованные файлы данных из удалённых систем хранения (HDFS или объектных хранилищ) на локальных дисках. При частом обращении к одним и тем же данным Data Cache позволяет избежать накладных расходов на повторный доступ к удалённым данным, повышая производительность и стабильность аналитических запросов к горячим данным.

Сценарии применения​

Кэширование данных работает только для запросов к таблицам Hive, Iceberg, Hudi и Paimon. Оно не влияет на запросы к внутренним таблицам и внешним таблицам, не основанным на файлах (например, JDBC, Elasticsearch).

Возможность повысить эффективность запросов с помощью кэширования данных зависит от нескольких факторов. Ниже приведены условия, при которых кэширование данных целесообразно:

  • Высокоскоростной локальный диск

    Каталог кэша данных рекомендуется размещать на высокоскоростных локальных дисках, например SSD или NVME. Использовать для этого механические жёсткие диски не рекомендуется. Для заметного повышения производительности пропускная способность IO и IOPS локального диска должны существенно превышать пропускную способность сети, а также пропускную способность IO и IOPS исходной системы хранения.

  • Достаточный объём кэша

    Для вытеснения данных из кэша используется стратегия LRU. Если в запрашиваемых данных нет чёткого разделения на горячие и холодные, содержимое кэша может часто обновляться и заменяться, что способно снизить производительность запросов. Кэширование данных рекомендуется включать, когда характер запросов позволяет чётко разделить данные на горячие и холодные (например, большинство запросов обращается только к сегодняшним данным и редко затрагивает исторические), а объёма кэша достаточно для хранения горячих данных.

  • Нестабильная задержка IO удалённого хранилища

    Такая ситуация обычно возникает при использовании HDFS. В большинстве организаций разные подразделения совместно используют одну систему HDFS, что может приводить к значительным колебаниям задержки IO в периоды пиковой нагрузки. Если в таких условиях требуется обеспечить стабильную задержку IO, рекомендуется включить кэширование данных. При этом необходимо учитывать и первые два условия.

Включение Data Cache​

Начиная с Doris 4.2, Data Cache включён по умолчанию: и параметр BE enable_file_cache, и переменная сеанса enable_file_cache по умолчанию имеют значение true. Для использования кэша настройте его каталог в be.conf; с помощью параметра FE можно включать и отключать кэширование для отдельного сеанса или глобально.

Настройка BE​

Сначала настройте путь к кэшу в be.conf и перезапустите узел BE, чтобы конфигурация вступила в силу.

ПараметрОбязательныйОписание
enable_file_cacheНетОпределяет, включён ли Data Cache. Начиная с Doris 4.2 включён по умолчанию.
file_cache_pathДаНастройки каталога кэша в формате JSON.
clear_file_cacheНетЗначение по умолчанию: false. Если задано true, каталог кэша очищается при перезапуске узла BE.

Пример настройки file_cache_path:

file_cache_path=[{"path": "/path/to/file_cache1", "total_size":53687091200},{"path": "/path/to/file_cache2", "total_size":53687091200},{"path": "/path/to/file_cache3", "total_size":53687091200}]

path задаёт путь для хранения кэша. Можно настроить один или несколько путей. Рекомендуется указывать только один путь на диск.

total_size задаёт верхний предел объёма кэша в байтах. При превышении этого предела кэшированные данные вытесняются по стратегии LRU.

Настройка FE​

Включение Data Cache для отдельного сеанса:

SET enable_file_cache = true;

Глобальное включение Data Cache:

SET GLOBAL enable_file_cache = true;

Сканирование внешних файлов использует кэш только тогда, когда включены параметр BE enable_file_cache, переменная сеанса enable_file_cache и допуск в кэш разрешён механизмом контроля. Переменная сеанса не влияет на внутренние таблицы.

File Cache включён по умолчанию начиная с Doris 4.2
  • На BE с совмещёнными хранением и вычислениями, где не задан file_cache_path, кэш создаётся в ${DORIS_HOME}/file_cache и при отсутствии total_size может расти до заполнения диска на 85%–88%. Задайте file_cache_path с указанием total_size, чтобы ограничить его объём, или установите enable_file_cache = false в be.conf, чтобы сохранить прежнее поведение.
  • Настройки BE не сохраняются в состоянии кластера, поэтому после обновления BE использует значение по умолчанию, скомпилированное в его бинарный файл, если соответствующий ключ не задан в be.conf. Переменные сеанса сохраняются в образе FE, поэтому кластер, обновлённый с более ранней версии, сохраняет прежнее значение; чтобы кэшировать внешние таблицы после обновления, выполните SET GLOBAL enable_file_cache = true.

Наблюдаемость кэша​

Просмотр доли попаданий в кэш​

Выполните set enable_profile=true, чтобы включить соответствующую переменную сеанса. После этого профиль задания можно просмотреть на вкладке Queries веб-интерфейса FE. Метрики кэша данных приведены ниже:

-  FileCache:  0ns
- BytesScannedFromCache: 2.02 GB
- BytesScannedFromRemote: 0.00
- BytesWriteIntoCache: 0.00
- LocalIOUseTimer: 2s723ms
- NumLocalIOTotal: 444
- NumRemoteIOTotal: 0
- NumSkipCacheIOTotal: 0
- RemoteIOUseTimer: 0ns
- WriteCacheIOUseTimer: 0ns
  • BytesScannedFromCache: объём данных, прочитанных из локального кэша.

  • BytesScannedFromRemote: объём данных, прочитанных из удалённого хранилища.

  • BytesWriteIntoCache: объём данных, записанных в кэш.

  • LocalIOUseTimer: время IO локального кэша.

  • RemoteIOUseTimer: время IO при чтении из удалённого хранилища.

  • NumLocalIOTotal: количество операций IO с локальным кэшем.

  • NumRemoteIOTotal: количество удалённых операций IO.

  • WriteCacheIOUseTimer: время IO при записи в кэш.

Если BytesScannedFromRemote равен 0, все данные прочитаны из кэша.

Метрики мониторинга​

Статистику кэша для каждого узла Backend можно просмотреть в системной таблице file_cache_statistics.

Ограничения кэша для запросов​

Doris предоставляет два независимых механизма управления Data Cache на уровне запроса:

МеханизмОсновной параметрПоведение после достижения ограничения
Ограничение доли занимаемого кэшаfile_cache_query_limit_percentЗаполнение кэша при промахах остаётся разрешённым, а BE освобождает место с помощью учёта LRU на уровне запроса и других очередей кэша
Прекращение записи в кэш при удалённом сканировании по порогу в байтахfile_cache_query_limit_bytesЕсли следующий блок кэша приведёт к превышению порога допущенных байтов, при последующих промахах данные читаются из удалённого хранилища без заполнения локального кэша

Ограничение доли занимаемого кэша​

Эта функция поддерживается начиная с версии 4.0.3.

Ограничение доли занимаемого кэша задаёт максимальный процент каждого экземпляра File Cache, который может использовать один запрос. Когда несколько пользователей или сложных запросов совместно используют ресурсы кэша, это снижает риск того, что один крупный запрос займёт слишком большую часть кэша и вытеснит другие горячие данные.

Для использования этой функции требуется настройка BE, FE и переменных сеанса.

1. Настройка BE

  • enable_file_cache_query_limit:
    • Тип: Boolean
    • Значение по умолчанию: false
    • Описание: главный переключатель функции ограничения файлового кэша для запросов на стороне BE. BE обрабатывает параметры ограничения, переданные из FE, только при включении этого переключателя.

2. Настройка FE

  • file_cache_query_limit_max_percent:
    • Тип: Integer
    • Значение по умолчанию: 100
    • Описание: максимальное ограничение для запроса, используемое для проверки верхней границы значения переменной сеанса.

3. Переменные сеанса

  • file_cache_query_limit_percent:
    • Тип: Integer (1-100)
    • Значение по умолчанию: -1
    • Описание: максимальный процент кэша, который может использовать запрос. Это значение ограничивается параметром file_cache_query_limit_max_percent. Рассчитанная квота кэша должна составлять не менее 256 MB; в противном случае BE записывает предупреждение в журнал.

Пример использования

-- Set the session variable to limit a query to at most 50% of the cache
SET file_cache_query_limit_percent = 50;

-- Execute the query
SELECT * FROM large_table;

Примечания:

  1. Значение должно находиться в диапазоне [1, file_cache_query_limit_max_percent].
  2. Перед использованием этого механизма включите на BE параметры enable_file_cache и enable_file_cache_query_limit, а также убедитесь, что в сеансе запроса переменная enable_file_cache имеет значение true.
  3. После достижения процентной квоты запись в Data Cache при промахах остаётся разрешённой. Этот механизм не переводит запрос в режим прекращения дальнейшей записи.

Прекращение записи в кэш при удалённом сканировании по порогу в байтах​

В режиме разделения вычислений и хранения переменная сеанса file_cache_query_limit_bytes ограничивает суммарный объём байтов, допущенных к записи в Data Cache при промахах кэша файлов данных Hive, Iceberg, Hudi или Paimon для одного запроса SELECT на каждом BE. Для её работы требуется enable_file_cache=true на BE, но она не зависит от enable_file_cache_query_limit или file_cache_query_limit_max_percent.

ПараметрТипЗначение по умолчаниюОписание
file_cache_query_limit_bytesBigInt-1Порог заполнения кэша при удалённом сканировании для одного запроса на каждом BE, в байтах. Значение меньше 0 отключает ограничение; 0 отключает заполнение кэша с самого начала запроса; при положительном значении допущенные байты суммируются по блокам кэша

Параллельные сканеры одного запроса используют общий порог на BE. Этот порог не является суммарным ограничением для всего запроса или кластера. Если следующий блок кэша приведёт к превышению порога допущенных байтов, запрос на этом BE переходит в режим чтения только из удалённого хранилища при промахе: диапазон запроса, полностью покрытый локальным кэшем, по-прежнему может быть прочитан локально; диапазон, покрытый не полностью, читается напрямую из удалённого хранилища без заполнения Data Cache. Результат запроса не изменяется.

В следующем примере на каждом BE задаётся порог заполнения кэша при удалённом сканировании, равный 1 GiB:

SET enable_profile = true;
SET profile_level = 2;
SET file_cache_query_limit_bytes = 1073741824;

SELECT COUNT(*) FROM hive_catalog.sales.orders;

Чтобы однократное сканирование не записывало данные в Data Cache с самого начала, установите порог в 0, а после запроса восстановите значение по умолчанию:

SET file_cache_query_limit_bytes = 0;
SELECT COUNT(*) FROM hive_catalog.sales.orders;

SET file_cache_query_limit_bytes = -1;

После включения Query Profile проверьте RemoteOnlyOnMissTriggered и RemoteOnlyOnMissThresholdBytes в группе метрик FileCache сканера Scanner. Значение RemoteOnlyOnMissTriggered=1 означает, что Scanner зафиксировал переход запроса в режим чтения только из удалённого хранилища при промахе. Используйте BytesWriteIntoCache и NumSkipCacheIOTotal для проверки фактических записей и операций I/O, выполненных в обход кэша. Поскольку NumSkipCacheIOTotal может также учитывать операции I/O, пропустившие кэш из-за других политик кэширования, одной этой метрики недостаточно, чтобы подтвердить срабатывание порога.

примечание
  • Этот механизм применяется только к заполнению Data Cache после промахов запросов SELECT в режиме разделения вычислений и хранения. Он не ограничивает объём байтов, читаемых из удалённого хранилища, и не влияет на явный прогрев кэша. Режим чтения только из удалённого хранилища при промахе может увеличить объём удалённых операций I/O и задержку запроса.
  • Допуск оценивается для каждого блока кэша. Если оставшийся бюджет меньше следующего блока, весь блок пропускается. RemoteOnlyOnMissTriggered принимает значение 1 только тогда, когда очередной блок привёл бы к превышению порога.
  • Параметр BE enable_file_cache_query_limit_segment_meta определяет, учитывается ли запись концевых данных Segment и метаданных Segment внутренних таблиц Doris в рамках того же порога. Заполнение кэша файлов данных Hive, Iceberg, Hudi и Paimon всегда подпадает под действие file_cache_query_limit_bytes. Полную область действия параметра и поведение для внутренних таблиц см. в руководстве по настройке и использованию File Cache.

Прогрев кэша​

Data Cache предоставляет функцию «прогрева» кэша, которая позволяет предварительно загружать внешние данные в локальный кэш узлов BE, повышая долю попаданий в кэш и производительность последующих запросов, впервые обращающихся к этим данным.

Эта функция поддерживается начиная с версии 4.0.2.

Синтаксис​

WARM UP SELECT <select_expr_list>
FROM <table_reference>
[WHERE <boolean_expression>]

Ограничения использования:

  • Поддерживается:

    • Запросы к одной таблице (допускается только один table_reference)
    • Простой SELECT для указанных столбцов
    • Фильтрация WHERE (поддерживаются обычные предикаты)
  • Не поддерживается:

    • JOIN, UNION, подзапросы, CTE
    • GROUP BY, HAVING, ORDER BY
    • LIMIT
    • INTO OUTFILE
    • Планы запросов к нескольким таблицам и сложные планы запросов
    • Другие сложные синтаксические конструкции

Примеры​

  1. Прогрев всей таблицы
WARM UP SELECT * FROM hive_db.tpch100_parquet.lineitem;
  1. Прогрев отдельных столбцов по разделу
WARM UP SELECT l_orderkey, l_shipmode
FROM hive_db.tpch100_parquet.lineitem
WHERE dt = '2025-01-01';
  1. Прогрев отдельных столбцов по условиям фильтрации
WARM UP SELECT l_shipmode, l_linestatus
FROM hive_db.tpch100_parquet.lineitem
WHERE l_orderkey = 123456;

Результаты выполнения​

После выполнения WARM UP SELECT FE отправляет задачи на каждый BE. BE сканирует удалённые данные и записывает их в Data Cache.

Система сразу возвращает статистику сканирования и записи в кэш для каждого BE (примечание: статистика обычно точна, но возможна некоторая погрешность). Например:

+---------------+-----------+-------------+---------------------------+----------------------------+---------------------+
| BackendId | ScanRows | ScanBytes | ScanBytesFromLocalStorage | ScanBytesFromRemoteStorage | BytesWriteIntoCache |
+---------------+-----------+-------------+---------------------------+----------------------------+---------------------+
| 1755134092928 | 294744184 | 11821864798 | 538154009 | 11283717130 | 11899799492 |
| 1755134092929 | 305293718 | 12244439301 | 560970435 | 11683475207 | 12332861380 |
| TOTAL | 600037902 | 24066304099 | 1099124444 | 22967192337 | 24232660872 |
+---------------+-----------+-------------+---------------------------+----------------------------+---------------------+

Описание полей:

  • ScanRows: количество просканированных и прочитанных строк.
  • ScanBytes: объём просканированных и прочитанных данных.
  • ScanBytesFromLocalStorage: объём данных, просканированных и прочитанных из локального кэша.
  • ScanBytesFromRemoteStorage: объём данных, просканированных и прочитанных из удалённого хранилища.
  • BytesWriteIntoCache: объём данных, записанных в Data Cache во время этого прогрева.

Контроль допуска в кэш​

Это экспериментальная функция, которая поддерживается начиная с версии 4.1.0.

Функция контроля допуска в кэш позволяет пользователям определять, могут ли данные, прочитанные запросом, попадать в File Cache (Data Cache), с учётом таких параметров, как пользователь, Catalog, база данных и таблица. При массовом чтении холодных данных (например, в масштабных заданиях ETL или ресурсоёмких нерегламентированных запросах) допуск всех прочитанных данных в кэш может приводить к частому вытеснению уже находящихся в нём горячих данных, то есть к «загрязнению кэша». Это снижает долю попаданий в кэш и общую производительность запросов. Когда контроль включён, данные, которым отказано в допуске, загружаются напрямую из удалённого базового хранилища (например, HDFS, S3), что защищает основные горячие данные от вытеснения.

По умолчанию функция контроля допуска в кэш отключена. Для её включения необходимо настроить соответствующие параметры FE.

Настройка FE​

Включите эту функцию и укажите путь к файлам правил в fe.conf, затем перезапустите узел FE, чтобы настройки вступили в силу. Изменения самих файлов правил могут загружаться динамически.

ПараметрОбязательныйОписание
enable_file_cache_admission_controlДаОпределяет, включён ли контроль допуска в кэш. Значение по умолчанию: false.
file_cache_admission_control_json_dirДаПуть к каталогу для хранения файлов JSON с правилами допуска. Все файлы .json в этом каталоге загружаются автоматически, а любые добавления, удаления или изменения правил вступают в силу динамически.

Формат настройки правил допуска​

Настройки правил размещаются в файлах .json в каталоге file_cache_admission_control_json_dir. Содержимое файла должно представлять собой массив JSON.

Описание полей​

Имя поляТипОписаниеПример
idLongИдентификатор правила.1
user_identityStringИдентификатор пользователя (формат: user@host, например % соответствует всем IP-адресам). Пустое или отсутствующее поле соответствует всем пользователям глобально."root@%"
catalog_nameStringИмя Catalog. Пустое или отсутствующее поле соответствует всем Catalog."hive_cat"
database_nameStringИмя базы данных. Пустое или отсутствующее поле соответствует всем базам данных."db1"
table_nameStringИмя таблицы. Пустое или отсутствующее поле соответствует всем таблицам."tbl1"
partition_patternString(Пока не реализовано) Регулярное выражение для раздела. Пустое значение соответствует всем разделам.""
rule_typeIntegerТип правила: 0 запрещает кэширование (чёрный список); 1 разрешает кэширование (белый список).0
enabledIntegerОпределяет, включено ли текущее правило: 0 означает, что оно отключено; 1 означает, что оно включено.1
created_timeLongВремя создания (метка времени UNIX, в секундах).1766557246
updated_timeLongВремя обновления (метка времени UNIX, в секундах).1766557246

Пример файла JSON​

[
{
"id": 1,
"user_identity": "root@%",
"catalog_name": "hive_cat",
"database_name": "db1",
"table_name": "table1",
"partition_pattern": "",
"rule_type": 0,
"enabled": 1,
"created_time": 1766557246,
"updated_time": 1766557246
},
{
"id": 2,
"user_identity": "",
"catalog_name": "hive_cat",
"database_name": "",
"table_name": "",
"partition_pattern": "",
"rule_type": 1,
"enabled": 1,
"created_time": 1766557246,
"updated_time": 1766557246
}
]

Импорт правил из MySQL​

Для автоматизированной интеграции с другими системами в репозитории исходного кода Doris предусмотрен вспомогательный скрипт tools/export_mysql_rule_to_json.sh. С его помощью можно экспортировать правила допуска в кэш, предварительно сохранённые в таблице базы данных MySQL, в файлы конфигурации JSON, соответствующие описанному выше формату.

Принципы сопоставления правил​

Категории областей действия правил​

Комбинируя пустые и конкретные значения полей (user_identity, catalog_name, database_name, table_name), можно задать 7 допустимых вариантов области действия правил. Любая конфигурация правила, нарушающая иерархические зависимости (например, если таблица указана напрямую без базы данных), считается недопустимой.

user_identitycatalog_namedatabase_nametable_nameУровень и область действия
УказаноУказаноУказаноУказаноПравило уровня таблицы для указанного пользователя
Пусто или отсутствуетУказаноУказаноУказаноПравило уровня таблицы для всех пользователей
УказаноУказаноУказаноПусто или отсутствуетПравило уровня базы данных для указанного пользователя
Пусто или отсутствуетУказаноУказаноПусто или отсутствуетПравило уровня базы данных для всех пользователей
УказаноУказаноПусто или отсутствуетПусто или отсутствуетПравило уровня Catalog для указанного пользователя
Пусто или отсутствуетУказаноПусто или отсутствуетПусто или отсутствуетПравило уровня Catalog для всех пользователей
УказаноПусто или отсутствуетПусто или отсутствуетПусто или отсутствуетГлобальное правило для указанного пользователя

Приоритет и порядок сопоставления​

Когда запрос обращается к данным таблицы, система оценивает правила, чтобы принять решение о допуске в кэш. При этом действуют следующие принципы:

  1. Сначала точное совпадение: сопоставление выполняется от наиболее конкретного уровня к наиболее общему (таблица → база данных → Catalog → глобальный уровень). Как только найдено совпадение на самом точном уровне (например, уровне таблицы), проверка немедленно завершается.
  2. Приоритет чёрного списка (принцип безопасности): на одном уровне правил правила запрета кэширования всегда имеют приоритет перед правилами разрешения кэширования. Если одновременно найдены совпадения с чёрным и белым списками, сначала применяется чёрный список, обеспечивая приоритет решения о запрете на том же уровне.

Полная последовательность принятия решения выглядит следующим образом:

1. Table-level rule matching
a) Hit Blacklist (rule_type=0) -> Deny
b) Hit Whitelist (rule_type=1) -> Allow
2. Database-level rule matching
...
3. Catalog-level rule matching
...
4. Global rule matching (only user_identity matched)
...
5. Default fallback decision: If no rules at any level above match, caching is [Denied] by default (equivalent to a global blacklist).

Совет: поскольку при отсутствии совпадений система по умолчанию запрещает кэширование, при внедрении этой функции обычно рекомендуется сначала создать общее разрешающее правило (например, белый список для всех пользователей или для важного бизнес-Catalog), а затем настроить адресные чёрные списки уровня таблицы для крупных таблиц, которые заведомо подвергаются полному сканированию в ходе офлайн-обработки. Это позволяет точнее разделять холодные и горячие данные.

Наблюдаемость решений о допуске в кэш​

После успешного включения функции и применения настроек пользователи могут просматривать подробные решения о допуске в кэш на уровне файловых данных отдельной таблицы с помощью команды EXPLAIN (см. строку file cache request в выводе ниже).

|   0:VHIVE_SCAN_NODE(74)                                                                                          |
| table: test_file_cache_features.tpch1_parquet.lineitem |
| inputSplitNum=10, totalFileSize=205792918, scanRanges=10 |
| partition=1/1 |
| cardinality=1469949, numNodes=1 |
| pushdown agg=NONE |
| file cache request ADMITTED: user_identity:root@%, reason:user table-level whitelist rule, cost:0.058 ms |
| limit: 1 |

Основные поля и описание решений:

  • ADMITTED / DENIED: показывает, разрешён ли запросу допуск в кэш (ADMITTED) или в нём отказано (DENIED).
  • user_identity: идентификатор пользователя, проверенный при выполнении этого запроса.
  • reason: конкретная причина решения (совпавшее правило), определившая результат. Часто встречаются следующие значения: user table-level whitelist rule (в текущем примере: белый список уровня таблицы для указанного пользователя); common table-level blacklist rule (чёрный список уровня таблицы для всех пользователей). Общий формат: [Scope] [Rule Level] [Rule Type] rule.
  • cost: время выполнения всей процедуры сопоставления правил допуска (в миллисекундах). Если накладные расходы слишком велики, их можно снизить, скорректировав количество уровней иерархии правил.

Приложение​

Принцип работы​

Кэширование данных сохраняет используемые удалённые данные на локальном узле BE. Исходный файл данных разбивается на блоки в соответствии с размером операций IO, а блоки сохраняются в локальном файле cache_path/hash(filepath).substr(0, 3)/hash(filepath)/offset. Метаданные блоков хранятся на узле BE. При обращении к тому же удалённому файлу Doris проверяет наличие его данных в локальном кэше и на основе смещения и размера блока определяет, какие данные читать из локального блока, а какие загружать из удалённого хранилища. Вновь загруженные удалённые данные кэшируются. При перезапуске узел BE сканирует каталог cache_path, чтобы восстановить метаданные блоков. Когда объём кэша достигает верхнего предела, давно не использовавшиеся блоки удаляются по принципу LRU.