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

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

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

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

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

Совет

Если вы используете словари с ClickHouse Cloud, используйте DDL-запрос для их создания и создавайте словари от имени пользователя default. Также проверьте список поддерживаемых источников словарей в руководстве по совместимости с ClickHouse Cloud.

<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 применяет разную логику в зависимости от типа источника:

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

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

  • Таблица словаря должна иметь поле, которое всегда изменяется при обновлении исходных данных.
  • В настройках источника должен быть указан запрос, который получает это изменяющееся поле. Сервер ClickHouse интерпретирует результат запроса как строку, и если эта строка изменилась относительно своего предыдущего состояния, словарь обновляется. Укажите запрос в поле <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))
...