ClickHouse は、LIFETIME タグ (秒単位で定義) に基づいて定期的に Dictionary を更新します。
LIFETIME は、完全にダウンロードされた Dictionary では更新間隔を、cache Dictionary では無効化間隔を表します。
更新中も、Dictionary の古いバージョンには引き続きクエリできます。 Dictionary の更新によってクエリがブロックされることはありません。ただし、初回使用時の読み込み時を除きます。 更新中にエラーが発生した場合、そのエラーはサーバーログに記録され、クエリは引き続き Dictionary の古いバージョンを使用できます。 Dictionary の更新が成功すると、Dictionary の古いバージョンはアトミックに置き換えられます。
設定例:
<dictionary>
...
<lifetime>300</lifetime>
...
</dictionary>または
CREATE DICTIONARY (...)
...
LIFETIME(300)
...<lifetime>0</lifetime> (LIFETIME(0)) を設定すると、Dictionary は更新されません。
更新間隔を設定すると、ClickHouse はその範囲内で一様ランダムに時刻を選択します。これは、多数のサーバーで更新する際に Dictionary ソースへの負荷を分散するために必要です。
設定例:
<dictionary>
...
<lifetime>
<min>300</min>
<max>360</max>
</lifetime>
...
</dictionary>または
LIFETIME(MIN 300 MAX 360)<min>0</min> かつ <max>0</max> の場合、ClickHouse はタイムアウトによって Dictionary を再読み込みしません。
この場合、辞書の設定ファイルが変更されたとき、または SYSTEM RELOAD DICTIONARY コマンドが実行されたときには、ClickHouse がそれより前に Dictionary を再読み込みすることがあります。
Dictionary を更新する際、ClickHouseサーバーは source の種類に応じて異なるロジックを適用します。
- テキストファイルの場合、更新時刻を確認します。時刻が前回記録された時刻と異なる場合、Dictionary が更新されます。
- その他のソースの Dictionary は、デフォルトで毎回更新されます。
その他のソース (ODBC、PostgreSQL、ClickHouse など) については、毎回ではなく、実際に変更があった場合にのみ Dictionary を更新するクエリを設定できます。これを行うには、次の手順に従います。
- Dictionary のテーブルには、ソースデータが更新されるたびに必ず変化するフィールドが必要です。
- ソースの設定では、その変化するフィールドを取得するクエリを指定する必要があります。ClickHouseサーバーはクエリ結果を 1 行として解釈し、その行が前回の状態と比べて変化していれば、Dictionary を更新します。クエリは、source の設定にある
<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 の各 Dictionary では、同期更新と非同期更新の両方がサポートされています。
また、Flat、Hashed、HashedArray、ComplexKeyHashed の各 Dictionary では、前回の更新以降に変更されたデータのみをリクエストすることも可能です。Dictionary ソース設定の一部として 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 クエリの最上位レベルで評価されます。あるいは、{condition}キーワードを使用して、クエリ内の任意の別のWHERE句でこの条件を評価することもできます。例:... 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))
...