Spill to disk#
Overview#
В случае операций, интенсивно использующих память, Trino позволяет выгружать промежуточные результаты операций на диск. Цель этого механизма — обеспечить выполнение запросов, требующих объёма памяти, превышающего лимиты на запрос или на узел.
Механизм похож на paging (swap) на уровне операционной системы. Однако он реализован на уровне приложения, чтобы учитывать специфические потребности Trino.
Свойства, связанные со spilling, описаны в Spilling properties.
Warning
Функциональность spill to disk и её реализация являются устаревшими
в Trino. Рекомендуется использовать Fault-tolerant execution
с политикой retry task и настроенным Exchange manager.
Memory management and spill#
По умолчанию Trino завершает запросы, если объём памяти, требуемый
для выполнения запроса, превышает свойства сессии query_max_memory
или query_max_memory_per_node. Этот механизм обеспечивает справедливое
распределение памяти между запросами и предотвращает deadlock,
связанный с её выделением. Он эффективен при большом количестве
небольших запросов в кластере, но приводит к завершению крупных
запросов, выходящих за пределы лимитов.
Чтобы устранить эту неэффективность, была введена концепция revocable memory. Запрос может использовать память, не учитываемую в лимитах, но эта память может быть отозвана memory manager в любой момент. Когда память отзывается, query runner выгружает промежуточные данные из памяти на диск и продолжает обработку позже.
На практике, когда кластер простаивает и вся память доступна, ресурсоёмкий запрос может использовать всю память кластера. В то же время, если в кластере мало свободной памяти, тот же запрос может быть вынужден использовать диск для хранения промежуточных данных. Запрос, использующий spill на диск, может выполняться на порядки дольше, чем запрос, полностью работающий в памяти.
Обратите внимание, что включение spill-to-disk не гарантирует выполнение
всех ресурсоёмких запросов. Возможно, что query runner не сможет разбить
промежуточные данные на достаточно мелкие части, чтобы каждая из них
помещалась в память, что приведёт к ошибке Out of memory при загрузке
данных с диска.
Spill disk space#
Выгрузка промежуточных результатов на диск и их последующее чтение —
дорогая операция с точки зрения I/O. Поэтому запросы, использующие spill,
часто ограничиваются производительностью диска. Для повышения
производительности рекомендуется использовать несколько путей
на разных локальных устройствах для spill (свойство
spiller-spill-path в Spilling properties).
Системный диск не следует использовать для spill, особенно если на нём работает JVM и записываются логи. Это может привести к нестабильности кластера. Также рекомендуется отслеживать загрузку дисков для путей, используемых под spill.
Trino рассматривает пути для spill как независимые диски (см. JBOD), поэтому использование RAID для spill не требуется.
Spill compression#
Если включено сжатие spill с помощью свойства
spill-compression-codec, страницы
данных сжимаются перед записью на диск. Это может снизить нагрузку
на диск за счёт увеличения нагрузки на CPU для сжатия и распаковки данных.
Spill encryption#
Если включено шифрование spill (spill-encryption-enabled в
Spilling properties), содержимое spill шифруется с использованием
случайно сгенерированного (для каждого файла) секретного ключа.
Это увеличивает нагрузку на CPU и снижает пропускную способность
операций spill, но защищает данные от восстановления из файлов spill.
Рекомендуется уменьшить значение memory-revoking-threshold
при включённом шифровании, чтобы компенсировать увеличение задержек.
Supported operations#
Не все операции поддерживают spilling на диск, и каждая из них реализует его по-своему. В настоящее время механизм реализован для следующих операций.
Joins#
Во время выполнения операции join одна из объединяемых таблиц хранится в памяти. Эта таблица называется build table. Строки из другой таблицы проходят потоком и передаются на следующий этап обработки, если они соответствуют строкам в build table. Наиболее ресурсоёмкой по памяти частью join является именно build table.
Когда значение task concurrency больше единицы, build table разбивается на
партиции. Количество партиций равно значению параметра конфигурации
task.concurrency (см. Task properties).
Когда build table разбита на партиции, механизм spill-to-disk позволяет уменьшить пиковое потребление памяти, необходимое для выполнения join. Когда запрос приближается к лимиту памяти, часть партиций build table сбрасывается на диск, вместе со строками из другой таблицы, которые попадают в те же партиции. Количество партиций, которые сбрасываются на диск, влияет на объём требуемого дискового пространства.
После этого сброшенные партиции считываются обратно по одной для завершения операции join.
С помощью этого механизма пиковое потребление памяти оператором join может быть
уменьшено до размера самой большой партиции build table. При отсутствии перекоса
данных (data skew) это составляет 1 / task.concurrency от размера всей build table.
Aggregations#
Функции агрегации выполняют операцию над группой значений и возвращают одно значение. Если количество групп, по которым выполняется агрегация, велико, может потребоваться значительный объём памяти. Когда включён spill-to-disk, при нехватке памяти промежуточные накопленные результаты агрегации записываются на диск. Затем они считываются обратно и объединяются с меньшим потреблением памяти.
Order by#
Если вы пытаетесь отсортировать большой объём данных, может потребоваться
значительный объём памяти. Когда включён spill-to-disk для order by,
при нехватке памяти промежуточные отсортированные результаты записываются
на диск. Затем они считываются обратно и объединяются с меньшим
потреблением памяти.
Window functions#
Оконные функции выполняют операцию над окном строк и возвращают одно значение для каждой строки. Если окно строк большое, может потребоваться значительный объём памяти. Когда включён spill-to-disk для оконных функций, при нехватке памяти промежуточные результаты записываются на диск. Затем они считываются обратно и объединяются при наличии доступной памяти. В настоящее время есть ограничение: spill работает не во всех случаях, например, когда одно окно очень большое.