Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

Обновление данных словаря с помощью LIFETIME

ClickHouse периодически обновляет словари на основе тега LIFETIME (задаётся в секундах). LIFETIME — это интервал обновления для полностью загруженных словарей и интервал инвалидации для кэшированных словарей.

Во время обновления к старой версии словаря по-прежнему можно обращаться в запросах. Обновление словарей не блокирует запросы, за исключением их начальной загрузки при первом использовании. Если во время обновления возникает ошибка, она записывается в журнал сервера, а запросы могут по-прежнему использовать старую версию словаря. Если обновление словаря завершается успешно, старая версия словаря заменяется атомарно.

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

<dictionary>
    ...
    <lifetime>300</lifetime>
    ...
</dictionary>

или

CREATE DICTIONARY (...)
...
LIFETIME(300)
...

Параметр <lifetime>0</lifetime> (LIFETIME(0)) предотвращает обновление словарей.

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

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

<dictionary>
    ...
    <lifetime>
        <min>300</min>
        <max>360</max>
    </lifetime>
    ...
</dictionary>

или

LIFETIME(MIN 300 MAX 360)

Если <min>0</min> и <max>0</max>, ClickHouse не перезагружает словарь по тайм-ауту. В этом случае ClickHouse может перезагрузить словарь раньше, если был изменён файл конфигурации словаря или выполнена команда SYSTEM RELOAD DICTIONARY.

При обновлении словарей ClickHouse server использует разную логику в зависимости от типа источника:

  • Для текстового файла проверяется время изменения. Если оно отличается от ранее зафиксированного, словарь обновляется.
  • Словари из других источников по умолчанию обновляются при каждом обращении.

Для других источников (ODBC, PostgreSQL, ClickHouse и т. д.) можно настроить запрос так, чтобы словари обновлялись только в том случае, если они действительно изменились, а не при каждом обращении. Для этого выполните следующие шаги:

  • В таблице словаря должно быть поле, которое всегда изменяется при обновлении исходных данных.
  • В настройках источника должен быть указан запрос, возвращающий изменяющееся поле. ClickHouse server интерпретирует результат запроса как строку, и, если эта строка изменилась по сравнению с предыдущим состоянием, словарь обновляется. Укажите запрос в поле <invalidate_query> в настройках источника.

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

<dictionary>
    ...
    <odbc>
      ...
      <invalidate_query>SELECT update_time FROM dictionary_source where id = 1</invalidate_query>
    </odbc>
    ...
</dictionary>

или

...
SOURCE(ODBC(... invalidate_query 'SELECT update_time FROM dictionary_source where id = 1'))
...

Для словарей Cache, ComplexKeyCache, SSDCache и SSDComplexKeyCache поддерживаются как синхронные, так и асинхронные обновления.

Для словарей Flat, Hashed, HashedArray и ComplexKeyHashed также можно запрашивать только те данные, которые изменились после предыдущего обновления. Если update_field указан в конфигурации источника словаря, в запрос данных будет добавлено значение времени предыдущего обновления в секундах. В зависимости от типа источника (Executable, HTTP, MySQL, PostgreSQL, ClickHouse или ODBC) перед запросом данных из внешнего источника к update_field будет применяться различная логика.

  • Если источник — HTTP, update_field будет добавлен как параметр запроса, а его значением будет время последнего обновления.
  • Если источник — Executable, update_field будет добавлен как аргумент исполняемого скрипта, а его значением будет время последнего обновления.
  • Если источник — ClickHouse, MySQL, PostgreSQL или ODBC, будет добавлено дополнительное условие WHERE, в котором update_field сравнивается со временем последнего обновления по условию «больше или равно».
    • По умолчанию это условие WHERE проверяется на самом верхнем уровне SQL-запроса. Либо это условие можно проверять в любом другом WHERE-условии внутри запроса, используя ключевое слово {condition}. Пример:
      ...
      SOURCE(CLICKHOUSE(...
          update_field 'added_time'
          QUERY '
              SELECT my_arr.1 AS x, my_arr.2 AS y, creation_time
              FROM (
                  SELECT arrayZip(x_arr, y_arr) AS my_arr, creation_time
                  FROM dictionary_source
                  WHERE {condition}
              )'
      ))
      ...

Если задана опция update_field, можно также задать дополнительную опцию update_lag. Значение опции update_lag вычитается из времени предыдущего обновления перед запросом обновлённых данных.

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

<dictionary>
    ...
        <clickhouse>
            ...
            <update_field>added_time</update_field>
            <update_lag>15</update_lag>
        </clickhouse>
    ...
</dictionary>

или

...
SOURCE(CLICKHOUSE(... update_field 'added_time' update_lag 15))
...
Navigation