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

Управление данными с помощью TTL (Время жизни)

Обзор TTL

TTL (время жизни) относится к возможности перемещения, удаления или агрегации строк или столбцов после того, как пройдет определенный интервал времени. Хотя выражение "время жизни" звучит так, будто оно относится только к удалению старых данных, TTL имеет несколько вариантов использования:

  • Удаление старых данных: совсем не удивительно, что вы можете удалять строки или столбцы после указанного временного интервала
  • Перемещение данных между дисками: после определенного времени вы можете переместить данные между объемами хранения - полезно для реализации архитектуры "горячее/теплое/холодное"
  • Агрегация данных: агрегируйте ваши старые данные в различные полезные агрегации и вычисления перед их удалением
примечание

TTL может применяться как ко всем таблицам, так и к конкретным столбцам.

Синтаксис TTL

Клаузула TTL может появляться после определения столбца и/или в конце определения таблицы. Используйте клаузулу INTERVAL, чтобы определить длину времени (которая должна быть типа данных Date или DateTime). Например, следующая таблица имеет два столбца с клаузами TTL:

  • Столбец x имеет время жизни 1 месяц от столбца timestamp
  • Столбец y имеет время жизни 1 день от столбца timestamp
  • Когда интервал истекает, столбец теряет свою актуальность. ClickHouse заменяет значение в столбце на значение по умолчанию его типа данных. Если все значения столбца в части данных истекают, ClickHouse удаляет этот столбец из части данных файловой системы.
примечание

Правила TTL могут быть изменены или удалены. См. страницу Манипуляции с таблицами TTL для получения более подробной информации.

Запуск событий TTL

Удаление или агрегация просроченных строк не происходит немедленно - это происходит только во время слияния таблиц. Если у вас есть таблица, которая не объединяется активно (по какой-либо причине), есть две настройки, которые запускают событий TTL:

  • merge_with_ttl_timeout: минимальная задержка в секундах перед повторным слиянием с удалением TTL. Значение по умолчанию составляет 14400 секунд (4 часа).
  • merge_with_recompression_ttl_timeout: минимальная задержка в секундах перед повторным слиянием с рекомпрессией TTL (правила, которые агрегируют данные перед удалением). Значение по умолчанию: 14400 секунд (4 часа).

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

примечание

Это не лучшее решение (или то, которое мы рекомендуем использовать часто), но вы также можете принудительно выполнить слияние с помощью OPTIMIZE:

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

Удаление строк

Чтобы удалять целые строки из таблицы после истечения определенного времени, определите правило TTL на уровне таблицы:

Кроме того, возможно определить правило TTL на основе значения записи. Это легко реализовать, указав условие where. Разрешены несколько условий:

Удаление столбцов

Вместо удаления всей строки, предположим, что вы хотите, чтобы только столбцы balance и address утратили актуальность. Давайте изменим таблицу customers и добавим TTL для обоих столбцов на 2 часа:

Реализация агрегации

Предположим, мы хотим удалить строки после определенного времени, но сохранить некоторые данные для отчетных целей. Нам не нужны все детали - только несколько агрегированных результатов исторических данных. Это можно реализовать, добавив клаузулу GROUP BY в ваше выражение TTL, вместе с некоторыми столбцами в вашей таблице для хранения агрегированных результатов.

Предположим, в следующей таблице hits мы хотим удалить старые строки, но сохранить сумму и максимум колонок hits перед удалением строк. Нам нужно поле для хранения этих значений, и нам нужно добавить клаузулу GROUP BY к клаузе TTL, которая агрегирует сумму и максимум:

Некоторые примечания о таблице hits:

  • Столбцы GROUP BY в клаузе TTL должны быть префиксом PRIMARY KEY, и мы хотим сгруппировать наши результаты по началу дня. Поэтому toStartOfDay(timestamp) была добавлена в первичный ключ
  • Мы добавили два поля для хранения агрегированных результатов: max_hits и sum_hits
  • Установка значения по умолчанию для max_hits и sum_hits на hits необходима для работы нашей логики, исходя из того, как определена клаузула SET

Реализация архитектуры "горячее/теплое/холодное"

Not supported in ClickHouse Cloud
примечание

Если вы используете ClickHouse Cloud, шаги в этом уроке неподходящие. Вам не нужно беспокоиться о перемещении старых данных в ClickHouse Cloud.

Распространенной практикой при работе с большими объемами данных является перемещение этих данных по мере их старения. Вот шаги для реализации архитектуры "горячее/теплое/холодное" в ClickHouse с использованием клаузул TO DISK и TO VOLUME команды TTL. (Кстати, это не обязательно должна быть горячая и холодная архитектура - вы можете использовать TTL для перемещения данных в зависимости от вашей задачи.)

  1. Опции TO DISK и TO VOLUME относятся к именам дисков или объемов, определенных в ваших файлах конфигурации ClickHouse. Создайте новый файл с именем my_system.xml (или любым другим именем), который определяет ваши диски, а затем определите объемы, которые используют ваши диски. Поместите XML файл в /etc/clickhouse-server/config.d/, чтобы применить конфигурацию к вашей системе:
  1. Приведенная выше конфигурация ссылается на три диска, которые указывают на папки, из которых ClickHouse может читать и записывать. Объемы могут содержать один или несколько дисков - мы определили объем для каждого из трех дисков. Давайте посмотрим на диски:
  1. И...давайте проверим объемы:
  1. Теперь мы добавим правило TTL, которое перемещает данные между горячими, теплыми и холодными объемами:
  1. Новое правило TTL должно быть реализовано, но вы можете принудительно его применить, чтобы быть уверенным:
  1. Проверьте, что ваши данные переместились на ожидаемые диски, используя таблицу system.parts:

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