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

Руководство по настройке и использованию файлового кэша (с разделением вычислений и хранения)

В режиме с разделением вычислений и хранения данные хранятся в удалённом объектном хранилище (например, S3 или HDFS). Doris использует локальные диски узлов BE как слой файлового кэша и эффективно управляет его пространством с помощью стратегии LRU (Least Recently Used — вытеснение давно не использовавшихся данных) с несколькими очередями. Пути доступа к индексам и метаданным специально оптимизированы, чтобы обеспечить максимальную долю попаданий в кэш для горячих данных.

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

Роль файлового кэша​

В режиме с разделением вычислений и хранения доступ к удалённому хранилищу обычно вызывает следующие две категории проблем:

ПроблемаОписание
Высокая задержка доступаЗадержка доступа к объектному хранилищу значительно выше, чем к локальному диску; особенно это заметно при большом числе одновременных обращений
Ограничения QPS и пропускной способностиОбъектное хранилище обычно имеет ограничения по QPS и пропускной способности, которые становятся узким местом при большом числе одновременных запросов
Оплата по факту использованияСтоимость объектного хранилища зависит от количества обращений и объёма переданных данных, поэтому частый доступ увеличивает эксплуатационные расходы

Кэшируя горячие данные на локальных дисках, Doris может значительно сократить задержку запросов и число прямых обращений к объектному хранилищу, тем самым снижая затраты.

Типы кэшируемых файлов​

Файловый кэш Doris в основном кэширует следующие два типа файлов:

  • Файлы данных Segment: базовая единица хранения данных внутренних таблиц Doris. Кэширование этих файлов ускоряет чтение данных и повышает производительность запросов.
  • Файлы инвертированных индексов: используются для ускорения фильтрации в запросах. Их кэширование позволяет быстрее находить данные, удовлетворяющие условиям, и поддерживает сложные сценарии запросов.

Настройка кэша​

Doris управляет работой файлового кэша с помощью следующих параметров в конфигурационном файле BE.

Включение файлового кэша​

ПараметрПо умолчаниюОписание
enable_file_cachetrueВключать ли файловый кэш. Начиная с версии 4.1.5 включён по умолчанию (ранее — false). В режиме с разделением вычислений и хранения BE всегда принудительно включает его.
предупреждение

По умолчанию file_cache_path указывает на каталог хранения в каталоге развёртывания BE. Если не задать total_size, кэш может расти, пока диск не будет заполнен на 85%–88%; задайте total_size, чтобы ограничить его размер.

Одноимённая переменная сеанса также должна быть включена. Допустимые значения и значения по умолчанию при обновлении см. в справочнике Переменные сеанса.

Настройка записи в кэш только индексов​

Если пространство локального кэша ограничено, а производительность запросов в большей степени зависит от индексов и метаданных Segment, можно включить политику записи только индексов. Эта политика ограничивает содержимое, которое загрузка данных, Schema Change, Compaction и другие пути записи активно записывают в File Cache. Она не влияет на заполнение кэша при промахе во время выполнения запроса или на прогрев кэша.

Doris предоставляет одну глобальную политику и две политики для Compaction:

ПараметрТипПо умолчаниюОбласть действияОписание
enable_file_cache_write_index_file_onlyBooleanfalseВсе операции записи rowset в режиме с разделением вычислений и хранения, включая загрузку данных, Schema Change, Cumulative Compaction и Base CompactionПоддерживается в Doris 4.0.8 и более поздних версиях серии 4.0, а также в Doris 4.1.4 и более поздних версиях серии 4.1. При значении true данные Segment активно не кэшируются. После закрытия Segment его футер и диапазоны внутренних индексов синхронно предзагружаются, а отдельные файлы инвертированных индексов по-прежнему записываются в File Cache. Этот параметр имеет приоритет над двумя параметрами для Compaction
enable_file_cache_write_base_compaction_index_onlyBooleanfalseBase CompactionЕсли существующая политика Base Compaction уже приняла решение записать результат в File Cache, запрещает активное кэширование файла Segment, сохраняя кэширование отдельных файлов инвертированных индексов. Этот параметр не приводит к кэшированию результатов Base Compaction, которые в противном случае записывались бы в обход кэша
enable_file_cache_write_cumu_compaction_index_onlyBooleanfalseCumulative CompactionКогда результат Cumulative Compaction записывается в File Cache, запрещает активное кэширование файла Segment, сохраняя кэширование отдельных файлов инвертированных индексов

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

  1. enable_file_cache=false имеет наивысший приоритет и отключает все операции записи в File Cache, включая предзагрузку футера и внутренних индексов Segment, а также запись отдельных инвертированных индексов.
  2. Если заданы enable_file_cache=true и enable_file_cache_write_index_file_only=true, включается глобальная политика записи только индексов. Два параметра для Compaction больше не меняют итоговое поведение. Адаптивная запись, политики сохранения результатов Compaction, пороги доли попаданий в кэш и настройки write_file_cache на уровне отдельных обращений не могут включить активное кэширование данных Segment; содержимое, связанное с индексами, по-прежнему записывается согласно описанной выше глобальной политике.
  3. Если глобальная политика записи только индексов отключена, параметры для Base/Cumulative Compaction лишь дополнительно ограничивают результаты соответствующего типа, уже выбранные для кэширования. Они не влияют на другие сценарии записи или на путь чтения запросов.
  4. Если все три параметра записи только индексов имеют значение false, существующее поведение активной записи в кэш, адаптивной записи и сохранения результатов Compaction остаётся прежним.
предупреждение

Два параметра для Compaction различают только отдельные файлы инвертированных индексов и файлы Segment. Они не запускают предзагрузку диапазонов футера и внутренних индексов Segment, которую использует глобальная политика записи только индексов. Чтобы активно сохранять как отдельные инвертированные индексы, так и внутренние индексы и метаданные Segment, используйте enable_file_cache_write_index_file_only.

Включение глобальной политики записи только индексов​

Задайте следующие настройки в be.conf на каждом узле BE:

enable_file_cache=true
enable_file_cache_write_index_file_only=true
enable_file_cache_write_base_compaction_index_only=false
enable_file_cache_write_cumu_compaction_index_only=false

Ожидаемое поведение:

СценарийСодержимое, активно записываемое в File Cache
Загрузка данных, Schema Change, Cumulative Compaction и Base CompactionДанные Segment активно не записываются; диапазоны футера и внутренних индексов Segment синхронно предзагружаются; отдельные файлы инвертированных индексов записываются
Чтение страниц данных запросомПоведение не меняется. После промаха кэша данные Segment по-прежнему могут заполнять кэш согласно существующим правилам пути чтения
Прогрев кэшаПоведение не меняется
Packed FileУпакованные небольшие файлы Segment не кэшируются целиком; упакованные отдельные небольшие файлы индексов по-прежнему могут кэшироваться целиком

При глобальной политике записи только индексов диапазоны футера и внутренних индексов Segment записываются в кэш через синхронное чтение и не управляются параметром enable_flush_file_cache_async. Для отдельных файлов инвертированных индексов по-прежнему используется существующий механизм прямой записи и асинхронного сброса.

Ограничение только результатов Compaction​

Чтобы уменьшить нагрузку на кэш от результатов Compaction, не меняя активную запись в кэш при загрузке данных и Schema Change, задайте:

enable_file_cache=true
enable_file_cache_write_index_file_only=false
enable_file_cache_write_base_compaction_index_only=true
enable_file_cache_write_cumu_compaction_index_only=true

Cumulative Compaction по умолчанию записывает результаты в кэш, поэтому включение соответствующего параметра исключает файлы Segment и сохраняет только отдельные файлы инвертированных индексов. Base Compaction по-прежнему сначала использует enable_file_cache_keep_base_compaction_output и долю попаданий в кэш для входных rowset, чтобы определить, нужно ли кэшировать результат. Параметр записи только индексов для Base Compaction ограничивает записываемое содержимое лишь после принятия этого решения.

Рекомендации​

  • Эти три параметра относятся к BE. Поддерживайте одинаковые значения на всех узлах BE одной вычислительной группы, чтобы узлы не использовали разные политики записи в кэш.
  • «Только индексы» не означает, что File Cache никогда не содержит данные Segment. Чтение страниц данных при промахе кэша во время запроса по-прежнему может заполнять кэш данными Segment.
  • Эта политика может уменьшить засорение кэша при загрузке данных и Compaction, но масштабное сканирование данных сразу после записи может увеличить число чтений из удалённого хранилища. Проверьте её на рабочей нагрузке запросов и отслеживайте вытеснение из очереди Index и метрики чтения индексов в SQL Profile.

Настройка путей и размера кэша​

file_cache_path  Default: the storage directory under the BE deployment path

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

ПолеОписание
pathПуть для хранения файлов кэша
total_sizeОбщий размер кэша для этого пути (в байтах)
ttl_percentПроцент пространства, выделяемый очереди TTL
normal_percentПроцент пространства, выделяемый очереди Normal
disposable_percentПроцент пространства, выделяемый очереди Disposable
index_percentПроцент пространства, выделяемый очереди Index
storageТип хранилища кэша: disk (по умолчанию) или memory

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

  • Настройка с одним путём:

    [{"path":"/path/to/file_cache","total_size":21474836480}]
  • Настройка с несколькими путями:

    [{"path":"/path/to/file_cache","total_size":21474836480},{"path":"/path/to/file_cache2","total_size":21474836480}]
  • Настройка хранения в памяти:

    [{"path": "xxx", "total_size":53687091200, "storage": "memory"}]

Автоматическая очистка кэша​

ПараметрПо умолчаниюОписание
clear_file_cachefalseОчищать ли кэшированные данные автоматически при перезапуске BE. При значении true кэш очищается при каждом перезапуске.

Упреждающее вытеснение​

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

ПараметрПо умолчаниюОписание
enable_evict_file_cache_in_advancetrueВключать ли упреждающее вытеснение
file_cache_enter_need_evict_cache_in_advance_percent88Порог заполненности (%), при котором запускается упреждающее вытеснение. Оно начинается, когда занятое пространство кэша или количество используемых inode достигает этого процента
file_cache_exit_need_evict_cache_in_advance_percent85Порог заполненности (%), при котором упреждающее вытеснение прекращается. Вытеснение останавливается, когда занятое пространство кэша снижается до этого процента

Квота кэша​

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

МеханизмОсновной параметрПоведение после достижения ограниченияСценарий использования
Ограничение доли занятого кэшаfile_cache_query_limit_percentНовые блоки по-прежнему могут записываться в кэш. BE сначала вытесняет блоки, учтённые для текущего запроса и доступные для освобождения, а затем при необходимости вытесняет блоки из других очередей кэшаОграничение объёма кэша, занятого запросом, с сохранением возможности дальнейшего заполнения кэша
Остановка записи в кэш при удалённом сканировании по порогу в байтахfile_cache_query_limit_bytesЕсли следующий блок кэша приведёт к превышению порога учтённых байтов, запрос на этом BE переходит в режим чтения только из удалённого хранилища при промахе кэша. Последующие промахи обслуживаются из удалённого хранилища без дальнейшей записи в File CacheОграничение записи в кэш и частой смены его содержимого при масштабном удалённом сканировании
Остановка записи в кэш на фазе 2 отложенной материализации TopNenable_topn_lazy_mat_phase2_no_write_file_cacheЧтения для поиска данных на фазе 2 отложенной материализации TopN при промахе кэша обращаются только к удалённому хранилищу и не заполняют File CacheПредотвращение засорения кэша чтениями TopN с низкой вероятностью повторного использования

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

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

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

Эта функция включает три уровня настройки: конфигурацию BE, конфигурацию FE и переменные сеанса.

Конфигурация BE

ПараметрТипПо умолчаниюОписание
enable_file_cache_query_limitBooleanfalseГлавный переключатель ограничения кэша для запросов на стороне BE. BE обрабатывает переданный от FE параметр ограничения запроса, только если этот переключатель включён

Конфигурация FE

ПараметрТипПо умолчаниюОписание
file_cache_query_limit_max_percentInteger100Максимальное значение ограничения квоты запроса, используемое для проверки верхней границы переменной сеанса

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

ПеременнаяТипПо умолчаниюОписание
file_cache_query_limit_percentInteger-1При явном задании значение должно находиться в диапазоне [1, file_cache_query_limit_max_percent]. Оно задаёт максимальный процент кэша, который может использовать один запрос. Рассчитанная квота должна быть не меньше 256 MB; иначе BE записывает предупреждение в журнал

Перед использованием этого механизма включите на BE оба параметра: enable_file_cache и enable_file_cache_query_limit, а также убедитесь, что в сеансе запроса enable_file_cache имеет значение true.

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

-- Limit a single query to using at most 50% of the cache
SET file_cache_query_limit_percent = 50;

-- Execute the query
SELECT * FROM large_table;

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

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

file_cache_query_limit_bytes ограничивает совокупный объём байтов, допущенных к записи в File Cache при сквозном чтении из-за промахов кэша при удалённом сканировании для одного запроса SELECT на каждом BE. Он действует только в режиме с разделением вычислений и хранения, когда на BE задано enable_file_cache=true. Он не зависит от enable_file_cache_query_limit или file_cache_query_limit_max_percent.

Параллельные сканеры одного запроса используют общий порог на одном BE, но этот порог не является общим для всего запроса или кластера. Например, если запрос выполняется на 10 узлах BE с порогом 1 GiB, каждый BE может независимо допустить примерно 1 GiB; ограничение не составляет 1 GiB суммарно для всех BE.

Параметры

ПараметрГде задаётсяТипПо умолчаниюОбязательныйОписание
file_cache_query_limit_bytesПеременная сеансаBigInt-1ДаПорог заполнения кэша при удалённом сканировании для одного запроса на каждом BE, в байтах. Значение меньше 0 отключает ограничение; 0 отключает заполнение кэша с начала запроса; при положительном значении допущенные байты суммируются по блокам кэша
enable_file_cache_query_limit_segment_metaКонфигурация BEBooleanfalseНетУчитывать ли запись футера и метаданных Segment в кэш в том же пороге байтов. Этот параметр можно изменять динамически. Запись страниц данных и инвертированных индексов подчиняется порогу байтов всегда, когда этот механизм активен

file_cache_query_limit_bytes работает следующим образом:

ЗначениеПоведение
< 0Отключает этот механизм и сохраняет исходное поведение заполнения кэша при промахе
= 0С начала запроса переводит его на каждом BE в режим чтения только из удалённого хранилища при промахе кэша. Диапазон обращения, полностью покрытый локальным кэшем, по-прежнему может читаться локально; диапазон, покрытый не полностью, читается напрямую из удалённого хранилища без заполнения кэша
> 0Допускает блоки кэша, пока их суммарный учтённый объём в байтах не превышает порог. Если следующий блок приведёт к превышению порога, он отклоняется, а последующие промахи этого запроса на данном BE больше не заполняют кэш

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

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

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

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

SELECT COUNT(*) FROM large_table;

Результат запроса не меняется. Если следующий блок кэша на BE приведёт к превышению 1 GiB допущенных байтов, последующие промахи кэша этого запроса на том же BE будут читать удалённые данные без дополнительной записи в локальный кэш.

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

SET file_cache_query_limit_bytes = 0;
SELECT COUNT(*) FROM large_table;

SET file_cache_query_limit_bytes = -1;

Учёт метаданных Segment

По умолчанию запись страниц данных и инвертированных индексов в кэш учитывается в пороге, а запись футера и метаданных Segment — нет. Поэтому футер и метаданные Segment могут записываться и после перехода запроса в режим чтения только из удалённого хранилища при промахе, а общий объём записи, отображаемый в Profile, может превышать file_cache_query_limit_bytes.

Чтобы также остановить заполнение кэша футерами и метаданными Segment, задайте следующую настройку на каждом BE одной вычислительной группы:

enable_file_cache_query_limit_segment_meta=true

Этот параметр можно изменить немедленно через API динамической конфигурации BE. Чтобы сохранить его после перезапусков, добавьте его в be.conf или используйте сохраняемую динамическую конфигурацию. Подробнее см. Конфигурация BE.

Проверка с помощью Query Profile

После включения Query Profile проверьте группу метрик FileCache в узле Scanner:

МетрикаОписание
RemoteOnlyOnMissTriggeredЗначение 1 означает, что Scanner обнаружил переход запроса в режим чтения только из удалённого хранилища при промахе кэша
RemoteOnlyOnMissThresholdBytesПорог в байтах, заданный для запроса
BytesWriteIntoCacheОбщий объём байтов, фактически записанных в File Cache
InvertedIndexBytesWriteIntoCacheОбъём байтов инвертированных индексов, фактически записанных в File Cache
SegmentFooterIndexBytesWriteIntoCacheОбъём байтов футера и метаданных Segment, фактически записанных в File Cache
NumSkipCacheIOTotalКоличество операций ввода-вывода, выполненных в обход кэша. Эта метрика также может учитывать операции, пропущенные из-за других политик кэширования, поэтому оценивайте её вместе с RemoteOnlyOnMissTriggered

Если объём допущенных байтов точно равен порогу и до завершения запроса ни один последующий блок кэша не пытается его превысить, RemoteOnlyOnMissTriggered может остаться равным 0. Состояние меняется только тогда, когда последующий блок привёл бы к превышению порога.

Рекомендации и особенности

  • Для разовых полных сканирований, ETL с низкой вероятностью повторного использования данных или нерегулярных запросов используйте небольшой положительный порог либо 0, чтобы отключить заполнение кэша с самого начала и не заменять горячие данные холодными.
  • Этот параметр ограничивает заполнение File Cache после промахов при чтении запросом. Он не ограничивает объём чтения из удалённого хранилища, не прерывает запрос и не влияет на запись в кэш при загрузке данных, Compaction, Schema Change или явном прогреве кэша.
  • В режиме чтения только из удалённого хранилища при промахе диапазоны обращений, полностью покрытые локальным кэшем, по-прежнему могут читаться локально. Не полностью покрытые диапазоны обращаются напрямую к удалённому хранилищу, что может увеличить объём ввода-вывода объектного хранилища и задержку запросов.
  • Используйте file_cache_query_limit_percent, если нужно ограничить объём кэша, удерживаемый запросом, сохранив возможность заполнения кэша при последующих промахах. Используйте file_cache_query_limit_bytes, если нужно остановить дальнейшее заполнение после допуска заданного объёма данных.
  • Исключение футера и метаданных Segment из подсчёта по умолчанию сохраняет преимущества кэширования часто повторно используемых метаданных. Включайте enable_file_cache_query_limit_segment_meta, только если эти записи также должны прекратиться после достижения порога, и проверяйте результат с помощью Query Profile.

Остановка записи в кэш на фазе 2 отложенной материализации TopN​

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

Запросы с ORDER BY ... LIMIT используют отложенную материализацию TopN: фаза 1 читает только столбцы сортировки для выбора строк-кандидатов, а фаза 2 находит остальные столбцы по идентификатору строки. Чтения фазы 2 разрежены, а прочитанные данные редко используются повторно, поэтому заполнение ими File Cache легко вытесняет горячие данные в режиме с разделением вычислений и хранения.

ПеременнаяТипПо умолчаниюОписание
enable_topn_lazy_mat_phase2_no_write_file_cacheBooleanfalseПри включении чтения фазы 2 отложенной материализации TopN при промахе File Cache обращаются напрямую к удалённому хранилищу и не записывают этот диапазон в File Cache

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

SET enable_topn_lazy_mat_phase2_no_write_file_cache = true;

SELECT * FROM large_table ORDER BY create_time DESC LIMIT 100;

Примечания

  • Переменная действует только в режиме с разделением вычислений и хранения; её установка в режиме совмещённых вычислений и хранения не оказывает влияния.
  • Она влияет только на чтения для поиска данных на фазе 2 отложенной материализации TopN. Чтения столбцов сортировки на фазе 1, заполнение кэша другими запросами и запись в кэш при загрузке данных, Compaction и прогреве кэша не затрагиваются.
  • Диапазоны, которые фаза 2 находит в File Cache, по-прежнему читаются локально. Отсутствующие диапазоны читаются напрямую из удалённого хранилища, что может увеличить объём ввода-вывода объектного хранилища.
  • Если запросы TopN многократно обращаются к одним и тем же горячим строкам, отключение заполнения кэша может увеличить число удалённых чтений. Оцените эффект с учётом характера ваших запросов.

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

Doris предоставляет функцию прогрева кэша, которая позволяет заранее загружать данные из удалённого хранилища в локальный кэш. Поддерживаются следующие три режима прогрева:

РежимОписание
Прогрев между вычислительными группамиПрогревает кэш горячих данных вычислительной группы A в вычислительной группе B. Doris периодически собирает сведения об активно используемых таблицах и разделах для каждой вычислительной группы и на их основе выполняет выборочный прогрев
Прогрев данных таблицыЗагружает все данные указанной таблицы в целевую вычислительную группу
Прогрев данных разделаЗагружает данные определённого раздела указанной таблицы в целевую вычислительную группу

Подробные инструкции см. в документации по SQL-команде WARM-UP.

Прогрев кэша заранее загружает данные из удалённого хранилища. Чтение из кэша других узлов дополняет его во время выполнения запросов: при промахе локального кэша блок сначала читается из другого BE и только при его отсутствии на всех BE — из удалённого хранилища. Это позволяет обслуживать холодные чтения, не охваченные прогревом.

Очистка кэша​

Doris предоставляет синхронный и асинхронный способы очистки кэша:

СпособКомандаОписание
Синхронная очисткаcurl 'http://BE_IP:WEB_PORT/api/file_cache?op=clear&sync=true'Команда возвращает управление только после завершения очистки. Doris синхронно удаляет файлы кэша из локальной файловой системы и очищает метаданные в памяти. Это быстро освобождает пространство, но может повлиять на выполняющиеся запросы. Обычно используется для быстрого тестирования
Асинхронная очисткаcurl 'http://BE_IP:WEB_PORT/api/file_cache?op=clear&sync=false'Команда возвращает управление немедленно; этапы очистки выполняются асинхронно, и можно наблюдать постепенное уменьшение занятого кэшем пространства. Doris обходит метаданные в памяти и удаляет файлы кэша по одному, откладывая удаление файлов, которые сейчас используются. Это меньше влияет на выполняющиеся запросы, но требует больше времени для полной очистки

Мониторинг кэша​

Сведения о блоках кэша​

Начиная с Doris 4.1 можно запрашивать information_schema.file_cache_info, чтобы просматривать записи кэша на уровне блоков и суммировать занятое пространство по tablet, BE, пути кэша или типу кэша. Doris 4.0.x не поддерживает эту системную таблицу.

Сведения о горячих данных​

Doris собирает сведения о горячих данных кэша для каждой вычислительной группы каждые 10 минут и записывает их во внутреннюю системную таблицу __internal_schema.cloud_cache_hotspot. С помощью следующих запросов можно анализировать горячие данные для планирования кэша.

Примечание

До версии 3.0.4 для получения сведений о горячих данных кэша можно было использовать оператор SHOW CACHE HOTSPOT. Начиная с версии 3.0.4 этот оператор больше не поддерживается. Вместо него запрашивайте системную таблицу __internal_schema.cloud_cache_hotspot напрямую.

Просмотр наиболее часто используемых таблиц во всех вычислительных группах​

-- Equivalent to SHOW CACHE HOTSPOT "/" before version 3.0.4
WITH t1 AS (
SELECT
cluster_id,
cluster_name,
table_id,
table_name,
insert_day,
SUM(query_per_day) AS query_per_day_total,
SUM(query_per_week) AS query_per_week_total
FROM __internal_schema.cloud_cache_hotspot
GROUP BY cluster_id, cluster_name, table_id, table_name, insert_day
)
SELECT
cluster_id AS ComputeGroupId,
cluster_name AS ComputeGroupName,
table_id AS TableId,
table_name AS TableName
FROM (
SELECT
ROW_NUMBER() OVER (
PARTITION BY cluster_id
ORDER BY insert_day DESC, query_per_day_total DESC, query_per_week_total DESC
) AS dr2,
*
FROM t1
) t2
WHERE dr2 = 1;

Просмотр наиболее часто используемых таблиц в определённой вычислительной группе​

Замените cluster_name = "compute_group_name0" фактическим именем вычислительной группы.

-- Equivalent to SHOW CACHE HOTSPOT '/compute_group_name0' before version 3.0.4
WITH t1 AS (
SELECT
cluster_id,
cluster_name,
table_id,
table_name,
insert_day,
SUM(query_per_day) AS query_per_day_total,
SUM(query_per_week) AS query_per_week_total
FROM __internal_schema.cloud_cache_hotspot
WHERE cluster_name = "compute_group_name0" -- Replace with the actual compute group name, e.g. "default_compute_group"
GROUP BY cluster_id, cluster_name, table_id, table_name, insert_day
)
SELECT
cluster_id AS ComputeGroupId,
cluster_name AS ComputeGroupName,
table_id AS TableId,
table_name AS TableName
FROM (
SELECT
ROW_NUMBER() OVER (
PARTITION BY cluster_id
ORDER BY insert_day DESC, query_per_day_total DESC, query_per_week_total DESC
) AS dr2,
*
FROM t1
) t2
WHERE dr2 = 1;

Метрики объёма кэша и доли попаданий​

Используйте следующую конечную точку для получения статистики кэша узла BE (brpc_port по умолчанию равен 8060):

curl {be_ip}:{brpc_port}/vars

Имена возвращаемых метрик содержат префикс с путём на диске. Например, префикс _mnt_disk1_gavinchou_debug_doris_cloud_be0_storage_file_cache_ соответствует пути /mnt/disk1/gavinchou/debug/doris-cloud/be0_storage_file_cache/. После удаления префикса пути метрики имеют следующий смысл (все размеры указаны в байтах):

Имя метрики (без префикса пути)Описание
file_cache_cache_sizeТекущий общий размер файлового кэша
file_cache_disposable_queue_cache_sizeТекущий размер очереди Disposable
file_cache_disposable_queue_element_countТекущее количество элементов в очереди Disposable
file_cache_disposable_queue_evict_sizeСовокупный объём данных, вытесненных из очереди Disposable с момента запуска
file_cache_index_queue_cache_sizeТекущий размер очереди Index
file_cache_index_queue_element_countТекущее количество элементов в очереди Index
file_cache_index_queue_evict_sizeСовокупный объём данных, вытесненных из очереди Index с момента запуска
file_cache_normal_queue_cache_sizeТекущий размер очереди Normal
file_cache_normal_queue_element_countТекущее количество элементов в очереди Normal
file_cache_normal_queue_evict_sizeСовокупный объём данных, вытесненных из очереди Normal с момента запуска
file_cache_total_evict_sizeСовокупный объём данных, вытесненных из всего файлового кэша с момента запуска
file_cache_ttl_cache_evict_sizeСовокупный объём данных, вытесненных из очереди TTL с момента запуска
file_cache_ttl_cache_lru_queue_element_countТекущее количество элементов в очереди TTL
file_cache_ttl_cache_sizeТекущий размер очереди TTL
file_cache_evict_by_heat_[A]_to_[B]Объём данных кэша типа A, вытесненных для освобождения места под данные кэша типа B (вытеснение по времени истечения срока действия)
file_cache_evict_by_size_[A]_to_[B]Объём данных кэша типа A, вытесненных для освобождения места под данные кэша типа B (вытеснение по занятому пространству)
file_cache_evict_by_self_lru_[A]Объём данных кэша типа A, которые очередь типа A вытеснила из себя для записи новых данных (вытеснение по LRU)
file_cache_evict_not_downloaded_sizeДобавлена в 4.1.5. Совокупный логический размер в байтах диапазонов блоков, удалённых до завершения загрузки, за исключением блоков, загружаемых в данный момент; не отражает физическое вытеснение загруженных данных
file_cache_evict_not_downloaded_numДобавлена в 4.1.5. Совокупное количество таких удалённых блоков
file_cache_ttl_mgr_ttl_info_map_sizeДобавлена в 4.1.5. Текущее количество отслеживаемых записей сведений о TTL для tablet, а не блоков

Начиная с версии 4.1.5 общие и отдельные для каждой очереди счётчики вытесненных байтов учитывают только полностью загруженные блоки. Блоки, удалённые до завершения загрузки, учитываются отдельно новыми счётчиками; блоки, помеченные для удаления во время загрузки, не увеличивают эти счётчики удаления. Соответствующие имена метрик в системной таблице SQL — evict_not_downloaded_size и evict_not_downloaded_num. См. file_cache_statistics.

Метрики кэша в SQL Profile​

Метрики кэша в SQL Profile находятся в узле SegmentIterator:

Имя метрикиОписание
BytesScannedFromCacheОбъём данных, прочитанных из файлового кэша
BytesScannedFromRemoteОбъём данных, прочитанных из удалённого хранилища
BytesWriteIntoCacheОбъём данных, записанных в файловый кэш
LocalIOUseTimerВремя, затраченное на чтение из файлового кэша
NumLocalIOTotalКоличество чтений из файлового кэша
NumRemoteIOTotalКоличество чтений из удалённого хранилища
NumSkipCacheIOTotalКоличество чтений из удалённого хранилища, результаты которых не были записаны в файловый кэш
RemoteIOUseTimerВремя, затраченное на чтение из удалённого хранилища
WriteCacheIOUseTimerВремя, затраченное на запись в файловый кэш

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

МетрикаОписание
InvertedIndexBytesScannedFromCache / InvertedIndexBytesScannedFromRemoteОбъём данных отдельных инвертированных индексов, прочитанных из File Cache / удалённого хранилища
InvertedIndexNumLocalIOTotal / InvertedIndexNumRemoteIOTotalКоличество локальных / удалённых чтений отдельных инвертированных индексов
InvertedIndexLocalIOUseTimer / InvertedIndexRemoteIOUseTimerВремя, затраченное на локальные / удалённые чтения отдельных инвертированных индексов
SegmentFooterIndexBytesScannedFromCache / SegmentFooterIndexBytesScannedFromRemoteОбъём данных футеров и внутренних индексов Segment, прочитанных из File Cache / удалённого хранилища
SegmentFooterIndexNumLocalIOTotal / SegmentFooterIndexNumRemoteIOTotalКоличество локальных / удалённых чтений данных футеров и внутренних индексов Segment
SegmentFooterIndexLocalIOUseTimer / SegmentFooterIndexRemoteIOUseTimerВремя, затраченное на локальные / удалённые чтения данных футеров и внутренних индексов Segment

Полный отчёт о производительности запроса можно просмотреть с помощью анализа производительности запросов.

NumPeerIOTotal, PeerIOUseTimer, SameCGPeerIOTotal, CrossCGPeerIOTotal и связанные счётчики показывают, поступили ли данные из кэша другого BE (чтение из кэша других узлов). См. Чтение из кэша других узлов: счётчики Query Profile.

Политика кэширования TTL​

Политика кэширования TTL (Time-To-Live — время жизни) позволяет задать срок хранения в кэше данных определённых таблиц. Это обеспечивает достаточно долгое пребывание небольших горячих таблиц или недавно загруженных данных в кэше, защищая их от вытеснения по LRU, вызванного большими запросами.

Установка TTL при создании таблицы​

Задайте file_cache_ttl_seconds (в секундах) в предложении PROPERTIES оператора CREATE TABLE:

CREATE TABLE IF NOT EXISTS customer (
C_CUSTKEY INTEGER NOT NULL,
C_NAME VARCHAR(25) NOT NULL,
C_ADDRESS VARCHAR(40) NOT NULL,
C_NATIONKEY INTEGER NOT NULL,
C_PHONE CHAR(15) NOT NULL,
C_ACCTBAL DECIMAL(15,2) NOT NULL,
C_MKTSEGMENT CHAR(10) NOT NULL,
C_COMMENT VARCHAR(117) NOT NULL
)
DUPLICATE KEY(C_CUSTKEY, C_NAME)
DISTRIBUTED BY HASH(C_CUSTKEY) BUCKETS 32
PROPERTIES (
"file_cache_ttl_seconds" = "300"
);

Начиная с версии 4.1.5 все пути записи и чтения вычисляют абсолютный срок окончания защиты как tablet creation time + file_cache_ttl_seconds. В приведённом примере каждый tablet защищён до истечения 300 секунд после его создания. Последующие загрузка данных, чтения, Compaction, Schema Change и прогрев не перезапускают таймер. После истечения срока данные кэшируются обычным образом; каждая новая загрузка данных не гарантирует ещё 300 секунд защиты.

Допустимый диапазон для file_cache_ttl_seconds — 0 <= value <= 4611686018427387903 (то есть Long.MAX_VALUE / 2). Начиная с версии 4.1.4 и CREATE TABLE, и ALTER TABLE ... SET проверяют это значение; значение вне диапазона или в неверном формате отклоняется с ошибкой:

The value <v> formats error or is out of range (0 <= integer <= 4611686018427387903). Larger values may overflow in BE and change TTL cache to normal cache; please use 4611686018427387903 or a smaller value.

До 4.1.4 верхняя граница не проверялась, и слишком большое значение приводило к переполнению на стороне BE, переводя кэш TTL в обычный кэш.

Изменение настройки TTL для таблицы​

ALTER TABLE customer SET ("file_cache_ttl_seconds" = "3000");
Примечание

Изменения TTL вступают в силу после задержки синхронизации метаданных. Если TTL не был задан при создании таблицы, его можно добавить с помощью ALTER TABLE. Новый срок окончания защиты по-прежнему отсчитывается от времени создания tablet. Начиная с версии 4.1.5 продление истёкшего TTL до будущего срока также возвращает обычные кэшированные блоки в очередь TTL. Установка TTL в 0 возвращает их к обычному кэшированию.

Практический пример​

Описание сценария:

У пользователя есть набор таблиц с общим объёмом данных более 3 TB, но доступная ёмкость кэша составляет всего 1.2 TB. Из этих таблиц две используются часто:

ТаблицаРазмерХарактер обращений
dimension_table200 MBЧастые обращения; данные меняются редко
fact_table100 GBНовые данные загружаются ежедневно и должны быть доступны для запросов по схеме T+1

К другим большим таблицам обращаются редко.

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

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

-- Dimension table: protect each tablet until 1 year after creation; use a longer TTL if it is already older than 1 year
ALTER TABLE dimension_table SET ("file_cache_ttl_seconds" = "31536000");

-- Fact table with new daily partitions: protect each new partition's tablets until 1 day after creation
ALTER TABLE fact_table SET ("file_cache_ttl_seconds" = "86400");

Часто задаваемые вопросы​

Вопрос: доля попаданий в кэш низкая, а запросы по-прежнему выполняются медленно. Как найти причину?

  1. Используйте curl {be_ip}:{brpc_port}/vars, чтобы проверить метрики evict_size для каждой очереди и определить, происходит ли частое вытеснение.
  2. Проверьте соотношение BytesScannedFromRemote и BytesScannedFromCache в SQL Profile, чтобы установить фактическую долю попаданий.
  3. Если большие запросы часто вытесняют горячие данные, рассмотрите включение функции ограничения кэша для запросов (enable_file_cache_query_limit) или настройку политики TTL для горячих таблиц.

Вопрос: данные кэша теряются после перезапуска BE.

Проверьте, не задано ли для clear_file_cache значение true. Если вы не хотите очищать кэш при перезапуске, установите false (значение по умолчанию).

Вопрос: первый запрос после запуска новой вычислительной группы выполняется очень медленно.

Используйте прогрев кэша, чтобы заранее загрузить горячие данные таблиц или разделов из удалённого хранилища в локальный кэш новой вычислительной группы до поступления запросов. Подробные инструкции см. в документации по SQL-команде WARM-UP. Если другая вычислительная группа уже содержит данные в своём кэше, включённое чтение из кэша других узлов позволяет новой вычислительной группе при промахе читать их из BE той группы.

Вопрос: как определить, заполнен ли текущий кэш?

Сравните метрику file_cache_cache_size со значением total_size, заданным в file_cache_path. Если она приближается к ограничению, проверьте, нужно ли увеличить ёмкость или изменить доли пространства, выделяемые каждой очереди.