Обновление словарей
ClickHouse периодически обновляет словари. Интервал обновления для полностью загружаемых словарей и интервал инвалидации для кэшируемых словарей определяется в теге <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 может перезагрузить данные словаря, если изменился XML файл с конфигурацией словаря или если была выполнена команда SYSTEM RELOAD DICTIONARY
.
При обновлении словарей сервер ClickHouse применяет различную логику в зависимости от типа источника:
- У текстового файла проверяется время модификации. Если время изменилось по отношению к запомненному ранее, то словарь обновляется.
- Для MySQL источника время модификации проверяется запросом
SHOW TABLE STATUS
(для MySQL 8 необходимо отключить кеширование мета-информации в MySQLset global information_schema_stats_expiry=0
). - Словари из других источников по умолчанию обновляются каждый раз.
Для других источников (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
и ComplexKeyHashed
могут запрашивать только те данные, которые были изменены после предыдущего обновления. Если update_field
указано как часть конфигурации источника словаря, к запросу данных будет добавлено время предыдущего обновления в секундах. В зависимости от типа источника (Executable, HTTP, MySQL, PostgreSQL, ClickHouse, ODBC) к update_field
будет применена соответствующая логика перед запросом данных из внешнего источника.
- Если источник HTTP, то
update_field
будет добавлено в качестве параметра запроса, а время последнего обновления — в качестве значения параметра. - Если источник Executable, то
update_field
будет добавлено в качестве аргумента исполняемого скрипта, время последнего обновления — в качестве значения аргумента. - Если источник ClickHouse, MySQL, PostgreSQL или ODBC, то будет дополнительная часть запроса
WHERE
, гдеupdate_field
будет больше или равно времени последнего обновления.
Если установлена опция 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))
...