Learning Platform
Глоссарий Troubleshooting
Урок 11.02 · 35 мин
Продвинутый
TTLstorage policyJBODS3tiered storage

Storage Policy и MOVE TTL

Многоуровневая стратегия хранения (tiered storage) позволяет хранить горячие данные на быстром локальном диске, а холодные — дешёвом объектном хранилище, например S3. ClickHouse управляет перемещением данных между уровнями автоматически через MOVE TTL и storage policy, без ручных скриптов.

Уровни хранилища и движение данных по TTL
INSERT → Hot (local disk)INSERT: новые данные всегда записываются на hot-диск (локальный SSD/HDD). storage_policy назначается при CREATE TABLE ... SETTINGS storage_policy = 'tiered'. Все новые parts сначала попадают в hot volume независимо от TTL.
TTL MOVE: event_time + INTERVAL 30 DAY
Hot volume (local SSD/HDD)Hot volume: локальный SSD/HDD, самый быстрый доступ. Хранит свежие данные с высокой частотой обращений. Это диск по умолчанию (default disk) — все новые parts приземляются здесь. При срабатывании TTL MOVE части перемещаются атомарно во warm volume.
merge triggers MOVE
Warm (S3 + s3_cache)Warm volume: S3-диск с локальным кешем (s3_cache). Части перемещаются атомарно во время merge-цикла после истечения MOVE TTL. Локальные метаданные остаются на диске — только данные уходят в S3. s3_cache ускоряет повторные чтения: ClickHouse не скачивает одни и те же данные дважды.
TTL DELETE: event_time + INTERVAL 365 DAY
Expire (DELETE TTL)Expire: строки удаляются физически при очередном merge. До merge строки могут присутствовать в таблице даже после истечения TTL — физическое удаление происходит только при merge. MATERIALIZE TTL принудительно применяет TTL ко всем существующим данным. OPTIMIZE TABLE t FINAL запускает принудительный merge.
JBOD volumeНесколько локальных дисков — один volume, round-robin записьJust a Bunch Of Disks: несколько физических дисков объединяются в один логический volume. ClickHouse распределяет новые parts по дискам по очереди (round-robin). При заполнении одного диска запись переходит на следующий. JBOD не даёт избыточности — это только горизонтальное расширение ёмкости hot volume.
Column TTLКолоночный TTL: значение заменяется на default типа (не NULL)Column-level TTL обнуляет конкретную колонку, а не удаляет строку. После истечения срока значение заменяется на default типа: 0 для числовых, '' для String, минимальная дата для Date. NULL не используется — column TTL не меняет nullable семантику колонки.
Partition opsDETACH/ATTACH/MOVE PARTITION — мгновенные операции с целыми частямиОперации с партициями работают с целыми partition directories без сканирования строк. DETACH PARTITION перемещает партицию в detached/ без удаления данных. ATTACH возвращает её обратно. MOVE PARTITION TO TABLE перемещает в другую таблицу мгновенно. Все операции O(1) по числу строк.
MATERIALIZE TTLПринудительное применение TTL к существующим даннымALTER TABLE t MATERIALIZE TTL немедленно запускает применение TTL ко всем существующим партициям. Без этой команды TTL применяется только к новым данным при следующем merge. Полезно при добавлении TTL к таблице с уже существующими данными.

Архитектура: диски, volumes и политики

Tiered storage строится из трёх концепций:

  • Диск (disk) — физическое или логическое хранилище: локальный путь, S3-бакет, кеш поверх S3.
  • Volume — группа дисков одного уровня (hot, warm, cold).
  • Storage policy — набор volumes с правилами заполнения.
Компоненты storage policy: диски, volumes, политика
default (local disk)default disk: встроенный локальный диск. Путь /var/lib/clickhouse/. Самый быстрый, но самый дорогой. Используется автоматически если storage_policy не задан. NVMe/SSD рекомендуется для hot tier.
s3_cold (S3 disk)s3_cold disk: диск типа 's3', указывает на S3-бакет. ClickHouse перемещает целые parts (не строки) на S3 при срабатывании MOVE TTL. Операции чтения медленнее локального диска — компенсируется s3_cache.
s3_cache (cache disk)s3_cache disk: кеширующий слой поверх S3-диска. Кэширует recently-accessed parts локально (max_size задаёт лимит). Прозрачно ускоряет повторные чтения с S3. Тип 'cache', параметр disk=s3_cold.
объединяются в volumes → policy
Volume: hotVolume 'hot': содержит default disk. Новые INSERT всегда попадают сюда. Данные хранятся здесь до срабатывания MOVE TTL или заполнения volume.
Volume: coldVolume 'cold': содержит s3_cold (или s3_cache) disk. Данные перемещаются сюда по TTL MOVE. Parts физически перемещаются на S3; локальный диск освобождается.

Конфигурация storage.xml

Storage policy задаётся в XML-конфигурации ClickHouse. В лабораторной среде с MinIO:

<!-- /etc/clickhouse-server/config.d/storage.xml -->
<clickhouse>
  <storage_configuration>
    <disks>
      <!-- Встроенный локальный диск (default) объявлять не нужно -->
      <s3_cold>
        <type>s3</type>
        <endpoint>http://minio:9000/clickhouse-cold/</endpoint>
        <access_key_id>minioadmin</access_key_id>
        <secret_access_key>minioadmin123</secret_access_key>
        <use_path_style_url>1</use_path_style_url>
        <metadata_path>/var/lib/clickhouse/disks/s3_cold/</metadata_path>
      </s3_cold>
      <s3_cache>
        <type>cache</type>
        <disk>s3_cold</disk>
        <path>/var/lib/clickhouse/disks/s3_cache/</path>
        <max_size>2Gi</max_size>
      </s3_cache>
    </disks>
    <policies>
      <tiered>
        <volumes>
          <hot>
            <disk>default</disk>
          </hot>
          <cold>
            <disk>s3_cold</disk>
          </cold>
        </volumes>
      </tiered>
    </policies>
  </storage_configuration>
</clickhouse>
WARNING

Параметр use_path_style_url обязателен для MinIO и других S3-совместимых хранилищ. Без него ClickHouse использует virtual-hosted style (bucket.hostname), что не поддерживается большинством self-hosted S3 реализаций. Для AWS S3 этот параметр не нужен.


MOVE TTL: синтаксис и примеры

MOVE TTL добавляется к обычному TTL-выражению с указанием целевого volume или диска:

-- Таблица с hot/cold tiered storage
CREATE TABLE events_tiered
(
    event_time DateTime,
    user_id    UInt64,
    payload    String
)
ENGINE = MergeTree
ORDER BY (user_id, event_time)
PARTITION BY toYYYYMM(event_time)
SETTINGS storage_policy = 'tiered'
TTL event_time + INTERVAL 30 DAY TO VOLUME 'cold';
-- Альтернатива: несколько TTL-правил (hot → warm → delete)
CREATE TABLE events_multi_ttl
(
    event_time DateTime,
    user_id    UInt64,
    payload    String
)
ENGINE = MergeTree
ORDER BY (user_id, event_time)
PARTITION BY toYYYYMM(event_time)
SETTINGS storage_policy = 'tiered'
TTL
    event_time + INTERVAL 30 DAY TO VOLUME 'cold',  -- переместить на холодный уровень
    event_time + INTERVAL 365 DAY DELETE;           -- удалить совсем через год
TIP

MOVE TTL перемещает целые parts, а не отдельные строки. Если part содержит строки с разными event_time (часть истёкших, часть нет), part не перемещается до тех пор, пока все строки в нём не пройдут TTL. Это означает, что разбиение по партициям (PARTITION BY toYYYYMM) критично для эффективного tiered storage: данные одного месяца оказываются в одном part.


JBOD: несколько дисков в одном volume

JBOD (Just a Bunch Of Disks) — паттерн, при котором несколько физических дисков объединяются в один volume. ClickHouse распределяет новые parts между дисками по round-robin.

<policies>
  <jbod_policy>
    <volumes>
      <hot>
        <disk>disk1</disk>
        <disk>disk2</disk>
        <disk>disk3</disk>
        <!-- Parts распределяются равномерно; при заполнении одного диска запись продолжается на других -->
      </hot>
    </volumes>
  </jbod_policy>
</policies>

JBOD не даёт отказоустойчивости (это не RAID): при потере одного диска данные на нём теряются. Но JBOD масштабирует ёмкость без изменения логики таблиц.


s3_cache: кеш поверх S3

s3_cache — специальный тип диска, который прозрачно кеширует recently-accessed parts с S3 на локальный диск. Это ускоряет повторные чтения с холодного уровня без изменения SQL-запросов.

-- Использование s3_cache вместо s3_cold в политике (прозрачно для запросов)
CREATE TABLE events_cached
(
    event_time DateTime,
    payload    String
)
ENGINE = MergeTree
ORDER BY event_time
SETTINGS storage_policy = 'tiered_with_cache'  -- cold volume использует s3_cache
TTL event_time + INTERVAL 30 DAY TO VOLUME 'cold';

Практический сценарий: горячий журнал событий

-- Полный пример: горячий журнал с автоматическим перемещением на S3 через 30 дней
-- и полным удалением через 1 год

CREATE TABLE access_log
(
    event_time  DateTime DEFAULT now(),
    user_id     UInt64,
    action      LowCardinality(String),
    resource    String,
    ip_address  String TTL event_time + INTERVAL 30 DAY  -- IP обнуляется раньше строки
)
ENGINE = MergeTree
ORDER BY (user_id, event_time)
PARTITION BY toYYYYMM(event_time)
SETTINGS storage_policy = 'tiered'
TTL
    event_time + INTERVAL 30 DAY TO VOLUME 'cold',
    event_time + INTERVAL 365 DAY DELETE;

-- Проверить текущие диски через system.disks
SELECT name, path, type, free_space, total_space
FROM system.disks;

-- Проверить storage policy
SELECT policy_name, volume_name, disk_name, max_data_part_size
FROM system.storage_policies
WHERE policy_name = 'tiered';
TIP

Для практики с MinIO и реальным MOVE TTL выполните лабораторную работу labs/minio/. Там настроена полная конфигурация с cgr.dev/chainguard/minio и ClickHouse 26.3 LTS.


Ключевые выводы

  1. Storage policy состоит из дисков (disk) → volumes → политики; таблица указывает политику через SETTINGS storage_policy = 'name'.
  2. MOVE TTL перемещает целые parts между volumes — не отдельные строки. Партиционирование по времени критично для эффективного MOVE.
  3. JBOD объединяет несколько дисков в один volume с round-robin распределением — масштабирует ёмкость, но не даёт отказоустойчивости.
  4. s3_cache — прозрачный кеш поверх S3-диска, ускоряет повторные чтения без изменения SQL.
  5. use_path_style_url=1 обязателен для MinIO и других self-hosted S3 реализаций.
Сжатие данных: LZ4, ZSTD, Snappy — фундаментальные принципы Iceberg, Delta Lake, Hudi: open table formats

Проверьте понимание

Результат: 0 из 0
Прикладной
Вопрос 1 из 4. Администратор настраивает tiered storage: горячий уровень (local SSD) и холодный (S3/MinIO). Какая минимально корректная конфигурация позволит таблице автоматически перемещать данные на S3 через 30 дней?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 8