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))
...